前端效能優化指南

發表於2019-11-01

前言

發現總結性的小乾貨可以為大家提升更好的開發技巧和編碼思維,對程式碼量產化提供更紮實的質量和支援。這次我們來聊聊大家可能都比較關心的話題:效能優化

一說到頁面的效能優化,大家可能都會想起雅虎軍規2-5-8原則3秒鐘首屏指標等規則,這些規則在開發過程中不是強制要求的,但是有時候為了追求頁面效能的完美和體驗,就不得不對原有的程式碼進行修改和優化。

下面就結合自己三年多的開發經驗和大量的專案實踐,整理出一些常用的效能優化要點,同時再羅列一下雅虎軍規2-5-8原則3秒鐘首屏指標這三個常用規則的要點。

為了方便記憶和閱讀,文章使用部分簡寫名詞,解釋如下
  • D端:桌面端頁面Desktop End Page
  • M端:移動端頁面Mobile End Page

概述指南

  1. D端優化手段在M端同樣適用
  2. 在M端提出3秒鐘渲染完成首屏指標
  3. 基於第二點,首屏載入3秒內完成或使用Loading進行佔位
  4. 基於聯通3G網路平均338kb/s(2.71mb/s),首屏資源不應超過1014kb
  5. M端因配置原因,除載入外渲染速度也是優化重點
  6. 基於第五點,要合理處理程式碼減少渲染損耗
  7. 基於第二點和第五點,所有影響首屏載入和渲染的程式碼應在處理邏輯中後置
  8. 載入完成後,使用者互動使用時也需注意效能
載入優化
  • 減少HTTP請求:儘量減少頁面的請求數(首次載入同時請求數不能超過4個),移動裝置瀏覽器同時響應請求為4個請求(Android支援4個,iOS5+支援6個)

    • 合併CSS和JS
    • 使用CSS精靈圖
  • 快取資源:使用快取可減少向伺服器的請求數,節省載入時間,所有靜態資源都要在伺服器端設定快取,並且儘量使用長快取(使用時間戳更新快取)

    • 快取一切可快取的資源
    • 使用長快取
    • 使用外聯的樣式和指令碼
  • 壓縮程式碼:減少資源大小可加快網頁顯示速度,對程式碼進行壓縮,並在伺服器端設定GZip

    • 壓縮程式碼(多餘的縮排、空格和換行符)
    • 啟用Gzip
  • 無阻塞:頭部內聯的樣式和指令碼會阻塞頁面的渲染,樣式放在頭部並使用link方式引入,指令碼放在尾部並使用非同步方式載入
  • 首屏載入:首屏快速顯示可大大提升使用者對頁面速度的感知,應儘量針對首屏的快速顯示做優化
  • 按需載入:將不影響首屏的資源和當前螢幕不用的資源放到使用者需要時才載入,可大大提升顯示速度和降低總體流量(按需載入會導致大量重繪,影響渲染效能)

    • 懶載入
    • 滾屏載入
    • Media Query載入
  • 預載入:大型資源頁面可使用Loading,資源載入完成後再顯示頁面,但載入時間過長,會造成使用者流失

    • 可感知Loading:進入頁面時Loading
    • 不可感知Loading:提前載入下一頁
  • 壓縮影象:使用影象時選擇最合適的格式和大小,然後使用工具壓縮,同時在程式碼中用srcset來按需顯示(過度壓縮影象大小影響影象顯示效果)

    • 使用TinyJpgTinyPng壓縮影象
    • 使用CSS3、SVG、IconFont代替影象
    • 使用img的srcset按需載入影象
    • 選擇合適的影象:webp優於jpgpng8優於gif
    • 選擇合適的大小:首次載入不大於1014kb、不寬於640px
    • PS切圖時D端影象儲存質量為80,M端影象儲存質量為60
  • 減少CookieCookie會影響載入速度,靜態資源域名不使用Cookie
  • 避免重定向:重定向會影響載入速度,在伺服器正確設定避免重定向
  • 非同步載入第三方資源:第三方資源不可控會影響頁面的載入和顯示,要非同步載入第三方資源
載入過程是最為耗時的過程,可能會佔到總耗時的`80%時間(**優化重點**)
執行優化
  • CSS寫在頭部,JS寫在尾部並非同步
  • 避免img、iframe等的src為空:空src會重新載入當前頁面,影響速度和效率
  • 儘量避免重置影象大小:多次重置影象大小會引發影象的多次重繪,影響效能
  • 影象儘量避免使用DataURLDataURL影象沒有使用影象的壓縮演算法,檔案會變大,並且要解碼後再渲染,載入慢耗時長
執行處理不當會阻塞頁面載入和渲染
渲染優化
  • 設定viewport:HTML的viewport可加速頁面的渲染

    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, minimum-scale=1, maximum-scale=1">
  • 減少DOM節點:DOM節點太多影響頁面的渲染,儘量減少DOM節點
  • 優化動畫

    • 儘量使用CSS3動畫
    • 合理使用requestAnimationFrame動畫代替setTimeout
    • 適當使用Canvas動畫:5個元素以內使用CSS動畫,5個元素以上使用Canvas動畫iOS8+可使用WebGL動畫
  • 優化高頻事件scrolltouchmove等事件可導致多次渲染

    • 函式節流
    • 函式防抖
    • 使用requestAnimationFrame監聽幀變化:使得在正確的時間進行渲染
    • 增加響應變化的時間間隔:減少重繪次數
  • GPU加速:使用某些HTML5標籤和CSS3屬性會觸發GPU渲染,請合理使用(過渡使用會引發手機耗電量增加)

    • HTML標籤:videocanvaswebgl
    • CSS屬性:opacitytransformtransition
樣式優化
  • 避免在HTML中書寫style
  • 避免CSS表示式:CSS表示式的執行需跳出CSS樹的渲染
  • 移除CSS空規則:CSS空規則增加了css檔案的大小,影響CSS樹的執行
  • 正確使用displaydisplay會影響頁面的渲染

    • display:inline後不應該再使用floatmarginpaddingwidthheight
    • display:inline-block後不應該再使用float
    • display:block後不應該再使用vertical-align
    • display:table-*後不應該再使用floatmargin
  • 不濫用floatfloat在渲染時計算量比較大,儘量減少使用
  • 不濫用Web字型:Web字型需要下載、解析、重繪當前頁面,儘量減少使用
  • 不宣告過多的font-size:過多的font-size影響CSS樹的效率
  • 值為0時不需要任何單位:為了瀏覽器的相容性和效能,值為0時不要帶單位
  • 標準化各種瀏覽器字首

    • 無字首屬性應放在最後
    • CSS動畫屬性只用-webkit-、無字首兩種
    • 其它字首為-webkit-、-moz-、-ms-、無字首四種:Opera改用blink核心,-o-已淘汰
  • 避免讓選擇符看起來像正規表示式:高階選擇符執行耗時長且不易讀懂,避免使用
指令碼優化
  • 減少重繪和迴流

    • 避免不必要的DOM操作
    • 避免使用document.write
    • 減少drawImage
    • 儘量改變class而不是style,使用classList代替className
  • 快取DOM選擇與計算:每次DOM選擇都要計算和快取
  • 快取.length的值:每次.length計算用一個變數儲存值
  • 儘量使用事件代理:避免批量繫結事件
  • 儘量使用id選擇器id選擇器選擇元素是最快的
  • touch事件優化:使用tap(touchstarttouchend)代替click(注意touch響應過快,易引發誤操作)

常用規則

雅虎軍規

雅虎團隊通過大量實踐總結出以下7類35條前端優化規則,規則詳情請參考這位兄弟的《雅虎前端優化35條規則翻譯》

  • 內容

    • Make Fewer HTTP Requests:減少HTTP請求數
    • Reduce DNS Lookups:減少DNS查詢
    • Avoid Redirects:避免重定向
    • Make Ajax Cacheable:快取AJAX請求
    • Postload Components:延遲載入資源
    • Preload Components:預載入資源
    • Reduce The Number Of DOM Elements:減少DOM元素數量
    • Split Components Across Domains:跨域拆分資源
    • Minimize The Number Of Iframes:減少iframe數量
    • No 404s:消除404錯誤
  • 樣式

    • Put Stylesheets At The Top:置頂樣式
    • Avoid CSS Expressions:避免CSS表示式
    • Choose <link> Over @import:選擇<link>代替@import
    • Avoid Filters:避免濾鏡
  • 指令碼

    • Put Scripts At The Bottom:置底指令碼
    • Make JavaScript And CSS External:使用外部JSCSS
    • Minify JavaScript And CSS:壓縮JSCSS
    • Remove Duplicate Scripts:刪除重複指令碼
    • Minimize DOM Access:減少DOM操作
    • Develop Smart Event Handlers:開發高效的事件處理
  • 影象

    • Optimize Images:優化圖片
    • Optimize CSS Sprites:優化CSS精靈圖
    • Don't Scale Images In HTML:不在HTML中縮放圖片
    • Make Favicon.ico Small And Cacheable:使用小體積可快取的favicon
  • 快取

    • Reduce Cookie Size:減少Cookie大小
    • Use Cookie-Free Domains For Components:使用無Cookie域名的資源
  • 移動端

    • Keep Components Under 25kb:保持資源小於25kb
    • Pack Components Into A Multipart Document:打包資源到多部分文件中
  • 伺服器

    • Use A Content Delivery Network:使用CDN
    • Add An Expires Or A Cache-Control Header:響應頭新增ExpiresCache-Control
    • Gzip ComponentsGzip資源
    • Configure ETags:配置ETags
    • Flush The Buffer Early:儘早輸出緩衝
    • Use Get For AJAX RequestsAJAX請求時使用get
    • Avoid Empty Image Src:避免圖片空連結
2-5-8原則

在前端開發中,此規則作為一種開發指導思路,針對瀏覽器頁面的效能優化。

  • 使用者在2秒內得到響應,會感覺頁面的響應速度很快 Fast
  • 使用者在2~5秒間得到響應,會感覺頁面的響應速度還行 Medium
  • 使用者在5~8秒間得到響應,會感覺頁面的響應速度很慢,但還可以接受 Slow
  • 使用者在8秒後仍然無法得到響應,會感覺頁面的響應速度垃圾死了(此時會有以下四種可能)

    • 難道是網速不好,發起第二次請求 => 重新整理頁面
    • 什麼垃圾頁面呀,怎麼還不開啟 => 離開頁面,有可能轉投競爭對手的網站
    • 垃圾程式猿,做的是什麼頁面啊 => 咒罵開發此頁面的程式猿
    • 斷網了 => 網線斷了?Wi-Fi斷了?訊號不好?話費用完了?
知道這個規則的數字順序怎樣來的嗎,看下鍵盤右方的數字鍵盤由下往上排序:2-5-8
3秒鐘首屏指標

此規則適用於M端,顧名思義就是開啟頁面後3秒鐘內完成渲染並展示內容。

結語

寫到最後總結得差不多了,後續如果我想起還有哪些前端效能優化遺漏的,會繼續在這篇文章上補全,同時也希望各位朋友對文章裡的要點進行補充或者提出自己的見解。歡迎在下方進行評論或補充喔,喜歡的點個贊收個藏,保證你在開發時用得上。

專欄文章

《靈活運用》系列
《必備工具》系列
《隨筆》系列

關注公眾號Uzero,更多前端小乾貨等著你喔!我是JowayYoung,喜歡分享前端技術和生活紀事,學習與生活不落下,每天進步一點點,與大家相伴成長

相關文章