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

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


  1. 你是否激活了鏈接以加快傳輸?

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

大部分時間,咱們至少會使用 preconnectdns-prefetch,咱們會當心使用 prefetchpreload;前者只能在你很是肯定用戶後續須要什麼資源的狀況下使用(相似於採購渠道)。注意,prerender 已被棄用,再也不被支持。html

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!)。android

事實上,使用資源提示多是最簡單的提升性能的方法,它確實頗有效。何時該使用什麼?Addy Osmani 已經作了解釋,咱們應該預加載肯定將在當前頁面中使用的資源。預獲取可能用於將來頁面的資源,例如用戶還沒有訪問的頁面所需的 Webpack 包。ios

Addy 的關於 Chrome 中加載優先級的文章展現了 Chrome 是如何精確地解析資源提示的,所以一旦你決定哪些資源對頁面渲染比較重要,你就能夠給它們賦予比較高的優先級。你能夠在 Chrome DevTools 網絡請求表格(或者 Safari Technology Preview)中啓動「priority」列來查看你的請求的優先級。git

the priority column in DevTools

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

例如,因爲字體一般是頁面上的重要資源,因此使用 preload 請求瀏覽器下載字體老是一個好主意。你也能夠動態加載 JavaScript ,從而有效的執行延遲加載。一樣的,由於 <link rel="preload"> 接收一個 media 的屬性,你能夠基於 @media 查詢規則來有選擇性地優先加載資源。web

一些必須牢記於心的陷阱:preload 適用於將資源的下載時間移到請求開始時,可是這些緩存在內存中的預先加載的資源是綁定在所發送請求的頁面上,也就意味着預先加載的請求不能被頁面所共享。再者,preload 與 HTTP 緩存配合得也很好:若是緩存命中則不會發送網絡請求。chrome

所以,它對後發現的資源也很是有用,如:經過 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 很不錯,但也要在實際設備上測試。

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前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索