1. 程式人生 > >掘金小冊前端效能優化原理與實踐讀後總結

掘金小冊前端效能優化原理與實踐讀後總結

webpack效能優化(emmm,我還沒學這個,啥都看不懂,勿噴)

1.不要讓loader做太多事情

2.處理第三方庫

3.構建結果體積壓縮

  a.檔案視覺化,找出導致體積過大的原因

  b.拆分資源

  c.刪除冗餘程式碼

  d.按需載入

4.webpack Gzip壓縮

圖片優化

總的來說就是根據圖片型別的特點去使用圖片

1.jpg圖片

特點是有失真壓縮、高質量壓縮、體積小、載入快、不支援透明,適用於呈現色彩豐富的圖片,適合用作背景圖、輪播圖或Banner圖的格式

2.png圖片

特點是無失真壓縮、高質量壓縮、體積大、支援透明,適用於呈現小的Logo,或者顏色簡單且對比強烈的圖片或背景圖的格式

3.SVG圖片

特點是體積小,不失真,相容性好,可壓縮性強,可程式設計,渲染成本高,學習成本高,最適合帶有大型渲染區域的應用程式(地圖應用)

4.雪碧圖

將一個頁面涉及到的所有圖片都包含到一張大圖中去,然後利用CSS的 background-image,background- repeat,background-position 的組合進行背景定位。利用CSS Sprites能很好地減少網頁的http請求,從而大大的提高頁面的效能;CSS Sprites能減少圖片的位元組。

5.Base64

對圖片進行Base64編碼,會得到一串字串,瀏覽器會直接將這串字串解碼為圖片,這樣就不用傳送http請求了,但是這樣的缺點是圖片會膨脹,體積會增加,所以它的應用條件是:圖片尺寸小、無法用雪碧圖、圖片更新頻率低(不需要我們重複編碼和修改檔案內容,維護成本較低)

6.webP

集各種格式的優點於一身,缺點就是相容性不好,所以應用時需要判斷瀏覽器

合理利用瀏覽器快取機制

1.MemoryCache,即在記憶體中的快取,從優先順序上來說,它是瀏覽器最先嚐試去命中的一種快取。從效率上來說,它是響應速度最快的一種快取。

2.Services Worker Cache,Service Worker 是一種獨立於主執行緒之外的 Javascript 執行緒。它脫離於瀏覽器窗體,因此無法直接訪問 DOM。這樣獨立的個性使得 Service Worker 的“個人行為”無法干擾頁面的效能,可利用這一點幫我們實現離線快取、訊息推送和網路代理等功能

3.Http快取,分為強快取和協商快取

http快取的是指:當Web請求抵達快取時, 如果本地有“已快取的”副本,就可以從本地儲存裝置而不是從原始伺服器中提取這個文件

強快取(優先於協商快取,返回碼200):

利用Expires(http1.0,記錄快取過期時間)和Cache-Control(http1.1,記錄快取過期時間)來控制,Cache-Control優先順序高於Expires,Expires 使用的是伺服器端的時間,要是客戶端時間和服務端不同步,就可能造成瀏覽器本地的快取無用或者一直無法過期,Cache-Control使用的是使用的是客戶端本地時間的計算,所以不會出現上述情況,Cache-Control優先順序高於Expires,

協商快取(返回碼304):

利用If-None-Match(請求頭)/Etag(響應頭)和If-Modified-Since(請求頭)/Last-Modified(響應頭),If-None-Match和Etag記錄的是伺服器為每個資源生成的唯一的標識字串,快取的資料要是改變了,那麼這兩個資料就會變,這樣可判斷快取到底有沒有更新,If-Modified-Since和Last-Modified記錄的是服務端的檔案最後改變的時間,通過判斷這個,可以快取有沒有被更新,Last-Modified有一個缺陷就是隻能精確到1s,所以對於精確更高的可能不適用,Etag優先順序高於Last-Modified,Etag生成過程需要伺服器額外付出開銷,會影響伺服器效能,所以要看情況使用Etag

強快取與協商快取更細緻的瞭解,請參考:

4.Push Cache

http2階段的快取,應用尚處於萌芽階段,是快取的最後一道防線。

瀏覽器只有在 Memory Cache、HTTP Cache 和 Service Worker Cache 均未命中的情況下才會去詢問 Push Cache。Push Cache 是一種存在於會話階段的快取,當 session 終止時,快取也隨之釋放。不同的頁面只要共享了同一個 HTTP2 連線,那麼它們就可以共享同一個 Push Cache。

合理利用本地儲存

1.利用WebStorage

WebStorage提供了一種方式讓網站能夠把資訊儲存到本地的計算機上,並在以後需要的時候進行獲取。這樣一來,當需要用到什麼資源時,可以直接在本地儲存裡獲取,而不用發起網路請求等待響應。WebStorage分為localStorage(只支援string型別的儲存)與Session Storage(只支援string型別的儲存),Session Storage在會話結束消失, localStorage永久有效,手動刪除才會消失,Session Storage 和localStorage都遵循同源策略,但是對Session Storage特殊的一定在於,即便是相同域名下的兩個頁面,只要它們不在同一個瀏覽器視窗中開啟,那麼它們的 Session Storage 內容便無法共享。

2.利用IndexDB

IndexDB執行在瀏覽器上的非關係型資料庫,突破了WebStorage的儲存大小限制,支援儲存字串和二進位制資料,IndexDB可建立資料庫和表,可以被當成一個真正的資料庫使用。

使用CDN

CDN全稱是內容分發網路,簡單的來說,CDN做的事,就是把資源存在離自己最近的伺服器裡,從而實現就近訪問資料,快速獲取到需要的資料

CDN 往往被用來存放靜態資源(像 JS、CSS、圖片等不需要業務伺服器進行計算即得的資源),可以將靜態資源和主頁面置於不同的域名下,避免cookie的攜帶,這樣可以做到優化CDN

使用服務端渲染

服務端渲染,就是當用戶第一次請求頁面時,由伺服器把需要的元件或頁面渲染成 HTML 字串,然後把它返回給客戶端。客戶端拿到手的,是可以直接渲染然後呈現給使用者的 HTML 內容。

沒有伺服器渲染,當瀏覽器解析html文件解析到<script>標籤時,就需要停下html渲染,去解析其中的指令碼並執行,這整個過程都會阻塞文件解析,直到指令碼執行完才會繼續解析文件進行渲染。如果js檔案的數量和內容都比較大,那麼就會造成頁面空白,這樣是非常不利於使用者體驗的,伺服器渲染就能很好的解決這一問題。

服務端渲染也不是隨便就能用的,它加重了伺服器的壓力,也需要合理使用

CSS優化

1.css選擇器:

css是從右往左進行解析的,這也就是說 (ul>li)這種寫法,瀏覽器是先去找到li,再去看每個li的父元素是不是ul,當使用層級較多的選擇器時(如:body>div>p>span),會加大瀏覽器的尋找時間,而我們的原則因當是使瀏覽器能夠儘快的找到相應的元素。所以css選擇器方面的優化方案為:

a.避免後代選擇符(後代選擇器的開銷很高)

b.避免鏈式選擇符,避免使用複雜的選擇器,層級越少越好

c.避免使用萬用字元(使用萬用字元會使瀏覽器找遍所有的元素)

d.少用標籤選擇器,儘量用類選擇器代替

e.避免不必要的重複

2.儘量減少頁面重排、重繪:

a.什麼是重繪和迴流?

部分渲染樹(或者整個渲染樹)需要重新分析並且節點尺寸需要重新計算。這被稱為重排。注意這裡至少會有一次重排-初始化頁面佈局。

由於節點的幾何屬性發生改變或者由於樣式發生改變,例如改變元素背景色時,螢幕上的部分內容需要更新。這樣的更新被稱為重繪。

重繪的代價要比迴流小,重繪只涉及樣式的改變,不涉及到佈局。重繪就好像給人染了一個頭發,而回流相當於給人做了一次抽脂手術,迴流一定伴隨著重繪,而重繪卻可以單獨出現

b.迴流發生的情況:

    1.新增、刪除、更新 DOM 節點

    2. 通過 display: none 隱藏一個 DOM 節點-觸發重排和重繪

    3.元素位置改變。

    4.元素的尺寸改變(包括:內外邊距、邊框厚度、寬度、高度等屬性的改變)。

    5. 內容改變。

    6.頁面渲染器初始化。

    7.瀏覽器視窗尺寸改變。

    8.新增一個樣式表,調整樣式屬性

    9.使用者行為,例如調整視窗大小,改變字號,或者滾動。

c.觸發迴流的屬性:

     1.盒子模型相關屬性: width ,height ,padding ,margin ,display ,border-width ,border

     2.定位屬性及浮動: top ,bottom ,left ,right ,position ,float ,clear

     3.改變節點內部文字結構:

       text-align, overflow-y ,font-weight ,overflow, font-family, line-height, vertival-align ,white-space,font-size

d.重繪發生的情況:

重繪發生在元素的可見的外觀被改變,但並沒有影響到佈局的時候。比如,僅修改DOM元素的字型顏色(只有Repaint,因為不需要調整佈局)

e.觸發重繪的屬性有:

color,border-style,border-radius ,visibility,text-decoration ,background ,background-image ,background-position ,background-repeat,background-size ,outline-color ,outline ,outline-style ,outline-width ,box-shadow

f.減少頁面重排、重繪的方法:

避免逐條改變樣式,使用類名去合併樣式,儘量將樣式寫在單獨的css檔案裡面

通過 visibility:hidden 隱藏一個 DOM 節點

參考文件:

重繪和重排

3.減少css阻塞:

當我們在html時,總是在解析到link標籤或style標籤時,CSSDOM才會開始構建,這個構建過程會導致DOM解析的阻塞,所以為了減少阻塞時間,我們需要儘快完成載入(啟用CDN),儘早完成載入(在head元素中引用css相關標籤)

JS優化

1.減少JS阻塞

頁面構建dom樹的過程,即從上到下解析HTML文件生成DOM節點樹,當解析到<script>標籤時,會解析其中的指令碼(對於外鏈的JavaScript檔案,需要先載入該檔案內容),然後立即執行,這整個過程都會阻塞文件解析,直到指令碼執行完才會繼續解析文件。如果js檔案的數量和內容都比較大,那麼就會造成頁面空白,所以為了避免這一狀況,應該把 <script>標籤放在</body>標籤前面,而不是放在<head>標籤裡,要使用async(非同步載入,指令碼載入完立刻執行)和defer(非同步載入,文件解析完執行)

2.在非同步任務中實現 DOM 修改時,把它包裝成 micro 任務(微任務)

事件迴圈一般是這樣,先處理Macro-task(巨集任務),再處理micro 任務,micro 任務處理完後面緊跟著就是渲染的步驟,然後更新介面,處理Web work任務。包裝成 micro 任務,這樣不用等新的一輪事件迴圈,直接渲染呈現

3.Dom方面(從減少頁面迴流方面來考慮)

減少Dom操作,快取dom變數(比如var a=document.querySelector("#demo");)

避免迴圈更改dom,在更改時建立一個documentFragment或div,在它上面應用所有DOM操作,最後再把它新增到相應dom中

4.使用非同步更新策略(我也沒看懂。。。)

使用圖片懶載入

圖片懶載入,就是當圖片出現在瀏覽器的可視區域內時,設定圖片真正的路徑,讓圖片顯示出來。當一個頁面中由許多圖片時,使用懶載入,可大大提高頁面效能。

具體完成過程為,先給圖片一個假的src,不讓圖片載入,通過監聽滾動時間+函式節流,來完成判斷元素距離可視區域頂部的高度,要是高度差>=0,那麼就將正確的src賦給圖片,圖片完成載入。