前端性能優(yōu)化指南
前言
發(fā)現(xiàn)總結(jié)性的小干貨可以為大家提升更好的開發(fā)技巧和編碼思維,對代碼量產(chǎn)化提供更扎實的質(zhì)量和支持。這次我們來聊聊大家可能都比較關(guān)心的話題:性能優(yōu)化。
一說到頁面的性能優(yōu)化,大家可能都會想起雅虎軍規(guī)、2-5-8原則、3秒鐘首屏指標等規(guī)則,這些規(guī)則在開發(fā)過程中不是強制要求的,但是有時候為了追求頁面性能的完美和體驗,就不得不對原有的代碼進行修改和優(yōu)化。
下面就結(jié)合自己三年多的開發(fā)經(jīng)驗和大量的項目實踐,整理出一些常用的性能優(yōu)化要點,同時再羅列一下雅虎軍規(guī)、2-5-8原則、3秒鐘首屏指標這三個常用規(guī)則的要點。
為了方便記憶和閱讀,文章使用部分簡寫名詞,解釋如下
- D端:桌面端頁面Desktop End Page
- M端:移動端頁面Mobile End Page
概述指南
- D端優(yōu)化手段在M端同樣適用
- 在M端提出3秒鐘渲染完成首屏指標
- 基于第二點,首屏加載3秒內(nèi)完成或使用Loading進行占位
- 基于聯(lián)通3G網(wǎng)絡(luò)平均338kb/s(2.71mb/s),首屏資源不應(yīng)超過1014kb
- M端因配置原因,除加載外渲染速度也是優(yōu)化重點
- 基于第五點,要合理處理代碼減少渲染損耗
- 基于第二點和第五點,所有影響首屏加載和渲染的代碼應(yīng)在處理邏輯中后置
- 加載完成后,用戶交互使用時也需注意性能
加載優(yōu)化
- 減少HTTP請求:盡量減少頁面的請求數(shù)(首次加載同時請求數(shù)不能超過4個),移動設(shè)備瀏覽器同時響應(yīng)請求為4個請求(Android支持4個,iOS5+支持6個)
- 合并CSS和JS
- 使用CSS精靈圖
- 緩存資源:使用緩存可減少向服務(wù)器的請求數(shù),節(jié)省加載時間,所有靜態(tài)資源都要在服務(wù)器端設(shè)置緩存,并且盡量使用長緩存(使用時間戳更新緩存)
- 緩存一切可緩存的資源
- 使用長緩存
- 使用外聯(lián)的樣式和腳本
- 壓縮代碼:減少資源大小可加快網(wǎng)頁顯示速度,對代碼進行壓縮,并在服務(wù)器端設(shè)置GZip
- 壓縮代碼(多余的縮進、空格和換行符)
- 啟用Gzip
- 無阻塞:頭部內(nèi)聯(lián)的樣式和腳本會阻塞頁面的渲染,樣式放在頭部并使用link方式引入,腳本放在尾部并使用異步方式加載
- 首屏加載:首屏快速顯示可大大提升用戶對頁面速度的感知,應(yīng)盡量針對首屏的快速顯示做優(yōu)化
- 按需加載:將不影響首屏的資源和當(dāng)前屏幕不用的資源放到用戶需要時才加載,可大大提升顯示速度和降低總體流量(按需加載會導(dǎo)致大量重繪,影響渲染性能)
- 懶加載
- 滾屏加載
- Media Query加載
- 預(yù)加載:大型資源頁面可使用Loading,資源加載完成后再顯示頁面,但加載時間過長,會造成用戶流失
- 可感知Loading:進入頁面時Loading
- 不可感知Loading:提前加載下一頁
- 壓縮圖像:使用圖像時選擇最合適的格式和大小,然后使用工具壓縮,同時在代碼中用srcset來按需顯示(過度壓縮圖像大小影響圖像顯示效果)
- 使用TinyJpg和TinyPng壓縮圖像
- 使用CSS3、SVG、IconFont代替圖像
- 使用img的srcset按需加載圖像
- 選擇合適的圖像:webp優(yōu)于jpg,png8優(yōu)于gif
- 選擇合適的大?。菏状渭虞d不大于1014kb、不寬于640px
- PS切圖時D端圖像保存質(zhì)量為80,M端圖像保存質(zhì)量為60
- 減少Cookie:Cookie會影響加載速度,靜態(tài)資源域名不使用Cookie
- 避免重定向:重定向會影響加載速度,在服務(wù)器正確設(shè)置避免重定向
- 異步加載第三方資源:第三方資源不可控會影響頁面的加載和顯示,要異步加載第三方資源
加載過程是最為耗時的過程,可能會占到總耗時的`80%時間(**優(yōu)化重點**)
執(zhí)行優(yōu)化
- CSS寫在頭部,JS寫在尾部并異步
- 避免img、iframe等的src為空:空src會重新加載當(dāng)前頁面,影響速度和效率
- 盡量避免重置圖像大小:多次重置圖像大小會引發(fā)圖像的多次重繪,影響性能
- 圖像盡量避免使用DataURL:DataURL圖像沒有使用圖像的壓縮算法,文件會變大,并且要解碼后再渲染,加載慢耗時長
執(zhí)行處理不當(dāng)會阻塞頁面加載和渲染
渲染優(yōu)化
- 設(shè)置viewport:HTML的viewport可加速頁面的渲染
- <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, minimum-scale=1, maximum-scale=1">
- 減少DOM節(jié)點:DOM節(jié)點太多影響頁面的渲染,盡量減少DOM節(jié)點
- 優(yōu)化動畫
- 盡量使用CSS3動畫
- 合理使用requestAnimationFrame動畫代替setTimeout
- 適當(dāng)使用Canvas動畫:5個元素以內(nèi)使用CSS動畫,5個元素以上使用Canvas動畫,iOS8+可使用WebGL動畫
- 優(yōu)化高頻事件:scroll、touchmove等事件可導(dǎo)致多次渲染
- 函數(shù)節(jié)流
- 函數(shù)防抖
- 使用requestAnimationFrame監(jiān)聽幀變化:使得在正確的時間進行渲染
- 增加響應(yīng)變化的時間間隔:減少重繪次數(shù)
- GPU加速:使用某些HTML5標簽和CSS3屬性會觸發(fā)GPU渲染,請合理使用(過渡使用會引發(fā)手機耗電量增加)
- HTML標簽:video、canvas、webgl
- CSS屬性:opacity、transform、transition
樣式優(yōu)化
- 避免在HTML中書寫style
- 避免CSS表達式:CSS表達式的執(zhí)行需跳出CSS樹的渲染
- 移除CSS空規(guī)則:CSS空規(guī)則增加了css文件的大小,影響CSS樹的執(zhí)行
- 正確使用display:display會影響頁面的渲染
- display:inline后不應(yīng)該再使用float、margin、padding、width和height
- display:inline-block后不應(yīng)該再使用float
- display:block后不應(yīng)該再使用vertical-align
- display:table-*后不應(yīng)該再使用float和margin
- 不濫用float:float在渲染時計算量比較大,盡量減少使用
- 不濫用Web字體:Web字體需要下載、解析、重繪當(dāng)前頁面,盡量減少使用
- 不聲明過多的font-size:過多的font-size影響CSS樹的效率
- 值為0時不需要任何單位:為了瀏覽器的兼容性和性能,值為0時不要帶單位
- 標準化各種瀏覽器前綴
- 無前綴屬性應(yīng)放在最后
- CSS動畫屬性只用-webkit-、無前綴兩種
- 其它前綴為-webkit-、-moz-、-ms-、無前綴四種:Opera改用blink內(nèi)核,-o-已淘汰
- 避免讓選擇符看起來像正則表達式:高級選擇符執(zhí)行耗時長且不易讀懂,避免使用
腳本優(yōu)化
- 減少重繪和回流
- 避免不必要的DOM操作
- 避免使用document.write
- 減少drawImage
- 盡量改變class而不是style,使用classList代替className
- 緩存DOM選擇與計算:每次DOM選擇都要計算和緩存
- 緩存.length的值:每次.length計算用一個變量保存值
- 盡量使用事件代理:避免批量綁定事件
- 盡量使用id選擇器:id選擇器選擇元素是最快的
- touch事件優(yōu)化:使用tap(touchstart和touchend)代替click(注意touch響應(yīng)過快,易引發(fā)誤操作)
常用規(guī)則
雅虎軍規(guī)
雅虎團隊通過大量實踐總結(jié)出以下7類35條前端優(yōu)化規(guī)則,規(guī)則詳情請參考這位兄弟的《雅虎前端優(yōu)化35條規(guī)則翻譯》。
- 內(nèi)容
- Make Fewer HTTP Requests:減少HTTP請求數(shù)
- Reduce DNS Lookups:減少DNS查詢
- Avoid Redirects:避免重定向
- Make Ajax Cacheable:緩存AJAX請求
- Postload Components:延遲加載資源
- Preload Components:預(yù)加載資源
- Reduce The Number Of DOM Elements:減少DOM元素數(shù)量
- Split Components Across Domains:跨域拆分資源
- Minimize The Number Of Iframes:減少iframe數(shù)量
- No 404s:消除404錯誤
- 樣式
- Put Stylesheets At The Top:置頂樣式
- Avoid CSS Expressions:避免CSS表達式
- Choose Over @import:選擇代替@import
- Avoid Filters:避免濾鏡
- 腳本
- Put Scripts At The Bottom:置底腳本
- Make JavaScript And CSS External:使用外部JS和CSS
- Minify JavaScript And CSS:壓縮JS和CSS
- Remove Duplicate Scripts:刪除重復(fù)腳本
- Minimize DOM Access:減少DOM操作
- Develop Smart Event Handlers:開發(fā)高效的事件處理
- 圖像
- Optimize Images:優(yōu)化圖片
- Optimize CSS Sprites:優(yōu)化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:打包資源到多部分文檔中
- 服務(wù)器
- Use A Content Delivery Network:使用CDN
- Add An Expires Or A Cache-Control Header:響應(yīng)頭添加Expires或Cache-Control
- Gzip Components:Gzip資源
- Configure ETags:配置ETags
- Flush The Buffer Early:盡早輸出緩沖
- Use Get For AJAX Requests:AJAX請求時使用get
- Avoid Empty Image Src:避免圖片空鏈接
2-5-8原則
在前端開發(fā)中,此規(guī)則作為一種開發(fā)指導(dǎo)思路,針對瀏覽器頁面的性能優(yōu)化。
- 用戶在2秒內(nèi)得到響應(yīng),會感覺頁面的響應(yīng)速度很快 Fast
- 用戶在2~5秒間得到響應(yīng),會感覺頁面的響應(yīng)速度還行 Medium
- 用戶在5~8秒間得到響應(yīng),會感覺頁面的響應(yīng)速度很慢,但還可以接受 Slow
- 用戶在8秒后仍然無法得到響應(yīng),會感覺頁面的響應(yīng)速度垃圾死了(此時會有以下四種可能)
- 難道是網(wǎng)速不好,發(fā)起第二次請求 => 刷新頁面
- 什么垃圾頁面呀,怎么還不打開 => 離開頁面,有可能轉(zhuǎn)投競爭對手的網(wǎng)站
- 垃圾程序猿,做的是什么頁面啊 => 咒罵開發(fā)此頁面的程序猿
- 斷網(wǎng)了 => 網(wǎng)線斷了?Wi-Fi斷了?信號不好?話費用完了?
知道這個規(guī)則的數(shù)字順序怎樣來的嗎,看下鍵盤右方的數(shù)字鍵盤由下往上排序:2-5-8
3秒鐘首屏指標
此規(guī)則適用于M端,顧名思義就是打開頁面后3秒鐘內(nèi)完成渲染并展示內(nèi)容。
結(jié)語
寫到最后總結(jié)得差不多了,后續(xù)如果我想起還有哪些前端性能優(yōu)化遺漏的,會繼續(xù)在這篇文章上補全,同時也希望各位朋友對文章里的要點進行補充或者提出自己的見解。歡迎在下方進行評論或補充喔,喜歡的點個贊或收個藏,保證你在開發(fā)時用得上。