- 原文地址:The State of the Web
- 原文作者:Karolina Szczur
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:undead25
- 校對者:sun、IridescentMia
網路現狀:效能提升指南
網際網路正在爆發式地增長,我們建立的 Web 平臺也是如此。我們通常都沒有考慮到使用者網路的連通性和使用情景。即使是全球資訊網現狀的一瞥,也可以看出我們還沒有建立起同理心和對形勢變化的認知,更不用說對效能的考慮了。
那麼,現今的網路狀況是怎樣的呢?
地球上 74 億人口中,只有 46% 的人能夠上網,平均網路速度為 7Mb/s。更重要的是,93% 的網際網路使用者都是通過移動裝置上網的 —— 不去迎合手持裝置是不可原諒的。資料往往比我們想象中要昂貴得多 —— 購買 500MB 資料的價格在德國要為此工作 1 個小時,而在巴西需要 13 個小時(更多有趣的統計可以看看 Ben Schwarz 的《泡沫破滅:真實的效能》)。
我們的網站表現得也不盡如人意 —— 平均體積大概是第一版 Doom 遊戲的大小(3MB 左右)(請注意,為了統計準確度,需要使用中位數,推薦閱讀 Ilya Grigorik 的 《“平均頁面”是一個神話》。中位數統計出的網站體積目前為 1.4MB)。圖片可以輕鬆佔用 1.7MB,而 JavaScript 平均為 400KB。不僅僅只有 Web 平臺,本地應用程式也有同樣的問題,你是否遇到過為了修復某些 bug,不得不下載 200MB 的應用呢?
技術人員經常會發現自己處於特權地位。擁有新型高階的筆記本、手機和快速的網路連線。我們很容易忘記,其實並不是每個人都有這樣的條件(實際上只有少部分人而已)。
如果我們只站在自己而不是使用者的角度來構建 web 平臺,那這將導致糟糕的使用者體驗。
我們如何通過在設計和開發中考慮效能來做得更好呢?
資源優化
最能明顯提升效能但未被充分利用的方式是,從瞭解瀏覽器如何分析和處理資源開始。事實證明,當瀏覽器解析和立即確定資源的優先順序時,在資源發現方面表現得非常不錯。下面是關於關鍵請求的解釋。
如果請求包含使用者視口渲染所需的資源,那該請求就是關鍵請求。
對於大多數網站,關鍵請求可以是 HTML、必要的 CSS、LOGO、網路字型,也可能是圖片。事實證明,在大多數情況下,當資源被請求時,許多其他不相關的(JavaScript、追蹤程式碼、廣告等)也被請求了。不過我們能夠通過仔細挑選重要資源,並調整它們的優先順序來避免這種情況發生。
通過 <link rel ='preload'>
,我們可以手動強制設定資源的優先順序,來確保所期望的內容按時渲染。這種技術可以明顯改善“互動時間”指標,從而使最佳使用者體驗成為可能。
由於相關資料的缺乏,關鍵請求對許多人來說似乎仍然是一個黑盒子。幸運的是,Ben Schwarz 發表了一篇非常全面且通俗易懂的文章 —— 《關鍵請求》。另外,你也可以檢視 Addy 關於預載入的文章 —— 《Chrome 中的預載入和優先順序》。
? 要追蹤優先處理請求的效果,你可以使用 Lighthouse 效能檢測工具和關鍵請求鏈路評測,或者檢視 Chrome 開發者工具網路標籤下的請求優先順序。
? 通用效能清單
- 主動快取
- 啟用壓縮
- 優先關鍵資源
- 使用 CDN
圖片優化
頁面傳輸的大部分資料通常都是圖片,因此優化圖片可以帶來很大的效能提升。有許多現有的策略和工具可以幫助我們刪除多餘的位元組,但首先要問的是:“圖片對於傳達後續的資訊和效果至關重要嗎?”。如果可以移除,不僅可以節省頻寬,還可以減少請求。
在某些情況下,我們可以通過不同的技術來實現同樣的效果。CSS 有很多具有藝術性的屬性,例如陰影、漸變、動畫和形狀,這就允許我們用具有合適樣式的 DOM 元素來替代圖片。
選擇正確的格式
如果必須使用圖片,那確定哪種格式比較合適是很重要的。一般都在向量圖和柵格圖之間進行選擇:
- 向量圖形:與解析度無關,檔案通常比較小。特別適用於 LOGO、圖示和由簡單圖形(點、線、圓和多邊形)組成的圖片。
- 柵格影像:表現內容更豐富。適用於照片。
做出上面的決定後,有這樣的幾種格式供我們選擇:JPEG、GIF、PNG-8、PNG-24 或者最新的格式,例如 WEBP 或 JPEG-XR。既然有這麼多的選擇,那如何確保我們選擇的正確性呢?以下是找到最佳格式的基本方法:
- JPEG:色彩豐富的圖片(例如照片)
- PNG–8:色彩不是很豐富的圖片
- PNG–24:具有部分透明度的圖片
- GIF:動畫圖片
Photoshop 在圖片匯出時,可以通過一些設定來對上述格式的圖片進行優化,例如降低質量、減少噪點或者顏色的數量。確保設計師有效能實踐的意識,並通過正確的優化預設來準備合適的圖片。如果你想了解更多關於如何開發圖片的資訊,可以閱讀 Lara Hogan 的 《速度與激情:以網站效能提升使用者體驗》。
嘗試新格式
有這樣幾種由瀏覽器廠商開發的新圖片格式:Google 的 WebP,Apple 的 JPEG 2000 和 Microsoft 的 JPEG-XR。
WebP 是最具有競爭力的,支援無損和有失真壓縮使得它被廣泛應用。無損 WebP 比 PNG 小 26%,比 JPG 小 25-34%。74% 的瀏覽器支援率及降級方案使它可以安全地被使用,最多可節省 1/3 的傳輸位元組。JPG 和 PNG 可以通過 Photoshop 和其他影像處理程式,也可以使用命令列(brew install webp
)將其轉換為 WebP。
如果你想探索這些格式之間的視覺差異,我推薦這個在 Github 上不錯的示例。
使用工具和演算法進行優化
即便使用了高效的圖片格式也需要後續的處理和優化。這一步很重要。
如果你選擇了體積相對較小的 SVG,它們也需要被壓縮。SVGO 是一個命令列工具,可以通過剝離不必要的後設資料來快速優化 SVG。另外,如果你喜歡 Web 介面或者由於作業系統的限制,也可以使用 Jake Archibald 的 SVGOMG。由於 SVG 是基於 XML 的格式,所以它也可以被服務端 GZIP 壓縮。
ImageOptim 是大多數其他圖片格式的絕佳選擇,它將 pngcrush、pngquant、MozJPEG、Google Zopfli 等一些不錯的工具打包進了一個綜合的開源包裡面。作為一個 Mac OS 應用程式、命令列介面和 Sketch 外掛,ImageOptim 可以輕鬆地用於現有的工作流中。大多數 ImageOptim 依賴 CLI 都可以在 Linux 或者 Windows 平臺上使用。
如果你傾向於嘗試新興的編碼器,今年早些時候,Google 釋出了 Guetzli —— 一個源於他們對 WebP 和 Zopfli 研究的開源演算法。Guetzli 可以生成比任何其他可用的壓縮方法少 35% 體積的 JPEG。唯一的缺點是:處理時間慢(每百萬畫素的 CPU 時間為一分鐘)。
選擇工具時,請確保它們能達到預期並適合團隊的工作流。最好能自動化優化,這樣所有圖片都是優化過了的。
響應式圖片
十年前,也許一種解析度就能滿足所有的場景,但隨著時代的變化,響應式網站現今已截然不同。這就是為什麼我們必須特別小心地實施我們精心優化的視覺資源,並確保它們適應各種視口和裝置。幸運的是,感謝響應式影像社群組織,通過 picture
元素和 srcset
屬性(都有 85%+ 的瀏覽器支援率),我們可以完美地做到。
srcset 屬性
srcset
在解析度切換場景中表現得非常不錯 —— 當我們想根據使用者的螢幕密度和大小顯示圖片時。根據 srcset
和 sizes
屬性中一些預定義的規則,瀏覽器將會根據視口選擇最佳的圖片進行展示。這種技術可以節省頻寬和減少請求,特別是對於移動端使用者。
picture 元素
picture
元素和 media
屬性旨在更容易地通往藝術殿堂。通過為不同的條件提供不同的來源(通過 media-queries
測試),無論解析度如何,我們始終能聚焦在最重要的影像元素上。
? 閱讀 Jason Grigsby 的《響應式圖片 101》 可以全面地瞭解這兩種方式。
使用圖片 CDN
圖片效能的最後一步就是分發了。所有資源都可以從使用 CDN 中受益,但有一些特定的工具是專門針對圖片的,例如 Cloudinary 或者 imgx。使用這些服務的好處遠不止於減少伺服器流量,它還可以顯著減少響應延遲。
CDN 可以降低重圖片站點提供自適應和高效能圖片的複雜度。他們提供的服務各不相同(價格也不同),但是大多數都可以根據裝置和瀏覽器進行尺寸調整、裁剪和確定最合適的格式,甚至更多 —— 壓縮、檢測畫素密度、水印、人臉識別和允許後期處理。藉助這些強大的功能和能夠將引數附到 URL 中,使得提供以使用者為中心的圖片變得輕而易舉了。
? 圖片效能清單
- 選擇正確的格式
- 儘可能使用向量圖
- 如果變化不明顯,則降低質量
- 嘗試新格式
- 使用工具和演算法進行優化
- 學習
srcset
屬性和picture
元素 - 使用圖片 CDN
優化網路字型
使用自定義字型的能力是一個非常強大的設計工具。但權利越大,責任就越大。68% 的網站正在使用網路字型,而這種資源是最大的效能瓶頸之一(很容易平均達到 100KB,這取決於字型的各種形態和數量)。
即使體積不是最重要的問題,但不可見文字閃現(FOIT)是。當網路字型在載入中或者載入失敗時,就會發生 FOIT,這會導致空白頁面,從而造成內容無法訪問。這可能值得我們仔細檢查是否需要網路字型。如果是這樣,有一些策略可以幫助我們減輕對效能的負面影響。
選擇正確的格式
有四種網路字型格式:EOT、TTF、WOFF 和近期的 WOFF2。TTF 和 WOFF 被廣泛使用,擁有超過 90% 的瀏覽器支援率。根據你所針對的支援情況,使用 WOFF2 可能最安全,併為老版本瀏覽器降級使用 WOFF。使用 WOFF2 的優點是一整套自定義的預處理和壓縮演算法(如 Brotli)可以 縮小 30% 的檔案大小和改進過的解析效能。
在 @font-face
中定義網路字型的來源時,使用 format()
提示來指定應該使用哪種格式。
如果你正在使用 Google 字型或者 Typekit 字型,他們都實施了一些策略來減輕對效能的影響。Typekit 所有套件現在都支援非同步來預防 FOIT,並且允許其 JavaScript 套件程式碼的快取期限延長 10 天(而不是預設的 10 分鐘)。Google 字型可以根據使用者裝置自動提供最小的檔案。
字型選擇評測
無論是否自託管,字型的數量、體積和樣式都將明顯影響效能。
理想情況下,我們只需要一種包括常規和粗體的字型。如果你不確定如何選擇字型,可以參考 Lara Hogan 的《美學與效能》。
使用 Unicode-range 子集
Unicode-range 子集允許將大字型分割成較小的集合。這是一個相對先進的策略,但它可能會明顯地減少字型體積,特別是在針對亞洲語言的時候(你知道中文字型的平均字形數是 20,000 嗎?)。第一步是將字型限制為必要的語言集,例如拉丁語、希臘語或西里爾語。如果網路字型只是做 LOGO 類的使用,那完全可以使用 Unicode-range 描述符來選擇特定的字元。
Filament Group 釋出的開源命令列工具 glyph hanger 可以根據檔案或 URL 生成需要的字形列表。或者,基於 web 的 Font Squirrel Web Font Generator,它提供高階子集和優化選項。如果使用 Google 字型或者 Typekit,他們在字型選擇介面都提供了語言子集的選擇,這使得確定基本子集更容易。
建立字型載入策略
字型是阻塞渲染的 —— 因為瀏覽器需要首先建立 DOM 和 CSSOM;網路字型用於與現有節點相匹配的 CSS 選擇器之前,它都不會被下載。這種行為顯然延遲了文字的渲染,通常都會導致前面提到的不可見文字閃現(FOIT)。在較慢的網路和移動裝置上,FOIT 則更加明顯。
實施字型載入策略可以避免使用者無法訪問內容。通常,無樣式文字閃現(FOUT)是最簡單和最有效的解決方案。
font-display
是一個新的 CSS 屬性,提供了一個不依賴 JavaScript 的解決方案。不幸的是,它只被部分支援(Chrome 和 Opera),Firefox 和 WebKit 目前在開發中。儘管如此,它可以並且應該與其他字型載入機制結合使用。
幸運的是,Typekit 的網路字型載入器 和 Bram Stein 的 字型觀察者 可以幫助我們管理字型的載入行為。此外,Zach Leatherman 是網路字型效能的專家,他釋出的《字型載入策略綜合指南》將幫助你為你的專案選擇正確的方法。
? 網路字型效能清單
- 選擇正確的格式
- 字型選擇評測
- 使用 Unicode-range 子集
- 建立字型載入策略
優化 JavaScript
目前,JavaScript 包的平均大小為 446KB,這使得使其成為第二大體積型別的資源(僅次於圖片)。
我們可能沒有意識到,我們所鍾愛的 JavaScript 隱藏著更加危險的效能瓶頸。
監控 JavaScript 傳輸
優化傳輸只是抗衡頁面臃腫的一種方法。JavaScript 下載後,必須由瀏覽器進行解析、編譯和執行。瀏覽一些熱門的網站,我們會發現,gzip 壓縮後的 JS 在解壓之後至少變大三倍。實際上,我們正在傳送一大堆程式碼。
1MB JavaScript 在不同的裝置上的解析時間。圖片來源於 Addy Osmani 的《JavaScript 啟動效能》。
分析解析和編譯時間,對於理解應用程式何時準備好進行互動至關重要,這些時間因使用者裝置的硬體能力而異。解析和編譯的時間會很容易地在低端手機上高出 2-5 倍。Addy 的研究表明,一個應用程式在普通手機上需要 16 秒才能達到可互動狀態,而在桌面上是 8 秒
分析這些指標至關重要,幸運的是,我們可以通過 Chrome 開發者工具來完成。
請務必閱讀 Addy Osmani 在《JavaScript 啟動效能》文中的詳細總結。
移除不必要的依賴
現今的包管理方式可以很容易地隱藏依賴包的數量和大小。webpack-bundle-analyzer 和 bundle-buddy 是很好的視覺化工具,可以幫助我們識別出重複程式碼、最大的效能瓶頸以及過時和不必要的依賴包。
通過 VS Code 和 Atom 中的 Import Cost
擴充套件,我們可以明顯知曉匯入包的大小。
實施程式碼分割
只要有可能,我們就應該只提供使用者體驗所必需的資源。向使用者傳送一個完整的 bundle.js
檔案,包括他們可能永遠看不到的互動效果的處理程式碼,這不太理想(試想一下,在訪問著陸頁時,下載了處理整個應用程式的 JavaScript)。同樣,我們不應到處提供針對特定瀏覽器或使用者代理的程式碼。
Webpack 是最受歡迎的打包工具之一,預設支援程式碼分割。最簡單的程式碼分割可以按頁面實施(例如著陸頁面的 home.js
,聯絡頁面的 contact.js
等)。但 Webpack 提供了比較少的高階策略,例如動態匯入或者懶載入,這可能值得研究。
考慮框架選擇
JavaScript 的前端框架日新月異。根據 2016 年的 JavaScript 現狀調查,React 是最受歡迎的。仔細評估架構選型可能會發現,你可以採用更為輕量級的替代方案,例如 Preact(需要注意的是,Preact 並不是一個完整的 React 重新實現,它只是一個具有高效能,功能更輕的虛擬 DOM 庫)。同樣,我們可以將較大的庫替換為更小的替代方案 —— moment.js
換成 date-fns
(或者在特定情況下,刪除 moment.js
中未使用的 locales
)。
在開始一個新專案之前,有必要確定什麼樣的功能是必需的,併為你的需求和目標選擇效能最好的框架。有時這可能意味著選擇寫更多的原生 JavaScript。
? JavaScript 效能清單
- 監控 JavaScript 傳輸
- 移除不必要的依賴
- 實施程式碼分割
- 考慮框架選擇
效能追蹤,前進之路
在大多數情況下,我們討論過的一些策略會對我們正在打造的產品的使用者體驗產生積極的變化。效能可能是一個棘手的問題,有必要長期跟蹤我們調整的效果。
以使用者為中心的效能指標
卓越的效能指標,旨在儘可能接近描繪的使用者體驗。以往的 onLoad
、onContentLoaded
或者 SpeedIndex
對於使用者多久能與頁面進行互動給出的資訊非常少。當僅關注資源傳輸時,我們很難量化感知得到的效能。幸運的是,有一些時間可以很好地描述內容的可視性和互動性。
這些指標是白屏時間、首次有效渲染、視覺完整和可互動時間。
- First Paint 白屏時間:瀏覽器從白屏到第一次視覺變化。
- First Meaningful Paint 首次有效渲染:文字、影像和主要內容都已可見。
- Visually Complete 視覺完整:視口中的所有內容都可見。
- Time to Interactive 可互動時間:視口中的所有內容都可見,並且可以進行互動(JavaScript 主執行緒停止活動)。
這些時間和使用者體驗息息相關,因此可以作為重點進行追蹤。如果可能,將它們全部記錄,否則選擇一兩個來更好地監控效能。其他指標也需要關注,特別是我們傳送的位元組數(優化和解壓縮)。
設定效能預算
所有資料可能會很快變得令人困惑和難以理解。沒有可執行的目標,很容易迷失我們最初的目的。幾年前,Tim Kadlec 寫過關於《效能預算》的概念。
遺憾的是,沒有什麼神奇的公式可以設定它們。效能預算通常歸結為競爭分析和產品目標,而這是每個業務所獨有的。
設定預算時,重要的是要有明顯的差異,通常情況下,至少要有 20% 的改善。實驗和迭代你的預算,可以參考 Lara Hogan 的使用效能預算來接近新設計。
使用效能預算計算器或者 Browser Calories Chrome 擴充程式來幫助你建立預算。
持續監控
效能監控應該是自動化的,市面上有很多提供全面報告的強大工具。
Google Lighthouse 是一個開源專案,它可以審查效能、可訪問性、PWA 等。你可以在命令列中或者直接在 Chrome 開發者工具中使用它。
對於持續的追蹤,可以選擇 Calibre,它提供的效能預算、裝置模擬、分散式監控和許多其他功能是我們不在構建自己的效能套件上花費大量精力是完成不了的。
無論你在哪裡追蹤,請確保資料對於整個團隊或者小型組織裡的整個業務線都是透明和可訪問的。
效能是共同的責任,不僅僅是開發團隊 —— 我們都應對所建立的使用者體驗負責,不管是什麼角色或職級。
在產品決策或者設計階段,提倡速度和建立協作流程以發現可能的瓶頸是非常重要的。
建立效能意識和同理心
關心效能不僅僅是一個業務目標(但如果你需要通過銷售統計資料來進行銷售,那可以使用 PWA 統計)。這關乎於基本的同理心,並把使用者的最大利益放在第一位。
作為技術人員,我們的責任是,不要讓使用者的注意力和時間放在等待頁面上。我們的目標是,建立有時間觀念和以人為本的工具。
提倡效能意識應該是每個人的目標。讓我們抱著效能和同理心,為所有人建立一個更好、更有意義的未來吧。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、React、前端、後端、產品、設計 等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。