效能是前端開發一個非常重要的組成部分,與應用不同,網頁的所有資源初始都需要通過網路傳輸,因此如何進行更好地進行網路傳輸對前端效能影響很大,此外還有瀏覽器渲染部分的優化。不管怎麼說如何進行前端效能優化是一個永恆的話題。本文是閱讀小冊前端效能優化原理與實踐後加上部分自己以前的理解整理而成的,更詳細的原理請看小冊。
概覽檔案:前端效能優化.xmind.zip
概述
效能優化需要從哪幾個方面入手?我們要先了解瀏覽器開啟網頁的過程。
- 瀏覽器對URL進行DNS解析
- 瀏覽器與伺服器進行TCP連線
- 瀏覽器發出HTTP請求
- 伺服器返回HTTP響應
- 瀏覽器進行頁面渲染
下面我們分別對這幾個階段進行優化。
瀏覽器進行DNS解析
DNS全稱Domain Name System。它是網際網路的“通訊錄”,它記錄域名與實際ip地址的關係,域名是為了方面人類記憶。每次我們方位一個網站,都要通過各級的DNS伺服器查詢到該網站的伺服器ip,然後才能訪問到該伺服器。
提前解析DNS
提前解析DNS需要用到DNS prefetch
技術。可以在html中使用
<link ref="dns-prefetch" href="">
複製程式碼
形式的標籤來對特定域名進行預解析,瀏覽器會在頁面載入完畢後進行該過程
另外還可以使用X-DNS-Prefetch-Control: on/off
響應頭來控制預解析的開關。可以在html中使用
<meta http-equiv="x-dns-prefetch-control" content="on/off">
複製程式碼
來實現該效果或直接讓伺服器返回該響應頭。
與伺服器建立TCP連線
TCP全稱Transmission Control Protocol。是一種面向連線的,可靠的傳輸協議,它位於OSI模型的傳輸層。
瀏覽器傳送HTTP請求
減少請求次數
-
資源合併
-
使用打包工具
使用webpack等工具,對js和css資源進行打包,避免js或css檔案過多。
但也要考慮打包檔案過大的問題,需要再這之間進行綜合考慮。
在SPA中常用的實踐是,webpack提取出的公用檔案先載入,然後路由相關的檔案按需載入。
-
精靈圖
多個小圖合併後的圖片。
使用的時候使用background-position進行定位使用。
-
-
快取
-
HTTP Cache(詳細解釋)
-
強快取
強快取的特定是不需要詢問伺服器,它通過expires和cache-control來實現。cache-control的優先順序高於expires,它們都用來表示過期時間,expires是儲存時間戳,cache-control使用max-age來表示相對時間。
cache-control 的no-cache不詢問瀏覽器,直接請求伺服器(進行協商快取)。 而no-store則不是不使用任何快取策略。 s-maxage只在代理伺服器中生效。
如果資源沒有過期,則會直接使用該資源。
-
協商快取
協商快取是請求伺服器後,伺服器來判斷是返回新的資源,還是告訴瀏覽器使用舊的資源。
伺服器每次返回資源會帶有Last-Modified時間戳,每次伺服器請求帶上If-Modified-Since的時間戳,由伺服器來判斷資源修改時間是否與該時間一致。
last-modified有個問題是,雖然伺服器檔案修改時間變了,但是檔案內容並沒有真正變化
所有加入了ETag,是由檔案內容計算出來的唯一標識。請求的時候會以If-None-Match帶上該值,來由伺服器判斷
-
-
Service Worker Cache
-
Memory Cache & Disk Cache
他們是配合http快取的。 memory cache命中最快,但是它週期較短,base64的圖片,較小的js和css能夠有較大機率被寫進記憶體,這沒有確定的定論。 其他較大的js、css和圖片等會被直接寫進硬碟,進行快取。
-
-
儲存(詳細解釋)
-
cookie
cookie最大為4k,通常用來儲存一些使用者登入狀態,每次請求,瀏覽器都會帶上相同域名下的cookie
-
webStrorage
webStorage分為兩種,sessionStorage和localStorage,它們的大小在5-10M之間。都是以鍵值對的方式進行儲存的。sessionStorage與localStorage的不同在於生命週期的不同,sessionStorage在tab關閉後,就不再存在了,而localStorage的永久儲存,除非主動刪除
-
indexDB
瀏覽器端的“資料庫”,由於目前基本沒用,所有暫不研究
-
縮小請求體積
-
資源壓縮
-
Gzip
傳輸的時候可以在伺服器端開啟gzip壓縮,可以有效減少傳輸檔案的大小,可以在響應頭content-encoding: gzip中看到。
-
程式碼壓縮
使用一些程式碼壓縮工具,刪除掉無用的註釋、空行和縮減名稱等操作來減少檔案體積。
-
圖片壓縮
圖片是網頁上佔用很多流量的一種資源。如果在圖片損失一些顏色和畫素的情況下並不會對使用者體驗有太大影響,那麼就應該對圖片進行壓縮。
同時可以對圖片做一些裁切和縮小等操作,來減小圖片的體積。
-
-
圖片選用正確的格式(詳細解釋)
-
PNG
無損格式,壓縮率一般,支援透明背景,常用於透明圖片或者Icon等。
-
JPG
有損格式,壓縮率較好,常用於複雜的大圖,不支援透明背景。
-
SVG
向量圖形,可程式設計。在各解析度下不失真,但是渲染複雜圖形較消耗效能。常用於簡單圖形。
-
WEBP
無損格式,相較於PNG和JPG來說,壓縮率更好,同時支援透明背景。唯一的缺點是相容性不好。可用於相容性好的瀏覽器,用JPG和PNG做回退機制。
-
伺服器傳送HTTP響應
減少響應時間
-
利用CDN
cdn全稱content delivery network。它是依靠部署在各地區的邊緣伺服器,達到使用者就近獲取內容,降低網路擁塞,提高使用者訪問速度和命中率的目的。它主要的關鍵技術是內容儲存和分發技術。
降低頁面初始渲染時間
-
伺服器渲染
伺服器渲染最大的作用是優化SEO。
同時在效能上也能加快首屏渲染速度,但是這樣會對伺服器帶來一定的壓力,所以需要進行綜合考量。
頁面渲染(詳細解釋)
減少阻塞
-
JS阻塞
當html解析遇到js會先下載和執行js檔案,這是為了防止js操作了dom等情況的發生。但我們作為操作者,可以人為的指定,那些元素可以延遲載入。
為script標籤指定 async 或 defer來延遲指令碼。
async表示js不會阻塞,但會在下載完成後立刻執行
defer則會在下載完成並且整個文件解析完成、DOMContentLoaded事件被觸發前開始執行
-
CSS阻塞
css會阻塞html進行渲染,但是為了介面沒有任何樣式的展現在使用者面前,因此我們需要將css提前
減少渲染次數
-
避免迴流與重繪
迴流又稱為重排,即通過某種手段改變了元素的位置大小等資訊,導致瀏覽器需要重新計算和渲染的過程。而重繪只是被改變了樣式如背景和顏色等。
不論是哪一種,都會耗費效能,所以我們要避免進行迴圈操作。
減少渲染節點數量
-
懶載入
對於一些不在使用者檢視內的元素,我們可以在展示的時候先不進行渲染,直到該元素出現在了檢視內再進行渲染。
懶載入包括對圖片或者dom元素的載入和渲染
提高渲染效率
-
減少dom節點的操作
瀏覽器的渲染引擎和js引擎是分離的,可以想象在js引擎和渲染引擎之間進行”跨界交流“並不簡單,這個開銷很大,所有我們要儘量避免這種操作。
-
利用事件迴圈和非同步更新(詳細解釋)