[譯] 2019 前端性能優化年度總結 — 第三部分

2019 前端性能優化年度總結 — 第三部分

讓 2019 來得更迅速吧~你正在閱讀的是 2019 年前端性能優化年度總結,始於 2016。php

[譯] 2019 前端性能優化年度總結 — 第一部分 [譯] 2019 前端性能優化年度總結 — 第二部分 [譯] 2019 前端性能優化年度總結 — 第三部分 [譯] 2019 前端性能優化年度總結 — 第四部分 [譯] 2019 前端性能優化年度總結 — 第五部分 [譯] 2019 前端性能優化年度總結 — 第六部分css

目錄

資源優化

17. 使用 Brotli 或 Zopfli 來對純文本進行壓縮

2015 年,Google 推出了 Brotli,一種新開源的無損數據格式,現已被全部現代瀏覽器所支持。實際上,Brotli 比 Gzip 和 Deflate 有效得。由於它比較依賴配置,因此這種壓縮可能會(很是)慢,但較慢的壓縮意味着更高的壓縮率。不過它解壓速度很快。因此你能夠考慮 Brotli 爲你的網站所節省的成本html

只有用戶經過 HTTPS 訪問站點時,瀏覽器纔會接受這種格式。那代價是什麼呢?Brotli 並無預安裝在一些服務器上,因此若是沒有自編譯 Nginx,那麼配置就會相對困難。儘管如此,它也並不是是不可攻破的難題,好比,Apache 自 2.4.26 版本起,開始逐步對它進行支持。得益於 Brotli 被衆多廠商支持,許多 CDN 也開始支持它(AkamaiAWSKeyCDNFastlyCloudlareCDN77),你甚至(結合 service worker 一塊兒使用)能夠在不支持它的 CDN 上,啓用 Brotli前端

在最高級別壓縮時,Brotli 會很是緩慢,以致於服務器在開始發送響應前等待動態壓縮資源所花費的時間,可能會抵消文件大小(被壓縮後)的潛在增益。但對於靜態壓縮,應該首選更高級別的壓縮android

或者,你能夠考慮使用將數據編碼爲 Deflate、Gzip 和 Zlib 格式的 Zopfli 的壓縮算法。任何普通的 Gzip 壓縮資源均可以經過 Zopfli 改進的 Deflate 編碼達到比 Zlib 的最大壓縮率小 3% 到 8%的文件大小。問題是壓縮文件大約須要耗費 80 倍的時間。這就是爲何在資源上使用 Zopfli 是個好主意,由於這些資源不會發生太大的變化,它們被設計成只壓縮一次但能夠下載屢次。ios

若是能夠下降動態壓縮靜態資源的成本,那麼這種付出是值得的。Brotli 和 Zopfli 均可以用於任意純文本的有效負載 —— HTML、CSS、SVG、JavaScript 等。nginx

有何對策呢?使用最高級別的 Brotli + Gzip 來預壓縮靜態資源,使用 Brotli 在 1 — 4 級中動態壓縮(動態)HTML。確保服務器正確處理 Brotli 或 Gzip 的協議內容。若是你在服務器上沒法安裝/維護 Brotli,請使用 Zopfli。git

18. 使用響應圖像和 WebP

儘可能使用帶有 srcsetsizes 屬性的響應式圖片和 <picture> 元素響應式圖片。固然,你還能夠經過在原生 <picture> 上使用 WebP圖片以及回退到 JPEG 的機制或者使用協議內容的方式中使用 WebP 格式 (在 Chrome、Opera、Firefox 6五、Edge 18 中都被支持的格式)(參見 Andreas Bovens 的代碼片斷),或者使用協議內容(Accept 頭部)。Ire Aderinokun 也有關於將圖像轉換爲 WebP 圖像的超詳細教程github

原生 Sketch 是支持 WebP 的,可使用 Phtotshop 的 WebP 插件從 Photoshop 中導出 WebP 圖像。固然也存在其餘可用的選項。若是你正在使用 WordPress 或 Joomla,也可使用一些擴展來幫助你本身輕鬆實現對 WebP 的支持,好比適用於 WordPress 的 OptimusCache EnablerJoomla 固然也存在對應可提供支持的擴展 (經過使用 Cody Arsenault)。web

須要注意的是,儘管 WebP 圖像文件大小等價於 Guetzli 和 Zopfli,但它並不支持像 JPEG 這樣的漸進式渲染,這也是用戶之前經過 JPEG 能夠更快地看到實際圖像的緣由,儘管 WebP 圖像在網絡中的傳輸速度更快。使用 JPEG,咱們能夠將一半甚至四分之一的數據提供給用戶,而後再加載剩餘數據,而不是像 WebP 那樣可能會致使有不完整的圖像。你應該根據本身的需求來進行取捨:使用 WebP,你能夠有效減小負載,使用 JPEG,你能夠提升性能感知。

在 Smashing Magazine 中,咱們使用 -opt 後綴來爲圖像命名 —— 好比,brotli-compression-opt.png;這樣,當咱們發現圖像包含該後綴時,團隊成員就會明白這個圖像已經被優化過了。—— 難以置信!—— Jeremy Wagner 出了一本關於 WebP 的書,寫的很好

Responsive Image Breakpoints Generator

響應式圖片端點生成器會自動生成圖像和標記。

19. 圖像的優化是否得當?

當你在開發 landing page 時,特定圖像的加載必須很快,要確保 JPEG 是漸進加載的而且通過了 [mozJPEG] 或者 Guetzli 的壓縮(經過操做掃描級別來改進開始渲染的時間),Google 新開源的編碼器專一於性能感知,並利用了從 Zopfli 和 WebP 中所學的優勢。惟一的缺點是:處理時間慢(每百萬像素須要一分鐘的 CPU)。對於 PNG 來講,咱們可使用 Pingo,對於 SVG 來講,咱們可使用 SVGOSVGOMG。若是你須要快速預覽、複製或下載網站上的全部 SVG 資源,那麼你能夠嘗試使用 svg-grabber

雖然每一篇圖像優化文章都會說,可是我仍是要提醒應該保證矢量資源的乾淨和緊湊。要記得清理未使用的資源,刪除沒必要要的元數據以及圖稿中的路徑點數量(好比 SVG 這類代碼)(感謝 Jeremy!

還有更高級的選項,好比:

  • 使用 Squoosh 以最佳壓縮級別(有損或無損)壓縮。調整和操做圖像。

  • 使用響應式圖像斷點生成器CloudinaryImgix 這樣的服務來實現自動化圖像優化。此外,在許多狀況下,使用 srcsetsizes 能夠得到最佳效果。

  • 要檢查響應標記的效率,你可使用 imaging-heap(一個命令行工具)來檢測不一樣視窗大小和設備像素比的效果。

  • 使用 lazysizes 來延遲加載圖像和 iframes,這是一個經過檢測用戶交互(或以後咱們將討論的 IntersectionObserver)來觸發任何可見性修改的庫。

  • 注意默認加載的圖像,它們可能永遠也用不到 —— 例如,在 carousels、accordions 和 image galleries。

  • 考慮根據請求類型來指定的不一樣圖像顯示以經過 Sizes 屬性切換圖像,好比,操做 sizes 來交換 magnifier 組件中的數據源。

  • 爲防止前景和背景圖像的意外下載,請檢查圖像下載的不一致性

  • 爲了從根本上優化存儲,你可使用 Dropbox 的新格式(Lepton)來對 JPEG 執行平均值可達到 22% 的無損壓縮。

  • 注意 CSS 屬性中的 aspect-ratio 屬性intrinsicsize 屬性,它們容許爲圖像設置寬高和尺寸,所以瀏覽器爲了避免樣式錯亂,能夠在頁面加載期間提早預留一個預約義的佈局槽。

  • 若是你喜歡冒險,爲了更快地經過網絡傳輸圖像,可使用基於 CDN 的實時過濾器 Edge workers 來終止並重排 HTTP/2 流。Edge workers 使用你能夠控制的 JavaScript 流模塊(它們是運行在 CDN 上的,能夠修改響應流),這樣你就能夠控制圖像的傳輸。相對於 service worker 來講,這個過程時間稍長,由於你沒法控制傳輸過程,但它確實適用於 Edge workers。所以,你能夠在針對特定登陸頁面逐步保存的靜態 JPEG 上使用它們。

imaging-heap(一個用於檢測跨視窗大小及設備像素比的加載效率的命令行工具)的輸出樣例,(圖像來源) (詳細預覽)

響應式圖像的將來可能會隨着採用客戶端提示而發生鉅變。客戶端提示內容是 HTTP 的請求頭字段,例如 DPRViewport-WidthWidthSave-DataAccept(指定圖像格式首選項)等。它們應該告知服務器用戶的瀏覽器、屏幕、鏈接等細節。所以,服務器能夠決定如何用對應大小的圖像來填充佈局,並且只提供對應格式所需的圖像。經過客戶端提示,咱們將資源從 HTML 標記中,遷移到客戶端和服務器之間的請求響應協議中。

就像 Ilya Grigorik 說的那樣,客戶端提示使圖像處理更加完整 —— 它們不是響應式圖像的替代品。<picture> 在 HTML 標記中提供了必要藝術方向的控制。客戶端提示爲請求的圖像提供註釋來實現資源選擇的自動化。Service Worker 爲客戶端提供完整的請求和響應管理功能。好比,Service Worker 能夠在請求中附加新的客戶端提示 header 值,重寫 URL 並將圖像請求指向 CDN,根據連接調整響應,用戶偏好等。它不只適用於圖像資源,也適用於全部其餘請求。

對於支持客戶端提示的客戶端,能夠檢測到在圖像上已經節省了 42% 的字節和超過 70% 的 1MB+ 字節數。在 Smashing 雜誌上,咱們一樣能夠檢測到已經提升了 19-32% 的性能。不幸的是,客戶端提示仍然須要獲得瀏覽器的支持才行FirefoxEdge 正在考慮對它的支持。但若是同時提供普通的響應圖像標記和客戶端提示的 <meta> 標記,瀏覽器將評估響應圖像標記並使用客戶端提示 HTTP header 請求相應的圖像。

還不夠?那麼你可使用多種背景圖像技術來提升圖像的感知性能。請記住,處理對比以及模糊沒必要要細節(或刪除顏色)也能夠減少文件大小。你想放大一張小照片而不至於損失質量的話,能夠考慮使用 Letsenhance.io

到目前爲止,這些優化只涉及基本內容。Addy Osmani 出版了一份很是詳細的關於基本圖像優化的指南,這份指南對於圖像壓縮和顏色管理的細節有很深刻的講解。例如,你能夠模糊圖像中沒必要要的部分(經過應用高斯模糊過濾器)來減少文件大小,甚至能夠移除顏色或將圖像轉換爲黑白來進一步縮小文件。對於背景圖像,從 Photoshop 中導出的照片質量只有 0 到 10% 是徹底能夠接受的。不要在 web 上使用 JPEG-XR —— 「在 CPU 上解碼 JPEG-XRs 軟件端這個過程會讓節省字節大小這個潛在地積極影響失效,甚至更糟,尤爲是在 SPAs 狀況下」。

20. 視頻優化是否得當?

到目前爲止,咱們的已經討論完了圖像的相關內容,但咱們避免了關於 GIF 優勢的探討。坦白說,與其加載影響渲染性能和帶寬的重動畫 GIF,不如選擇動態 WebP(GIF 做爲回退)或者用 HTML5 videos 循環來替換它們。是的,帶有 <video> 的瀏覽器性能極差,並且與圖像不一樣的是,瀏覽器不會預加載 <video> 內容,但它們每每比 GIF 更輕量級、更小。別無他法了麼?那麼至少咱們能夠經過 Lossy GIFgifsiclegiflossy 來有損壓縮 GIF。

早期測試代表帶有 img 標籤的內聯視頻相較與等效的 GIF,除了文件大小問題外,前者的顯示的速度要快 20 倍,解碼要快 7 倍。雖然在 Safari 技術預覽中聲明瞭對 <img src=".mp4"> 的技術支持,可是這個特性還遠未普及,所以它在近期內不會被採用

Addy Osmani 推薦用循環內聯視頻來取代 GIF 動畫。文件大小差別明顯(節省了 80%)。(預覽)

前端是不停進步的領域,多年來,視頻格式一直在不停改革。很長一段時間裏,咱們一直但願 WebM 能夠成爲格式的統治者,而 WebP(基本上是 WebM 視頻容器中的一個靜止圖像)將取代過期的圖像格式。儘管這些年來 WebP 和 WebM 得到了支持,但咱們所但願看到的突破並未發生。

在 2018,Alliance of Open Media 發佈了一種名爲 AV1 的視頻格式。AV1 具備和 H.265(H.264 的改進版本)編碼器相似的壓縮,但與後者不一樣的是,AV1 是免費的。H.265 的許可證價格迫使瀏覽器供應商採用性能相同的 AV1:AV1(與 H.265 同樣)的壓縮性能是 WebP 的兩倍

AV1 Logo 2018

AV1 頗有可能成爲網絡視頻的終極標準。(圖像來源:Wikimedia.org) (詳細預覽)

事實上,目前 Apple 使用的是 HEIF 格式和 HEVC (H.265),最新的 IOS 中,全部的照片和視頻都以這些格式保存,而不是純 JPEG 格式。儘管 HEIFHEVC (H.265) 並無在網上被公開使用,但被瀏覽器已經開始對慢慢支持 AV1 了。所以在你的 <video> 標籤中能夠添加 AV1,由於全部的瀏覽器供應商都會慢慢加入對它的支持。

目前來講,使用最普遍的是 H.264,由 MP4 文件提供服務,所以在提供文件以前,請確保你的 MP4 文件用 multipass-encoding 處理過,用 frei0r iirblur 進行了模糊處理(若是適用),moov atom metadata 也被移動到文件頭部,而你的服務器接受字節服務。Boris Schapira 提供了 FFmpeg 的確切說明來最大限度地優化視頻。固然,提供 WebM 格式做爲替代方案也會有所幫助。

視頻回放性能自己就有不少內容能夠研究,若是你想深刻了解它的細節,能夠參閱 Doug Sillar 關於當前視頻現狀視頻傳輸最佳實踐的系列視頻。包括視頻傳輸指標、視頻預加載、壓縮和流媒體等詳細信息。

Zach Leatherman’s Comprehensive Guide to Font-Loading Strategies

Zach Leatherman 的字體加載策略綜合指南爲 web 字體傳輸提供了十幾種選擇。

21. Web 字體優化過了麼?

值得提出的第一個問題就是,你是否能夠首選 UI 系統字體。若是不是上述狀況,那你所提供的 Web 字體頗有可能包括系統字體沒有使用的字形或額外的特性或者字體粗細。你能夠要求字體提供方將字體分組,或者若是你使用的是開源字體,你可使用 GlyphhangerFontsquirrel 自行對它們進行子集化。你甚至可使用 Peter Müller 的 subfont,一個能夠自動化你整個流程的命令行工具,它能夠靜態分析你的頁面,生成最佳 Web 字體子集,而後注入頁面中。

WOFF2 的支持性是最好的,你可使用 WOFF 做爲不支持 WOFF2 的瀏覽器的備用選項 —— 畢竟,系統字體對遺留的瀏覽器版本會更友好。Web 字體的加載有不少,不少,不少的選項。你能夠從 Zach Leatherman 的 "字體加載策略綜合指南"中選擇一種策略(代碼片斷也能夠在 Web 字體加載中找到)。

如今,更好的選項應該是使用 Critical FOFT 結合 preload"The Compromise" 方法。它們都使用兩階段渲染來逐步提供 Web 字體 —— 首先是使用 Web 字體快速準確地渲染頁面所需的小超集,而後再異步加載剩餘部分,不一樣的是 "The Compromise" 技術只在字體加載事件不受支持的的狀況下才異步加載 polyfill,因此默認狀況下不須要加載 polyfill。須要快速入門?Zach Leatherman 有一個 快速入門的 23 分鐘教程和案例研究來幫助你使用字體。

通常而言,使用 preload 資源提示來預加載字體是個好主意,但須要在你的標記中包含 CSS 和 JavaScript 的連接。不然,字體加載會在第一次渲染時消耗時間。儘管如此,有選擇性地選擇重要文件是個好主意。好比,渲染相當重要的文件會有助於你避免可視化和具備破壞性的文本刷新文件。總之,Zach 建議預加載每一個系列的一到兩個字體。若是這些字體不是很關鍵的話,延遲加載一些字體也是有意義的。

沒有人喜歡等待內容的顯示。使用 font-display CSS 描述符,咱們能夠控制字體加載行爲並使內容可被當即讀取(font-display: optional),或者幾乎是當即被讀(font-display: swap)。然而,若是你想避免文本被重排,咱們仍然須要使用字體加載 API,尤爲是 group repaints,或者當你使用第三方主機時。除非你能夠 用 Cloudflare workers 的 Google 字體。討論 Google 字體:考慮使用 google-webfonts-helper,這是一種輕鬆自我託管 Google 字體的方式。若是能夠,那麼自行託管你的字體會賦予你對字體最大程度的控制。

通常而言,若是你選擇 font-display: optional,那麼就須要放棄使用 preload,由於它會提早觸發對 Web 字體的請求(若是你有其餘須要獲取的關鍵路徑資源,就會致使網絡阻塞)。preconnect 能夠更快地獲取跨域字體請求,但要謹慎使用 preload,由於來自不一樣域的預加載字體會致使網絡競爭。全部這些技術都包含在 Zach 的 Web 字體加載

此外,若是用戶在輔助功能首選項中啓用了 Reduce Motion 或選擇數據保護模式(詳細內容可參閱 Save-Data header),那麼最好是選擇不使用 Web 字體(至少是第二階段的渲染中)。或者當用戶碰巧連接速度較慢時(經過 網絡信息 API)。

要檢測 Web 字體的加載性能,能夠考慮使用全部文本可視化的度量標準(字體加載的時,全部內容當即以 Web 字體顯示),以及首次渲染後的 Web 字體重排計數。顯然,這兩種指標越低,性能越好。重要的是考慮到變量字體對性能的需求。它們爲設計師提供了更大的字體選擇空間,代價是單個串行請求與許多單獨的文件請求相反。這個單一的請求可能會緩慢地阻止頁面上的整個排版外觀。不過,好的一面是,在使用可變字體的狀況下,默認狀況下咱們將獲得一個從新的文件流,所以不須要 JavaScript 對從新繪製的內容進行分組。

有沒有一種完美的 Web 字體加載策略? 子集字體爲二階段渲染作好準備,使用 font-display 描述符來聲明它們,使用字體加載 API 對從新繪製的內容進行分組並將字體存儲在持久化的 service worker 緩存中。若是有必要,你能夠回到 Bram Stein 的 Font Face Observer。若是你有興趣檢測字體加載的性能,Andreas Marschke 研究了使用 字體 API 和 UserTiming API 的性能

最後,不要忘記加入 unicode-range,將一個大字體分解成更小的特定語言字體,使用 Monica Dinculescu 的 font-style-matcher 來最小化佈局上的不和諧變化,這是由於回退和 Web 字體之間的大小會產生不一致。

[譯] 2019 前端性能優化年度總結 — 第一部分 [譯] 2019 前端性能優化年度總結 — 第二部分 [譯] 2019 前端性能優化年度總結 — 第三部分 [譯] 2019 前端性能優化年度總結 — 第四部分 [譯] 2019 前端性能優化年度總結 — 第五部分 [譯] 2019 前端性能優化年度總結 — 第六部分

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


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

相關文章
相關標籤/搜索