前端性能優(yōu)化指北-關于有些細節(jié)和思路

2021-3-31    前端達人

目錄

1. 比你最強的競爭對手快20%

2. 反應時間為100毫秒,幀數(shù)是每秒60幀

3. 首次有效渲染時間要低于1.25秒,速度指數(shù)要低于1000

定義你所需要的環(huán)境

4. 選擇和安裝你的開發(fā)環(huán)境

5. 漸進增強(progressive enhancement)

6. AMP還是Instant Articles?

7. 選擇適合你的CDN

開始優(yōu)化

8. 直接確定優(yōu)化順序

9. 使用符合標準的技術

10. 考慮微優(yōu)化和漸進啟動

12. HTTP的緩存頭使用的合理嗎?

13. 減少使用第三方庫,加載JavaScript異步操作

14. 圖片是否被正確優(yōu)化?

15. 圖片的進一步優(yōu)化

15.1 如何使用webpack將靜態(tài)素材快速托管到ImageX,并開啟http/2

16. 網(wǎng)頁字體優(yōu)化了嗎?

17. 快速執(zhí)行關鍵部分的CSS

18. 通過tree-shaking和code-splitting減少凈負載

19. 提升渲染性能

20. 預熱網(wǎng)絡連接,加快傳輸速度

HTTP/2

21. 準備好使用HTTP/2

22. 適當部署HTTP/2

23. 確保服務器安全可靠

快速入門

 

微優(yōu)化是保持性能最好的辦法,但是又不能有太過明確的優(yōu)化目標,因為過于明確的目標會影響在項目中做的每一個決定。以下是一些不同的模型,請按照自己舒服的順序閱讀

1. 比你最強的競爭對手快20%

根據(jù)一個心理學研究,你的網(wǎng)站最少在速度上比別人快20%,才能讓用戶感覺到你的網(wǎng)站比別人的更快。這個速度說的不是整個頁面的加載時間,而是開始加載渲染的時間,首次有效渲染時間(例如頁面需要加載主要內容的時間),或者交互時間(指的是頁面或者應用中主要的頁面加載完成,并主備好與用戶進行交互的時間)。

在Moto G(一個中端三星設備)和Nexus 4(比較主流的設備)上衡量開始渲染時間(用WebPagetest)以及首頁有效渲染時間(用Lighthouse),最好是在一個開放的實驗室中,使用規(guī)范的3G,4G和Wi-Fi鏈接。

 

你可以通過你的分析報告看看你的用戶處在哪個階段,選取其中前90%的用戶體驗來做測試。接著收集數(shù)據(jù),建一個表格,篩去20%的數(shù)據(jù)并預設一個目標(如:性能預算)?,F(xiàn)在你可以將上述兩個值進行對比檢測。如果你始終維持著你的目標并且通過一點一點改變腳本去加快交互時間,那么上述方法就是合理可行的。

 

如果前端工程師們都在積極的參與項目概念,UX以及視覺設計的決定,這將會給整個項目帶來巨大收益。地圖設計的決定違背了性能理念,所以他在這份清單內的順序有待考慮。

2. 反應時間為100毫秒,幀數(shù)是每秒60幀

RAIL性能模型會為你提供一個優(yōu)秀的目標,既盡最大的努力在用戶初始操作后的100毫秒內提供反饋。為了達到這個目標,頁面需要放棄權限,并將權限在50毫秒內交回給主線程。對于像動畫一樣的高壓點,最好的方法就是什么都不做,因為你永遠無法達到最小絕對值。
同理,動畫的每一幀都需要在16毫秒內完成,這樣才能保證每秒60幀(一秒/60=16.6毫秒),如果可以的話最好能在10毫秒內完成。因為瀏覽器需要一定的時間去在屏幕上渲染新的幀,而且你的代碼需要在16.6毫秒內完成執(zhí)行。要注意,上述目標應用于衡量項目的運行性能,而非加載性能。

3. 首次有效渲染時間要低于1.25秒,速度指數(shù)要低于1000

縱使這個目標實現(xiàn)起來非常困難,你的最終目標也應該是讓開始渲染時間低于1秒且速度指數(shù)低于1000(在網(wǎng)速快的地方)。對于首次有效渲染時間,上限最好是1250毫秒。對于移動端,3G下移動設備首次渲染時間低于3秒都是可以接受的。稍微高一點也沒關系,但千萬別高太多。

定義你所需要的環(huán)境

4. 選擇和安裝你的開發(fā)環(huán)境

不要過多的關注當下最流行的工具,堅持選擇適合自己開發(fā)環(huán)境的工具,例如Grunt、Gulp、Webpack、PostCSS,或者組合起來的工具。只要這個工具運行的速度夠快,而且沒有給你的維護帶來太大問題,這就夠了。

5. 漸進增強(progressive enhancement)

在構建前端結構的時候,應始終將漸進增強作為你的指導原則。首先設計并且構建核心體驗,隨后再完善那些為高性能瀏覽器設計的高級特性的相關體驗,創(chuàng)建彈性體驗。如果你的網(wǎng)頁可以在使用低速網(wǎng)絡、老舊顯示器的很慢的電腦上運行飛快,那么在光纖高配電腦上它只會運行的更快。

6. AMP還是Instant Articles?

根據(jù)你整體組織結構的優(yōu)先順序和策略,你可以考慮使用Google的AMP或Facebook的Instant Articles。要知道沒有這些你也可以達到不錯的性能,但是AMP可以提供一個性能不錯的免費的內容分發(fā)網(wǎng)絡框架(CDN),Instant Articles可以在Facebook上促進你的性能。你也可以建立progressive web AMP。

7. 選擇適合你的CDN

根據(jù)你的動態(tài)數(shù)據(jù)量,可以將一部分內容外包給靜態(tài)網(wǎng)站生成工具,將它置于CDN上,從中生成一個靜態(tài)版本,從而避免那些數(shù)據(jù)庫的請求。也可以選擇基于CDN的靜態(tài)主機平臺,通過交互組件豐富你的頁面(JAMStack)。注意CDN是否可以很好的處理(或分流)動態(tài)內容。沒必要單純的將你的CDN限制為靜態(tài)。反復檢查CDN是否執(zhí)行了內容的壓縮和轉化,檢查智能HTTP/2傳輸和緩存服務器(ESI),注意哪些靜態(tài)或動態(tài)的部分處在CDN的邊緣(最接近用戶的服務器)。

開始優(yōu)化

8. 直接確定優(yōu)化順序

首先應該弄清楚你想解決的問題是什么。檢查一遍你所有的文件(JavaScript,圖片,字體,第三方script文件以及頁面中重要的模塊,例如輪播,復雜信息圖標和多媒體內容),并將他們分類。
列一個表格。明確瀏覽器上應該有的基礎核心內容,哪些部分屬于為高性能瀏覽器設計的升級體驗,哪些是附加內容(那些不必要或者可以被延時加載的部分,例如字體,不必要的樣式,輪播組件,播放器,社交網(wǎng)站入口,很大的圖片)。

9. 使用符合標準的技術

使用符合標準的技術向過時的瀏覽器提供核心體驗,向老式瀏覽器提供增強體驗, 同時對所加載的內容要有嚴格的把控。即首要加載核心體驗部分,將增強部分放在DomContentLoaded,把額外內容發(fā)在load事件中。以前我們可以通過瀏覽器的版本推斷出設備的性能,但現(xiàn)在我們已經(jīng)無法推測了。因為現(xiàn)在市場上很多廉價的安卓手機都不考慮內存限制和CPU性能,直接使用高版本的Chrome瀏覽器。一定要注意,在我們沒有其他選擇的時候,我們選擇的技術同時可能成為我們的限制。

10. 考慮微優(yōu)化和漸進啟動

在一些應用中,可以在渲染頁面前先初始化應用。最好先顯示框架,而不是一個進度條或指示器。使用可以加速初始渲染時間的模塊或技術(例如tree-shakingcode-splitting),因為大部分性能問題來自于應用引導程序的初始分析時間。還可以在服務器上提前編譯,從而減輕部分客戶端的渲染過程,從而快速輸出結果。最后,考慮使用Optimize.js來加快初始加載速度,它的原理是包裝優(yōu)先級高的調用函數(shù)(雖然現(xiàn)在已經(jīng)沒什么必要了)。

 

到底采用客戶端渲染還是服務器端渲染?不論哪種做法,我們的目標都是建立漸進啟動:使用服務器端渲染可以得到很短的首次有效渲染時間,這個渲染過程也包括小部分的JavaScript文件,目的是使交互時間盡可能的接近首次有效渲染時間。接下來,盡可能的增加一些應用的非必要功能。不幸的是,正如Paul Lewis所說,框架基本上對開發(fā)者是沒有優(yōu)先級的概念的,因此漸進啟動在很多庫和框架上是很難實施的。如果你有時間的話,還是考慮使用策略去優(yōu)化你的性能吧。

12. HTTP的緩存頭使用的合理嗎?

仔細檢查一下例如expires,cache-control,max-age以及其他HTTP緩存頭是否被正確的使用。一般來說,資源不論在短時間(如果它會被頻繁改動)還是不確定的時間內(如果它是靜態(tài)的)都是可緩存的——你大可在需要的時候在URL中成改版本。如果可能,使用為指紋靜態(tài)資源設計的Cache-control:immutable,從而避免二次驗證(2016年12月,只有FireFox在https://處理中支持)。你可以使用,Heroku的primer on HTTP caching headers,Jake Archibald的 ”Caching Best Practices”,還有IIya Grigorik的HTTP caching primer作為指導。

13. 減少使用第三方庫,加載JavaScript異步操作

當用戶請求頁面時,瀏覽器會抓取HTML同時生成DOM,然后抓取CSS并建立CSS對象模型,最后通過匹配DOM和CSS對象生成渲染樹。在需要處理的JavaScript文件被解決之前,瀏覽器不會開始對頁面進行渲染。作為開發(fā)者,我們要明確的告訴瀏覽器不要等待,直接開始渲染。具體方法是使用HTML中的deferasync兩個屬性。事實上,defer更好一些(因為對于IE9及以下用戶對于IE9及以下用戶,很有可能會中斷腳本)。同時,減少第三方庫和腳本的使用,尤其是社交網(wǎng)站的分享按鍵和<iframe>嵌入(比如地圖)。你可以使用靜態(tài)的社交網(wǎng)站分享按鍵(例如SSBG的)和指向交互地圖的靜態(tài)鏈接去代替他們。

14. 圖片是否被正確優(yōu)化?

盡可能的使用帶有srcset,sizes還有<picture>元素的響應式圖片。你也可以利用<picture>元素的AVIF、WEBP格式,用JPEG格式作為替補(參見Andreas Bovens的code snippet)或是使用內容協(xié)商(使用接受頭)。本身可以使用自己的PS或者skecth嘗試導出,若不能導出,可以嘗試 火山引擎的ImageX圖像處理服務(不知道怎么使用可以自行百度搜索 "火山引擎 ImageX")可以支持多種格式輸出,比如AVIF、webp格式;

我曾經(jīng)寫過這篇文檔可以對照一下:高效率圖像壓縮處理服務, 參考截圖:

 

你也可以使用客戶端提示,現(xiàn)在瀏覽器也可以做到。在用來生成響應圖片的源文件過少時,使用響應圖片斷點生成器。

15. 圖片的進一步優(yōu)化

當你在編寫登錄界面的時候,發(fā)現(xiàn)頁面上的圖片加載的特別快,這時你需要確認一下圖片進一步優(yōu)化的思路只要有三點:

  • 降低圖片的分辨率,如果瀏覽器中展示區(qū)域100*100,此時展示 400*400 就屬于資源浪費,這也是顯著提高圖片響應速度最直接的方法;
  • 降低圖片壓縮的質量,圖片壓縮質量,使用有損壓縮,比如圖片壓縮質量90 和75對人眼可見的范圍內都可以接受,常見支持有損壓縮的圖片格式比如,jpeg、wepb、heic、avif等圖片格式支持圖片有損壓縮;
  • 改變圖像壓縮的壓縮方式,改變圖片的壓縮算法也能更高效的提高圖片優(yōu)化圖片提高速度,比如 常見圖像壓縮率(圖像畫質等同前提下): HEIF (heic) > AVIF (avif、avis) >webP(awebp) > jpeg > png 等;

正常情況下PNG是原圖格式,體積特別大,巧的是業(yè)界對PNG 有pngquant 使用Median Cut量化算法的修改版本和其他技術來緩解Median Cut的不足,可以最大效率保留信息的前提下降低png 的體積大??;如果我們把如上的一些優(yōu)化處理起來,我使用的過程中發(fā)現(xiàn),火山引擎的imagex 已經(jīng)完美的支持了上面三者的使用方法:下面我舉個例子做一下說明:

http://imagex.75live.com/tos-cn-i-n9b2vwdhz3/public/attachments/2021/03/11/GyVrojIWFkQOKSAzYnUmlQxvaESnPaZYxgpu9v1Z.png~tplv-n9b2vwdhz3-12:300:200.webp 這個是 png的原圖處理好的結果,在這個url中imagex 給出了一種url語義,"~tplv--模板名稱:[模板參數(shù)].圖像格式"  通過改變300:300 能改改變壓縮率,通過參數(shù)能夠調整壓縮質量,通過改變webp-->avif 可以轉換成不同的壓縮方法;

更巧妙的是在這,就算指定輸出png后仍然還可以設置質量參數(shù)

 

如果你還覺得不夠,那你可以通過多重背景圖片技術來提高圖片的感知性能。

15.1 如何使用webpack將靜態(tài)素材快速托管到ImageX,并開啟http/2

這里發(fā)現(xiàn)一個第三方寫的但被官方推薦的開源插件https://github.com/Cmaxd/veimagex-webpack-loader ,通過配置webpack-loader 插件的方式可以將圖片上傳到ImageX,然后將圖片使用不同的圖片模板訪問就可以滿足需求,同一個圖片可以使用多個地址,例如avif、webp、jpeg 使用 <picture> 標簽進行降級 或者判斷瀏覽器支持降級;

 

16. 網(wǎng)頁字體優(yōu)化了嗎?

你用來修飾網(wǎng)頁字體的服務很有可能毫無用處,包括字形和額外的特性。如果你在使用開源的字體,嘗試用字體庫中某一個小的子集或是自己歸類一個小的子集從而壓縮文件大小(例如通過一些特殊的注音符號引用Latin)。WOFF2 support是個非常不錯的選擇,如果瀏覽器不支持,那你可以將WOFF和OTF作為備用。你也可以從Zach Leatherman的“Comprehensive Guide to Font-Loading Strategies”一文中選擇一個合適的策略,然后使用服務器來緩存字體。如果想要快速入門,Pixel Ambacht的教程與案例會讓你的字體變得盡然有序。如果你用的是第三方服務器主機,沒辦法自己在服務器上對字體進行操作,一定看看Web Font Loader。

17. 快速執(zhí)行關鍵部分的CSS

為了確保瀏覽器盡可能快的渲染你的頁面,先收集頁面首次可見部分的CSS文件(也叫決定性CSS或上半版CSS)進行渲染,然后將它加入頁面的<head>部分,從而避免重復操作。因為慢啟動階段對交換包大小的限制,你關鍵CSS文件的大小也被限制在14KB左右。如果高于這個值,瀏覽器需要重復一些步驟來獲取更多的樣式。關鍵CSS是允許你這樣做的??赡軐γ總€模板都需要這個操作。如果可能,考慮一下用Fiament Group用的條件內斂方法。

通過HTTP/2,關鍵CSS可以單獨存為CSS文件,通過服務器傳輸,而且可以避免HTML膨脹。服務器傳輸缺乏連續(xù)支持,并且存在一些超高速緩存的問題(Hooman Beheshti演示的前144頁)。事實上,這樣會導致網(wǎng)絡緩沖區(qū)膨脹。因為TCP的慢啟動,服務器傳輸在穩(wěn)定的連接下會更有效率。所以你可能需要建立帶有緩存的HTTP/2服務器傳輸機制。但請記住,新的cache-digest規(guī)則會否定手動建立的需要緩存的服務器的請求。

18. 通過tree-shaking和code-splitting減少凈負載

Tree-shaking是通過保留那些在項目過程中真正需要的代碼從而清理你的構建過程的一種方式。你可以用Webpack 2來提出那些沒用的住配置文件,用UnCSSHelium從CSS中取出不需要的樣式。同理,也可以考慮學習一下如何編寫高效的CSS選擇器,以及如何避免膨脹和高費的樣式

Code-splitting是另一個Webpack特性,它可以根據(jù)按需加載的塊將你的代碼分開。只要你在代碼中定義了分離點,Webpack便會處理好相關的輸出文件。它基本上能保證你初始下載的內容很小,而且在需求被添加時按需請求代碼。

Rollup所展示的結果要比Browserify配置文件所顯示的好得多。所以當我們想使用類似工具的時候,或許應該看看Rollupify,它將ECMAScript2015模塊變成了一個更大的CommonJS模塊——因為小模塊沒準有出乎意料的高性能成本,這源自于你對打包工具模塊系統(tǒng)的選擇。

19. 提升渲染性能

使用類似CSS containment的方法對高消耗組建進行隔離,從而限制瀏覽器樣式的范圍,可以作用在為無canvas的瀏覽工作的布局和裝飾工作中,或是用在第三方工具上。要確保頁面滾動和出現(xiàn)動畫效果時沒有延遲,別忘了之前提到過的每秒60幀的原則。如果沒辦法做到,那就盡可能保證每秒幀數(shù)的大致范圍在15到60幀。使用CSS中的will-change通知瀏覽器哪些元素和屬性發(fā)生了變化。也記得要衡量渲染執(zhí)行中的性能(可以用DevTools)??梢詤⒄誙dacity上Paul Lewis的免費課程——瀏覽器渲染優(yōu)化,作為入門。還有一篇Sergey Chikuyonok的文章講了如何正確的用GPU動畫。

20. 預熱網(wǎng)絡連接,加快傳輸速度

使用頁面框架,對高消耗組建延遲加載(字體,JS文件,循環(huán)播放,視頻和內嵌框架)。使用資源提示來節(jié)省在dns-prefetch(指的是在后臺執(zhí)行DNS檢索),preconnect(指要求瀏覽器在后臺進行握手鏈接(DNS,TCP,TLS)),prerender(指要求瀏覽器在后臺對特定頁面進行渲染),preload(指的是提前取出暫不執(zhí)行的源文件)。根據(jù)你瀏覽器的支持情況,盡量使用preconnect來代替dns-prefetch,而且在使用prefetchprerender要特別小心——后者(prerender)只有在你非常確信用戶下一步操作的情況下再去使用(比如購買流程中)。

HTTP/2

21. 準備好使用HTTP/2

Google開始向著更安全網(wǎng)頁的方向努力,并且將所有Chrome上的HTTP網(wǎng)頁定義為“不安全”時,你或許應該考慮是繼續(xù)使用HTTP/1.1,還是將目光轉向HTTP/2環(huán)境。雖然初期投入比較大,但是使用HTTP/是大趨勢,而且在熟練掌握之后,你可以使用service worker和服務器推送技術讓行性能再提升一大截。
現(xiàn)在,Google計劃把所有HTTP頁面標記為不安全,并且將HTTP安全指示器設置為與Chrome用來攔截HTTPS的紅色三角相同的圖標。

使用HTTP/2的環(huán)境的缺點在于你要轉移到HTTPS上,并且根據(jù)你HTTP/1.1用戶的數(shù)量(主要指使用過時操作系統(tǒng)和過時瀏覽器的用戶),你需要適應不同的建構過程,才能發(fā)送不同的建構。注意:不論是遷移還是新的構建過程都可能非常棘手而且耗時很多。

 

22. 適當部署HTTP/2

重申,使用HTTP/2協(xié)議之前,你需要徹底排查目前為止你所使用協(xié)議的情況。你需要在打包組建和同時加載很多小組間之間找到平衡。

一方面,你可能想要避免將很多資源鏈式鏈接,與其將你全部的界面分割成許多小模塊,不如將他們壓縮使之成為建構過程的一部分,之后給它們賦予可檢索的信息并加載它們。這樣的話,對一文件將不再需要重新下載整個樣式清單或JavaScript文件。

另一方面,封裝是很有必要的,因為一次向瀏覽器發(fā)送太多JavaScript文件會出問題。首先,壓縮會造成損壞。得益于dictionary reuse,壓縮大文件不會對文件造成損害,壓縮小文件則不然。確實有方法可以解決這個問題,但這不是本文討論的范疇。其次,瀏覽器還沒有優(yōu)化到可以對類似工作流進行優(yōu)化。例如,Chrome會引發(fā)進程間通信(IPCs),這些通信的數(shù)量與資源的數(shù)量成正比,而這成百上千個資源將會消耗大量的瀏覽器的執(zhí)行時間。
Chrome的Jake Archibald建議,為了用HTTP/2達到最好的效果,考慮一下逐步加載CSS文件

當然你可以考慮逐步加載CSS文件。很顯然,你這樣做對HTTP/1.1的用戶非常不利,所以你可能需要根據(jù)不同的瀏覽器建立多個版本來應對你的調度過程,這樣就會使過程略微復雜。你也可以避免HTTP/2連接的合并,同時受益于HTTP/2來使用域名碎片,但是實現(xiàn)起來有些困難。

我們到底應該做什么呢?如果你粗略的用過HTTP/2,似乎成功的發(fā)送過10個左右的包(在老是瀏覽器上運行的也不錯)。那你就能著手開始試驗并且為你的網(wǎng)站找到平衡點。

23. 確保服務器安全可靠

所有的瀏覽器都支持HTTP/2并且使用TLS,這是有你可能想要避免安全警告,并刪除頁面上沒用的元素。好好檢查你的安全頭部是否設置正確,排除已知的缺陷檢查證書

如果還沒有遷移到HTTP, 你那可以先看看HTTPS準則(The HTTPS-Only Standard)。確保所有外部插件和監(jiān)視腳本都能被HTTPS正確加載,確保沒有跨站腳本出現(xiàn),HTTP腳本傳輸?shù)陌踩^內容安全頭也都設置正確。

快速入門

這份清單綜合性很強,幾乎介紹了所有的可用的優(yōu)化方式。那么,如果你只有一個小時進行優(yōu)化,你應該干什么呢?讓我們從中總結10個最有用的來。別忘了在你開始優(yōu)化前和結束優(yōu)化后,記錄你的結果,包括開始渲染時間以及在3G,有限連接下的速度。

但沒關系,本文只是一個普通大綱(希望能做到綜合性強),你應該根據(jù)自己的工作環(huán)境列一份適合自己的清單。最重要的,在開始優(yōu)化之前,先對項目中存在的問題有一個明確的了解。


轉自:csdn論壇 ,

藍藍設計www.bouu.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務

分享本文至:

日歷

鏈接

個人資料

藍藍設計的小編 http://www.bouu.cn

存檔