服務端渲染、客戶端渲染和CRP性能節點優化

1. 服務端渲染

在先後端分離這個概念還沒出現的時候,一個團隊開發網站的時候是這樣來開展工做的:javascript

那個時候的前端開發叫作網頁製做,只是簡單的開發網站的結構和樣式,而後提交給後端,後端進行數據綁定;後端經過jspphpasp的語法來實現數據綁定。php

這種服務端渲染時,瀏覽器拿到的既有數據也有樣式,能夠直接展現出來,可是這樣對服務器的壓力太大了,而且這個時候的頁面不能實現局部刷新的功能;可是服務端渲染有利於SEO優化。css

SEO:百度/谷歌瀏覽器會不定時開啓一個爬蟲(搜索引擎搜錄)爬取網站上的內容,收錄的內容越多,網站的權重越大(不一樣標籤的權重不一樣,因此標籤語義化有利於提升網站的權重),可是爬蟲只會爬取源代碼中存在的信息,例如客戶端渲染的技術就會致使源代碼裏面沒有內容,不利於優化。html

1) 優勢

  1. 有利於SEO優化。

2) 缺點

  1. 數據全從服務器渲染致使服務器壓力很大;
  2. 不能實現局部刷新的效果,由於每次修改後都是直接整個頁面;
  3. 不利於團隊協做開發,前端不會jsp等技術,後端不會htmlcss等技術,配合起來難度很高。

2. 客戶端渲染

隨着時代的發展,在服務器渲染以後出現了客戶端渲染技術,實現了先後端分離,解放了服務器的巨大壓力,瀏覽器首次獲取的只有結構和樣式,並無動態綁定的數據;數據是在後面的ajax請求中才返回回來,由客戶端本身渲染,完成數據的綁定。前端

1) 優勢

  1. 經過AJAX實現局部刷新效果;
  2. 團隊配合很方便,先後端工做涇渭分明;
  3. 服務器壓力會小不少。

2) 缺點

  1. 客戶端渲染是基於js動態綁定的數據,在源代碼中沒有值,不利於SEO優化。

3. 辦分離半不分離

  1. 須要SEO的部分服務器渲染,其餘地方客戶端渲染(再或者第一次服務器渲染,後期操做想要局部刷新,再交給客戶端渲染) => SSR服務器渲染; vue->nuxt.js react->next.js
  2. 骨架屏技術(服務器):若是服務器承壓能力比較好,咱們項目的首屏信息是服務器渲染的,其他屏幕信息再滾動條滾動到指定位置的時候,再基於客戶端渲染;
  3. 骨架屏技術(客戶端):第一次從服務器獲取回來的只有結構樣式,沒有數據,此時咱們用佔位圖或者默認的灰色塊,先把結構樣式撐起來(或者作一個loding的狀態,真實數據獲取到以後再修改),當頁面第一次渲染完成,再從服務器獲取數據,進行客戶端渲染(真實項目中的數據請求是異步的,這樣能夠防止數據的請求阻礙GUI的渲染)。

4.白屏

所謂白屏,就是當前設備打開頁面,第一步從服務器請求回來HTML,而後渲染,渲染過程當中請求CSS資源,生成DOM樹、CSSOM樹、Render-Tree渲染樹,最後整個渲染頁面,這個過程是須要時間的,從請求頁面到整個全部東西沒有完成以前所經歷的時間會產生一個白屏的效果。 白屏優化:減小第一次頁面渲染時間,包括後續打開時間,這些優化就是項性能優化的關鍵點。vue

5. CRP性能節點優化

爲了提升性能;Webkit瀏覽器預測解析:chrome的預加載掃描器html-preload-scanner經過掃描節點中的「src」, 「link」等屬性,找到外部鏈接資源後進行預加載,避免了資源加載的等待時間,一樣實現了提早加載以及加載和執行分離。java

  1. 減小DOM樹的渲染時間(HTML層級不要太深,注意標籤語義化);
  2. 減小CSSOM樹渲染時間(選擇器是從右向左解析,因此儘量減小使用選擇器的層級【less/sass雖然好用可是是個大坑】);
  3. 儘早儘快地把CSS下載到客戶端(充分利用HTTP多請求併發機制),把請求放在頭部;
  4. 爲了不白屏,能夠進來第一件事,快速生成一套 loding 的渲染樹(前端骨架屏);服務器的SSR骨架屏所提升的渲染是避免了客戶端再次單獨請求數據,而不是樣式和結構上的(首屏處理);
  5. 把JS放在頁面底部以及儘量使用defer或者async
  6. 減小DOM迴流和重繪;

1) 迴流repaint和重繪reflow

  1. 重繪:元素樣式的改變(但寬高、大小、位置不變)
  2. 迴流:元素的大小或者位置發生了變化(當頁面佈局和幾何信息發生了變化的時候),觸發了從新佈局,致使渲染樹從新計算佈局和渲染;

迴流必定會觸發重繪,可是重繪不必定觸發迴流。react

優化:放棄操做DOM,分離讀寫,集中式改變。ajax

現代版瀏覽器存在一個渲染隊列機制,對於修改樣式的操做會存放到渲染隊列中,接着執行代碼,若是仍是修改代碼的繼續添加進去(只要不是獲取元素樣式直接無視),直到代碼是獲取元素樣式或者執行結束爲止,最後當即把隊列中的樣式統一進行渲染,最後只引起一次迴流重繪。chrome

box.style.width = '200px';
box.style.height = '200px';
// 這樣只觸發一次迴流

box.style.width = '200px';
box.offsetWidth;
box.style.height = '200px';
// 這樣觸發兩次迴流

box.cssText = 'width:200px;height:200px;'
// 這樣只觸發一次迴流
複製代碼

緩存佈局信息和元素批量修改:

for (let i = 0; i < 10; i++) {
	let span = document.createElement('span');
	span.innerHTML = i;
	document.body.appendChild(span);
}
// 這樣會觸發十次迴流

let frg = document.createDocumentFragment();
	for (let i = 0; i < 10; i++) {
		let span = document.createElement('span');
		span.innerHTML = i;
		frg.appendChild(span);
	}
document.body.appendChild(frg); 
// 這樣利用文檔碎片只觸發一次迴流;用字符串拼接也能實現相同效果
複製代碼

相關文章
相關標籤/搜索