[譯] 2018 前端效能優化清單 - 第 4 部分

LeviDing發表於2018-01-20

下面是前端效能問題的概述,您可能需要考慮以確保您的響應時間是快速和平滑的。


  1. 你是否啟用了連線以加快傳輸?

使用 資源提示 來節約時間,如 dns-prefetch (在後臺執行 DNS 查詢),preconnect (告訴瀏覽器在後臺進行連線握手(DNS, TCP, TLS)),prefetch (告訴瀏覽器請求一個資源) and preload (預先獲取資源而不執行他們)。

大部分時間,我們至少會使用 preconnectdns-prefetch,我們會小心使用 prefetchpreload;前者只能在你非常確定使用者後續需要什麼資源的情況下使用(類似於採購渠道)。注意,prerender 已被棄用,不再被支援。

Note that even with preconnect and dns-prefetch, the browser has a limit on the number of hosts it will look up/connect to in parallel, so it's a safe bet to order them based on priority (thanks Philip!).

請注意,即使使用 preconnectdns-prefetch,瀏覽器也會對它將並行查詢或連線的主機數量進行限制,因此最好是將它們根據優先順序進行排序(感謝 Philip!)。

事實上,使用資源提示可能是最簡單的提高效能的方法,它確實很有效。什麼時候該使用什麼?Addy Osmani 已經做了解釋,我們應該預載入確定將在當前頁面中使用的資源。預獲取可能用於未來頁面的資源,例如使用者尚未訪問的頁面所需的 Webpack 包。

Addy 的關於 Chrome 中載入優先順序的文章展示了 Chrome 是如何精確地解析資源提示的,因此一旦你決定哪些資源對頁面渲染比較重要,你就可以給它們賦予比較高的優先順序。你可以在 Chrome DevTools 網路請求表格(或者 Safari Technology Preview)中啟動“priority”列來檢視你的請求的優先順序。

the priority column in DevTools

DevTools 中的 "Priority" 列。圖片來源於:Ben Schwarz,重要的請求

例如,由於字型通常是頁面上的重要資源,所以使用 preload 請求瀏覽器下載字型總是一個好主意。你也可以動態載入 JavaScript ,從而有效的執行延遲載入。同樣的,因為 <link rel="preload"> 接收一個 media 的屬性,你可以基於 @media 查詢規則來有選擇性地優先載入資源。

一些必須牢記於心的陷阱:preload 適用於將資源的下載時間移到請求開始時,但是這些快取在記憶體中的預先載入的資源是繫結在所傳送請求的頁面上,也就意味著預先載入的請求不能被頁面所共享。再者,preload 與 HTTP 快取配合得也很好:如果快取命中則不會傳送網路請求。

因此,它對後發現的資源也非常有用,如:通過 background-image 載入的一幅 hero image,內聯關鍵 CSS (或 JavaScript),並預先載入其他 CSS (或 JavaScript)。此外,只有當瀏覽器從伺服器接收 HTML,並且前面的解析器找到了 preload 標籤後,preload 標籤才可以啟動預載入。由於我們不等待瀏覽器解析 HTML 以啟動請求,所以通過 HTTP 頭進行預載入要快一些。早期提示將有助於進一步,在傳送 HTML 響應標頭之前啟動預載入。

請注意:如果你正在使用 preloadas 必須定義否則什麼都不會載入,還有,預載入字型時如果沒有 crossorigin 屬性將會獲取兩次

  1. 你優化渲染效能了嗎?

使用 CSS containment 隔離昂貴的元件 - 例如,限制瀏覽器樣式、隱藏導航欄的佈局和繪製,第三方元件的範圍。確保在滾動頁面時沒有延遲,或者當一個元素進行動畫時,持續地達到每秒 60 幀。如果這是不可能的,那麼至少要使每秒幀數持續保持在 60 到 15 的範圍。使用 CSS 的 will-change 通知瀏覽器哪個元素的哪個屬性將要發生變化。

此外,評估執行時渲染效能(例如,使用 DevTools)。可以通過學習 Paul Lewis 免費的關於瀏覽器渲染優化的 Udacity 課程和 Emily Hayman 的文章優化網頁動畫和互動來入門。

同樣,我們有 Sergey Chikuyonok 這篇文章關於如何正確使用 GPU 動畫。注意:對 GPU-composited 層的更改是代價最小的,如果你能通過“不透明”和“變形”來觸發合成,那麼你就是在正確的道路上。

  1. 你優化過渲染體驗嗎?

元件以何種順序顯示在頁面上以及我們如何給瀏覽器提供資源固然重要,但是我們同樣也不能低估了感知效能的角色。這一概念涉及到等待的心理學,主要是讓顧客在其他事情發生時保持忙碌。這就涉及到了感知管理優先開始提前完成寬容管理

這一切意味著什麼?在載入資源時,我們可以嘗試始終領先於客戶一步,所以將很多處理放置到後臺,相應會很迅速。讓客戶參與進來,我們可以用骨架螢幕例項演示),而不是當沒有更多優化可做時、用載入指示,新增一些動畫/過渡欺騙使用者體驗

HTTP/2

  1. 遷移到 HTTPS,然後開啟 HTTP/2.

在谷歌提出向更安全的網頁進軍以及認為 Chrome 中所有的 HTTP 網頁都是“不安全”的後,遷移到[HTTP/2]((https://http2.github.io/faq/)是不可避免的。HTTP/2[支援得非常好]it isn't going anywhere; and, in most cases, you're better off with it.(不知道啥意思,求助)。一旦執行在 HTTPS 上,你至少能夠在 service workers 和 server push 方面獲得顯著的效能提升

HTTP/2

最終,谷歌計劃將所有 HTTP 頁面標記為不安全的,並將有問題的 HTTPS 的 HTTP 安全指示器更改為紅色三角形。(圖片來源

最耗時的任務將是遷移到 HTTPS,取決於你的 HTTP/1.1 使用者基礎有多大(即使用舊版作業系統或瀏覽器的使用者),你將不得不為舊版的瀏覽器效能優化傳送不同的構建版本,這需要你採用不同的構建流程。注意:開始遷移和新的構建過程可能會很棘手,而且耗費時間。對於本文的其餘部分,我假設您將要麼切換到 HTTP/2,要麼已經切換到 HTTP/2。

  1. 正確地部署 HTTP/2.

再次,通過 HTTP/2 提供資源需要對現階段正如何提供資源服務進行區域性檢查。您需要在打包模組和並行載入多個小模組之間找到一個良好的平衡。最終,仍然是最好的請求就是沒有請求,然而我們的目標是在快速傳輸資源和快取之間找到一個好的平衡點。

一方面,你可能想要避免合併所有資源,而不是把整個介面分解成許多小模組,壓縮他們(作為構建過程的一部分),通過“偵察”的方法引用和並行載入它們。一個檔案的更改不需要重新下載整個樣式表或 JavaScript。這樣還可以[最小化解析時間](https://css- s.com/musings-on-http2-and-bundling/),並將單個頁面的負荷保持在較低的水平。

另一方面,打包仍然很重要。首先,壓縮將獲益。大包的壓縮將從字典重用中獲益,而小的單獨的包則不會。有標準的工作來解決這個問題,但現在還遠遠不夠。其次,瀏覽器還沒有為這種工作流優化。例如,Chrome 將觸發程式間通訊(IPCs),與資源的數量成線性關係,因此頁面中如果包含數以百計的資源將會造成瀏覽器效能損失。

Progressive CSS loading

為了獲得使用 HTTP/2 最好的效果,可以考慮使用漸進地載入 CSS,正如 Chrome 的 Jake Archibald 所推薦的。

你可以嘗試漸進地載入 CSS。顯然,通過這樣做,您會傷害 HTTP/1.1 使用者,因此您可能需要為不同的瀏覽器生成和提供不同的構建流程,作為部署過程的一部分,這是事情變得稍微複雜的地方。你可以使用 HTTP/2 連線合並,它允許您使用 HTTP/2 提供的域分片,但在實踐中實現這一目標是很困難的。

怎麼做呢?如果你執行在 HTTP/2 之上,傳送 6-10 個包是個理想的折中(對舊版瀏覽器也不會太差)。對於你自己的網站,你可以通過實驗和測量來找到最佳的折中。

  1. 你的服務和 CDNs 支援 HTTP/2 嗎?

不同的服務和 CDNs 可能對 HTTP/2 的支援情況不一樣。使用TLS 夠快了嗎?來檢視你的可選服務,或者快速的檢視你的服務的效能以及你想要其支援的特性。

Is TLS Fast Yet?

Is TLS Fast Yet? allows you to check your options for servers and CDNs when switching to HTTP/2.

當你想遷移到 HTTP/2 時 TLS 夠快了嗎?可以讓你檢視你的可選服務和 CDNs。

  1. 是否啟動了 OCSP stapling?

通過在你的服務上啟動 OCSP stapling,你可以加速 TLS 握手。線上證照狀態協議(OCSP)的提出是為了替代證照登出列表(CRL)協議。兩個協議都是用於檢查一個 SSL 證照是否已被撤回。但是,OCSP 協議不需要瀏覽器花時間下載然後在列表中搜尋認證資訊,因此減少了握手時間。

  1. 你是否已採用了 IPv6?

因為 IPv4 即將用完以及主要的行動網路正在迅速採用 IPv6(美國已經達到50% 的 IPv6 使用閾值),[將你的 DNS 更新到 IPv6]((https://www.paessler.com/blog/2016/04/08/monitoring-news/ask-the-expert-current-status-on-ipv6) 以應對未來是一個好的想法。只要確保在網路上提供雙棧支援,就可以讓 IPv6 和 IPv4 同時執行。畢竟,IPv6 不是向後相容的。研究顯示,多虧了“鄰居”發現(NDP)和路由優化,IPv6 使得這些網站快了 10% 到 15%。

  1. 使用了 HPACK 壓縮嗎?

如果你使用 HTTP/2,請再次檢查,確保您的服務針對 HTTP 響應頭部實現 HPACK 壓縮以減少不必要的開銷。由於 HTTP/2 服務相對較新,它們可能不完全支援該規範,HPACK 就是一個例子。可以使用 H2spec 這個偉大的(如果技術上很詳細)工具來檢查。HPACK作品

h2spec

H2spec (View large version) (Image source)

H2spec (超大圖) (圖片來源)

  1. 確保你的服務安全性是“防彈”的

所有實現了 HTTP/2 的瀏覽器都在 TLS 上執行,因此您可能希望避免安全警告或頁面上的某些元素不起作用。仔細檢查你的安全頭部被正確設定消除已知的漏洞檢查你的證照。同時,確保所有外部外掛和跟蹤指令碼通過 HTTPS 載入,不允許跨站點指令碼,HTTP 嚴格傳輸安全頭內容安全策略頭是正確的設定。

  1. 是否使用了 service workers 來快取以及用作網路回退?

沒有什麼網路效能優化能快過使用者機器上的本地快取。如果你的網站執行在 HTTPS 上,使用 “Service Workers 的實用指南” 在一個 service worker 中快取靜態資源並儲存離線回退(甚至離線頁面)並從使用者的機器中檢索它們,而不是訪問網路。同時,參考 Jake 的 Offline Cookbook 和 Udacity 免費課程“離線 Web 應用程式”。瀏覽器支援?如上所述,它得到了廣泛支援 (Chrome、Firefox、Safari TP、Samsung Internet、Edge 17+),但不管怎麼說,它都是網路。它有助於提高效能嗎?是的,它確實做到了

測試和監控

  1. 你是否在代理瀏覽器和舊版瀏覽器中測試過?

在 Chrome 和 Firefox 中進行測試是不夠的。看看你的網站在代理瀏覽器和舊版瀏覽器中是如何工作的。例如,UC 瀏覽器和 Opera Mini,在亞洲有大量的市場份額 (達到 35%)。在你感興趣的國家測量平均網路速度從而避免在未來發現“大驚喜”。測試網路節流,並模擬一個高 DPI 裝置。BrowserStack 很不錯,但也要在實際裝置上測試。

[譯] 2018 前端效能優化清單 - 第 4 部分

k6 可以讓你像寫單元測試一樣編寫效能測試用例。

  1. 是否啟用了持續監控?

有一個WebPagetest私人的例項總是有利於快速和無限的測試。但是,一個帶有自動警報的連續監視工具將會給您提供更詳細的效能描述。設定您自己的使用者計時標記來度量和監視特定的業務指標。同時,考慮新增自動化效能迴歸警報來監控隨著時間而發生的變化。

使用 RUM 解決方案來監視效能隨時間的變化。對於自動化的類單元測試的負載測試工具,您可以使用 k6 指令碼 API。此外,可以瞭解下 SpeedTrackerLighthouseCalibre

速效方案

這個列表非常全面,完成所有的優化可能需要很長時間。所以,如果你只有一個小時的時間來進行重大的改進,你會怎麼做?讓我們把這一切歸結為10個低掛的水果。顯然,在你開始之前和完成之後,測量結果,包括開始渲染時間以及在 3G 和電纜連線下的速度指數。

  1. 測量實際環境的體驗並設定適當的目標。一個好的目標是:第一次有意義的繪製 < 1 s,速度指數 < 1250,在慢速的 3G 網路上的互動 < 5s,對於重複訪問,TTI < 2s。優化渲染開始時間和互動時間。

  2. 為您的主模板準備關鍵的 CSS,並將其包含在頁面的 <head> 中。(你的預算是 14 KB)。對於 CSS/JS,檔案大小不超過 170 KB gzipped(解壓後 0.8-1 MB)。

  3. 延遲載入儘可能多的指令碼,包括您自己的和第三方的指令碼——特別是社交媒體按鈕、視訊播放器和耗時的 JavaScript 指令碼。

  4. 新增資源提示,使用 dns-lookuppreconnectprefetchpreload 加速傳輸。

  5. 分離 web 字型,並以非同步方式載入它們(或切換到系統字型)。

  6. 優化影象,並在重要頁面(例如登入頁面)中考慮使用 WebP。

  7. 檢查 HTTP 快取頭和安全頭是否設定正確。

  8. 在伺服器上啟用 Brotli 或 Zopfli 壓縮。(如果做不到,不要忘記啟用 Gzip 壓縮。)

  9. 如果 HTTP/2 可用,啟用 HPACK 壓縮並開啟混合內容警告監控。如果您正在執行 LTS,也可以啟用 OCSP stapling。

  10. 在 service worker 快取中儘可能多的快取資產,如字型、樣式、JavaScript 和影象。

清單下載(PDF, Apple Pages)

記住了這個清單,您就已經為任何型別的前端效能專案做好了準備。請隨意下載該清單的列印版PDF,以及一個可編輯的蘋果頁面文件,以定製您需要的清單:

如果你需要其他選擇,你也可以參考 Rublic 的前端清單和 Jon Yablonski 的“設計師的 Web 效能清單”。

動身吧

一些優化可能超出了您的工作或預算範圍,或者由於需要處理遺留程式碼而顯得過度濫用。沒問題!使用這個清單作為一個通用(並且希望是全面的)指南,並建立適用於你的環境的你自己的問題清單。但最重要的是,測試和權衡您自己的專案,以在優化前確定問題。祝大家 2018 年的效能大漲!

**非常感謝 Guy Podjarny, Yoav Weiss, Addy Osmani, Artem Denysov, Denys Mishunov, Ilya Pukhalski, Jeremy Wagner, Colin Bendell, Mark Zeman, Patrick Meenan, Leonardo Losoviz, Andy Davies, Rachel Andrew, Anselm Hannemann, Patrick Hamann, Andy Davies, Tim Kadlec, Rey Bango, Matthias Ott, Mariana Peralta, Philipp Tellis, Ryan Townsend, Mohamed Hussain S H, Jacob Groß, Tim Swalling, Bob Visser, Kev Adamson, Aleksey Kulikov and Rodney Rehm 對這篇文章的校對,同樣也感謝我們出色的社群,分享了他們在效能優化工作中學習到的技術和經驗,供大家使用。你們真正的非常了不起! **


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章