- 原文地址:Front-End Performance Checklist 2018 - Part 3
- 原文做者:Vitaly Friedman
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:Cherry
- 校對者:Ryou、z
下面你將會看到你可能須要考慮到的前端性能優化問題,以保證你的應用具備快速和流暢的響應時間。css
在 2005 年,Google 推出了 Brotli,一個新的開源無損數據壓縮格式,如今 被全部的現代瀏覽器所支持。實際上,Brotli 比 Gzip 和 Deflate 更有效。取決於設置信息,壓縮可能會很是慢。可是緩慢的壓縮過程會提升壓縮率,而且仍然能夠快速解壓。固然,解壓縮速度很快。html
只有當用戶經過 HTTPS 訪問網站時,瀏覽器纔會採用。Brotli 如今還不能預裝在某些服務器上,並且若是不本身構建 NGINX 和 UBUNTU 的話很難部署。不過這也並不難。實際上,一些 CDN 是支持的,甚至 能夠也能夠經過服務器在不支持 CDN 的狀況下啓用 Brotli。前端
在最高級別的壓縮下,Brotli 的速度會變得很是慢,以致於服務器在等待動態壓縮資源時開始發送響應所花費的時間可能會使文件大小的任何潛在收益都無效。可是,對於靜態壓縮,高壓縮比的設置比較受歡迎 —— (感謝 Jeremy!)android
或者,你能夠考慮使用 Zopfli 的壓縮算法,將數據編碼爲 Deflate,Gzip 和 Zlib 格式。Zopfli 改進的 Deflate 編碼使得任何使用 Gzip 壓縮的文件受益,由於這些文件大小比 用Zlib 最強壓縮後還要小 3% 到 8%。問題在於壓縮文件的時間是原來的大約 80倍。這就是爲何雖然 使用 Zopfli 是一個好主意可是變化並不大,文件都須要設計爲只壓縮一次能夠屢次下載的。ios
比較好的方法是你能夠繞過動態壓縮靜態資源的成本。Brotli 和 Zopfli 均可以用於明文傳輸 —— HTML,CSS,SVG,JavaScript 等。git
有什麼方法呢?在最高等級和 Brotli 的 1-4 級動態壓縮 HTML 使用 Brotli+Gzip 預壓縮靜態資源。同時,檢查 Brotli 是否支持 CDN,(例如 KeyCDN,CDN77,Fastly)。確保服務器可以使用 Brotli 或 gzip 處理內容。若是你不能安裝或者維護服務器上的 Brotli,那麼請使用 Zopfli。github
srcset
,sizes
和 <picture>
元素使用 響應式圖片。也能夠經過 <picture>
元素使用 WebP 格式的圖像(Chrom,Opera,Firefox soon支持),或者一個 JPEG 的回調(見 Andreas Bovens 的 code snippet)或者經過使用內容協商(使用 Accept
頭信息)。Sketch 自己就支持 WebP 而且 WebP 圖像能夠經過使用 WebP 插件 從 PhotoShop 中導出。也有其餘選擇可使用,若是你使用 WordPress 或者 Joomla,也有能夠輕鬆支持 WebP 的擴展,例如 Optimus 和 Cache Enabler(經過 Cody Arsenault)web
你能夠仍然使用 client hints,但仍須要得到一些瀏覽器支持。沒有足夠的資源支持響應式圖片?使用 斷點發生器 或者相似 Cloudinary 這樣的服務自動優化圖片。一樣,在許多狀況下,只使用 srcset
和 sizes
會有不錯的效果。算法
On Smashing Magazine, we use the postfix -opt
for image names — for example, brotli-compression-opt.png
; whenever an image contains that postfix, everybody on the team knows that the image has already been optimized.chrome
響應圖像斷點生成器自動生成圖像和標記生成。
每個圖像優化的文章會說明,但始終保持保持矢量資產清潔老是值得提醒的。確保清理未使用的資源,刪除沒必要要的元數據,並減小圖稿中的路徑點數量(從而減小SVG代碼)。(感謝,Jeremy!)
到目前爲止,這些優化只涵蓋了基礎知識。 Addy Osmani 已經發布了 一個很是詳細的基本圖像優化指南,深刻到圖像壓縮和顏色管理的細節。 例如,您能夠模糊圖像中沒必要要的部分(經過對其應用高斯模糊濾鏡)以減少文件大小,最終甚至能夠開始移除顏色或將圖像變成黑白色,以進一步縮小圖像尺寸。 對於背景圖像, 從Photoshop 導出的照片質量爲 0 到 10% 也是絕對能夠接受的。
那麼 GIF 圖片呢?咱們可使用 循環的 HTML5 視頻,而不是影響渲染性能和帶寬的重度 GIF 動畫,而使用循環的 HTML5 視頻,<video>
會使得 瀏覽器的性能很慢,並且與圖像不一樣的是,瀏覽器不會預先加載 <video>
內容。 至少咱們可使用 Lossy GIF, gifsicle 或者 giflossy 添加有損壓縮 GIF。
好 消息: 但願不久之後咱們可使用 <img src=".mp4">
來加載視頻, 早期的測試代表 img
標籤比同等大小的 GIF 顯示的要 快 20 多倍解析速度與要快 7 倍多。
還不夠好?那麼,你也可使用 多種 背景 圖像 技術 提升圖像的感知性能。 記着,減小對比度 和模糊沒必要要的細節(或消除顏色)也能夠減少文件的大小。 你須要放大一個小照片而不失真?考慮使用 Letsenhance.io
Zach Leatherman 的 字體加載策略綜合指南 提供了十幾種更好的網頁字體發送選項
WOFF2 很是好,你可使用 WOFF 和 OTF 做爲不支持它的瀏覽器的備選。另外,從 Zach Leatherman 的《字體加載策略綜合指南》(代碼片斷也能夠做爲 Web字體加載片斷)中選擇一種策略,並使用服務器緩存持久地緩存字體。是否是感受小有成就?Pixel Ambacht 有一個 快速教程和案例研究,讓你的字體按順序排列。
若是你沒法從你的服務器拿到字體並依賴於第三方主機,請確保使用 字體加載事件(或對不支持它的瀏覽器使用 Web字體加載器)FOUT 要優於 FOIT; 當即開始渲染文本,並異步加載字體 —— 也可使用 loadCSS。 你也能夠 擺脫本地安裝的操做系統字體,也可使用 可變的 字體。
怎麼才能是一個無漏洞的字體加載策略? 從 font-display
開始,而後回到 Font Loading API,而後回到 Bram Stein 的 Font Face Observer(感謝 Jeremy!)若是你有興趣從用戶的角度來衡量字體加載的性能, Andreas Marschke 探索了 使用 Font API 和 UserTiming API 進行性能跟蹤
此外,不要忘記包含 font-display:optional
描述符來提供彈性和快速的字體回退,unicode-range
將大字體分解成更小的語言特定的字體,以及Monica Dinculescu 的字體樣式匹配器 用來解決因爲兩種字體之間的大小差別,最大限度地減小了佈局上的震動的問題。
defer
和 async
屬性。事實證實,咱們 應該把 defer
改成 async
(由於 ie9 及如下不支持 async)。 另外,如上所述,限制第三方庫和腳本的影響,特別是使用社交共享按鈕和嵌入的 <iframe>
嵌入(如地圖)。 大小限制 有助於防止 JavaScript 庫過大:若是您不當心添加了大量依賴項,該工具將通知你並拋出錯誤。 您可使用 靜態社交分享按鈕(如經過 SSBG )和 靜態連接 來代替交互式地圖。
當目標變得可見或不可見時執行回調函數,因此當它攔截視口時,能夠在元素變得可見以前開始採起一些行動。 事實上,咱們能夠精確地控制觀察者的回調什麼時候被調用,使用 rootMargin
(根邊緣)和 threshold
(一個數字或者一個數字數組來表示目標可見度的百分比, 瞄準)。Alejandro Garcia Anglada 發表了一個 簡單的教程 關於如何實際實施的方便教程。
你甚至能夠經過向你的網頁添加 漸進式圖片加載 來將其提高到新的水平。 與 Facebook,Pinterest 和 Medium 相似,你能夠首先加載低質量或模糊的圖像,而後在頁面繼續加載時,使用 Guy Podjarny 提出的 LQIP (Low Quality Image Placeholders) technique(低質量圖像佔位符)技術替換它們的所有質量版本。
若是技術提升了用戶體驗,觀點就不同了,但它確定會提升第一次有意義的繪畫的時間。咱們甚至能夠經過使用 SQIP 建立圖像的低質量版本做爲 SVG 佔位符來實現自動化。 這些佔位符能夠嵌入 HTML 中,由於它們天然能夠用文本壓縮方法壓縮。 Dean Hume 在他的文章中 描述了 如何使用相交觀測器來實現這種技術。
瀏覽器支持成都如何呢?Decent,與 Chrome,火狐,Edge 和 Samsung Internet 已經支持了。 WebKit 目前 正在開發中。若是瀏覽器不支持呢? 若是不支持交叉點觀察者,咱們仍然能夠 延遲加載 一個 polyfill 或當即加載圖像。甚至還有一個 library。
一般,咱們會使用懶加載來處理全部代價較大的組件,如 字體,JavaScript,輪播,視頻和 iframe。 你甚至能夠根據網絡質量調整內容服務。網絡信息 API,特別是 navigator.connection.effectiveType
(Chrome 62+)使用 RTT 和下行鏈路值來更準確地表示鏈接和用戶能夠處理的數據。 您可使用它來徹底刪除視頻自動播放,背景圖片或 Web 字體,以便鏈接速度太慢。
<head>
中,從而減小往返。 因爲在慢啓動階段交換包的大小有限,因此關鍵 CSS 的預算大約是 14 KB。若是超出這個範圍,瀏覽器將須要額外往返取得更多樣式。 CriticalCSS 和 Critical 能夠作到這一點。 你可能須要爲你使用的每一個模板執行此操做。 若是可能的話,考慮使用 Filament Group 使用的 條件內聯方法。
使用 HTTP/2,關鍵 CSS 能夠存儲在一個單獨的 CSS 文件中,並經過 服務器推送 來傳遞,而不會增大 HTML 的大小。 問題在於,服務器推送是很 麻煩,由於瀏覽器中存在許多問題和競爭條件。 它一直不被支持,並有一些緩存問題(參見 [Hooman Beheshti介紹的文章](Hooman Beheshti's presentation) 114 頁內容)。事實上,這種影響多是 負面的,會使網絡緩衝區膨脹,從而阻止文檔中的真實幀被傳送。 並且,因爲 TCP 啓動緩慢,彷佛服務器推送在熱鏈接上 更加有效。
即便使用 HTTP/1,將關鍵 CSS 放在根目錄上的單獨文件中也是有 好處的,有時甚至比緩存和內聯更爲有效。 Chrome 請求這個頁面的時候會再發送一個 HTTP 鏈接到根目錄,從而不須要 TCP 鏈接來獲取這個 CSS(感謝 Philip!)
須要注意的一點是:和 preload
不一樣的是,preload
能夠觸發來自任何域的預加載,而你只能從你本身的域或你所受權的域中推送資源。 一旦服務器獲得來自客戶端的第一個請求,就能夠啓動它。 服務器將資源壓入 Push 緩存,並在鏈接終止時被刪除。 可是,因爲能夠在多個選項卡之間重複使用 HTTP/2 鏈接,因此推送的資源也能夠被來自其餘選項卡的請求聲明(感謝 Inian!)。
目前,服務器並無一個簡答的方法得知被推送的資源 是否已經存在於用戶的緩存中,所以每一個用戶的訪問都會繼續推送資源。所以,您可能須要建立一個 緩存監測 HTTP/2 服務器推送機制。若是被提取,您能夠嘗試從緩存中獲取它們,這樣能夠避免再次推送。
但請記住,新的 cache-digest
規範 無需手動創建這樣的 「緩存感知」 的服務器,基本上在 HTTP/2 中聲明的一個新的幀類型就能夠表達該主機的內容。所以,它對於 CDN 也是特別有用的。
對於動態內容,當服務器須要一些時間來生成響應時,瀏覽器沒法發出任何請求,由於它不知道頁面可能引用的任何子資源。 在這種狀況下,咱們能夠預熱鏈接並增長 TCP 擁塞窗口大小,以便未來的請求能夠更快地完成。 並且,全部內聯配置對於服務器推送都是較好的選擇。事實上,Inian Parameshwaran 對 HTTP/2 Push 和 HTTP Preload 進行了比較 深刻的研究,內容很不錯,其中包含了您可能須要的全部細節。服務器究竟是推送仍是不推送呢?你能夠閱讀一下 Colin Bendell 的 Should I Push?。
底線:正如 Sam Saccone 所說,preload
有利於將資產的開始下載時間更接近初始請求, 而服務器推送是一個完整的 RTT(或 更多,這取決於您的服務器反應時間 —— 若是你有一個服務器能夠防止沒必要要的推送。