[譯]Web 的現狀:網頁性能提升指南
原文:https://medium.com/@fox/talk-the-state-of-the-web-3e12f8e413b3
互聯網發展非常迅速,所以我們創造了Web平台。通常我們會忽視連通性等問題,但用戶們卻不會視而不見。一瞥萬維網的現狀,可以發現我們並沒有用同情心、變通意識去構建它,更不要說性能了。
所以,今天的Web是什麼狀態呢?
在這個星球上的74億人中,只有46%可以上網。平均網路速度上限為7Mb/s。更重要的是,有93%的互聯網用戶正在通過移動設備進行訪問——若不適配移動設備將引起用戶反感。通常情況下,數據比我們假設的更昂貴——可能需要1到13小時才能購買500MB的數據包(德國 vs. 巴西;更有趣的統計數據參見 Ben Schwarz 的 Beyond the Bubble: The Real World Performance)。
我們的網站也不是完美的——平均網站是原始Doom遊戲的大小(約3 MB)(請注意,為了統計準確,應使用中位數,閱讀 Ilya Grigorik 的優秀「平均頁面」是一個神話,中檔網站大小目前為1.4MB)。圖像可以輕鬆佔用1.7 MB的帶寬,而JavaScript平均值也有400KB的體積。這不僅是Web平台的問題,原生應用程序可能更糟,還記得為了獲取錯誤修復版本,而下載200MB安裝包的情景嗎?
技術人員經常會發現自己處於特權狀態。隨著最新的高端筆記本電腦、手機和快速有線互聯網連接,很容易讓我們忘記,這些並不是每個人都有的條件(實際上,真的很少)。
如果我們從特權和缺乏同情的角度來構建網路平台,那麼將導致排他性的糟糕體驗。
考慮到設計和開發的性能,我們怎樣才能做得更好?
優化所有資源
理解瀏覽器如何分析和處理資源,是顯著提高性能的最強大但未充分利用的方式之一。事實證明,瀏覽器在嗅探資源方面非常出色,同時解析並確定其優先順序。這裡是關鍵請求的來源。
如果請求中包含用戶視口中呈現內容所必需的資源,則該請求至關重要。
對於大多數網站,它將是HTML、必要的CSS、logo、網路字體,也可能是圖片。在許多情況下,幾十個其他不相關的資源(JavaScript、跟蹤代碼、廣告等)影響了關鍵請求。幸運的是,我們能夠通過仔細挑選重要資源並調整優先順序來控制這種行為。
通過 <link rel =preload> 我們可以手動強制調高資源的優先順序,確保所需的內容按時呈現。這種技術可以顯著改善「交互時間」指標,從而使最佳的用戶體驗成為可能。
關鍵請求對許多人來說,似乎仍然是一個黑匣子,可共享資料的缺乏並不能改變現狀。幸運的是,Ben Schwarz 發表了關於這個問題的非常全面並平易近人的文章——關鍵請求。另外,請參閱Addy的文章,在Chrome中的預載入、預取和優先順序(Preload, Prefetch and Priorities in Chrome)。
[在Chrome開發人員工具中啟用優先順序]
要跟蹤在請求優先順序處理方面的情況,請使用Lighthouse性能工具和關鍵請求鏈審核工具,或查看Chrome開發人員工具中「網路」選項卡下的請求優先順序。
通用性能清單
- 積極地緩存
- 啟用壓縮
- 優化關鍵資源的優先順序
- 使用CDN(Content Delivery Networks)
圖片優化
圖片通常佔網頁傳輸的大部分有效載荷,因此圖片優化可以帶來最大的性能提升。有許多現有的策略和工具可以幫助我們刪除額外的位元組,但是首先應考慮的問題是:「圖片對於我想傳達的信息和效果至關重要嗎?」。如果可以消除它,不僅可以節省帶寬,而且還節省了請求。
在某些情況下,可以通過不同的技術實現類似的結果。比如CSS就具有藝術方向的一系列屬性,例如陰影、漸變、動畫及形狀,允許我們構造適當風格的DOM元素。
選擇正確的格式
如果不能捨棄圖片,確定哪種格式更合適就很重要了。首先要在矢量和光柵圖形之間做出選擇:
- 矢量圖形:解析度獨立,通常體積更小。非常適合logo、icon和簡單的圖形,包括基本形狀(線,多邊形,圓和點)。
- 光柵圖形:呈現更詳細的信息,比較適合相片。
做出首個決定後,可以選擇以下幾種格式:JPEG、GIF、PNG–8、PNG–24,或最新的 WEBP 與 JPEG-XR 格式。有了這麼多的選項,如何確保我們做出正確的選擇?以下是找出最佳格式的基本方法:
- JPEG:顏色非常豐富的圖片(例如照片)
- PNG–8:色彩相對單一的圖片
- PNG–24:局部透明的圖片
- GIF:動圖
Photoshop可以通過各種設置,例如降低質量、降低噪音或色彩數量來優化以上每一種格式。確保設計師了解上述性能實踐,並能夠使用正確的方式優化相應格式的圖片。如果您想了解更多如何處理圖片,請閱讀 Lara Hogan 的好文 Designing for Performance。
試用新格式
圖像格式有幾個較新的玩家,即WebP、JPEG 2000 和 JPEG-XR。它們都是由瀏覽器廠商開發的:Google 的 WebP,Apple 的 JPEG 2000 和 Microsoft 的 JPEG-XR。
WebP 是最受歡迎的競爭者,支持無損和有損壓縮,這使得它非常靈活。無損的 WebP 比 PNG 小26%,比 JPG 小25-34%。WebP 有著74%的瀏覽器支持,它可以安全地進行降級,最多可節省1/3的傳輸位元組。JPG 和 PNG 可以在 Photoshop 和其他圖像處理應用程序以及命令行界面(brew install webp)中轉換為WebP。
如果你想探索其他格式之間的視覺差異,推薦 Github 上這個很贊的 Demo。
用工具和演算法進行優化
即使使用了高效的圖像格式,也不應跳過後處理優化。這一步很重要。
如果您選擇了尺寸相對較小的 SVG,它們也是可以再次壓縮的。SVGO 是一個命令行工具,可以通過剝離不必要的元數據來快速優化 SVG。另外,如果您喜歡Web界面或受操作系統的限制,請使用 Jake Archibald 的 SVGOMG。因為 SVG 是基於 XML 的格式,它也可以在伺服器端進行 GZIP 壓縮。
ImageOptim 是大多其他圖像類型的最好選擇。包括 pngcrush、pngquant、MozJPEG、Google Zopfli等,它在一個全面的開源包中捆綁了一大堆優秀的工具。ImageOptim 可以以 Mac OS 應用程序、命令行界面和 Sketch 插件形式,輕鬆地實現到現有的工作流程中。對於那些在 Linux 或 Windows 上的場景,大多數 ImageOptim 的 CLI 都可以在您的平台上使用。
如果您傾向於嘗試新興的編碼器,Google 今年早些時候發布了 Guetzli——源自 WebP 和 Zopfli 的開源演算法。Guetzli 可以比任何其他可用的壓縮方法生成35%更小體積的 JPEG。唯一的缺點是:處理時間慢(CPU 每處理百萬像素需要1分鐘)。
選擇工具時,請確保它們生成所需的結果並適應團隊的工作流程。理想情況是,將優化過程自動化,這樣就不會產生漏掉的情況。
響應式圖片
十年前,我們使用一種解析度,就可以為所有人服務,但時代變化太快,現今的響應式 Web 已非往日可比。這也是為什麼我們必須要特別留心,去精心優化視覺資源,確保它們適應各種視口設備。幸運的是,感謝 Responsive Images 社區小組,我們可以完美使用 picture 元素和 srcset 屬性(二者都有85%+支持率)。
srcset 屬性
srcset在解析度切換方案中效果最佳——即當我們需要根據用戶的屏幕密度和大小顯示圖像時。基於srcset和size屬性中的一組預定義規則,瀏覽器將選擇最佳圖片,相應地提供給視口。這項技術可以帶來很大的帶寬和請求節省,特別是對於移動用戶。
[srcset 使用示例]
picture 元素
picture元素和media屬性旨在使藝術設計變得容易。通過為不同情形提供不同圖片(通過媒體查詢進行測試),無論什麼解析度,我們都能始終將圖像中最重要的元素保持在焦點。
[picture 元素使用示例]
請務必閱讀 Jason Grigsby 的 Responsive Images 101指南,以便對這兩種方法進行徹底的闡述。
使用圖片 CDN 進行分發
視覺優化的最後一步是分發。所有資源都可以從使用 內容分發網路 中受益,但還有一些針對圖片優化的特定工具,例如 Cloudinary 和 imgx。使用這些服務的好處遠遠超過了減少伺服器上的流量,並顯著降低了響應延遲。
CDN可以很好的解決重圖片網站的複雜度,包括響應式服務與圖片優化。雖然產品不同(價格也是如此),但是大多數方案都是根據設備和瀏覽器,調整大小、裁剪來確定哪種格式最適合用戶。甚至更多——它們可以壓縮、檢測像素密度、水印、識別面部,並允許後置處理能力。藉助這些強大的功能,和將參數附加到URL的能力,以用戶為中心的圖片服務變得十分容易。
圖像性能清單
- 選擇正確的圖片格式
- 儘可能使用矢量圖形
- 如果變化不明顯,則降低圖片質量
- 使用新格式圖片
- 使用工具與演算法優化
- 學習srcset和picture
- 使用圖片 CDN
Web 字體優化
自定義字體是一項非常強大的設計工具。但是能力伴隨著很多責任。現有68%的網站在使用 Web字體,這種類型的資源是性能殺手之一(平均輕鬆可達100KB,取決於變體和字體的數量)。
即使體積不是最大的問題,不可見文本閃動(FOIT)也算是。當Web字體載入中或載入失敗時,會發生FOIT,這會讓空白頁面,從而導致內容無法訪問。首先仔細檢查我們是否需要Web字體可能是值得的。如果真是這樣,有一些策略可以幫助我們減輕對業務的負面影響。
選擇正確的格式
有4種網路字體格式:EOT、TTF、WOFF 和最近的 WOFF2。TTF 和 WOFF 被廣泛使用,擁有超過90%的瀏覽器支持率。根據支持情況,最有可能安全地使用WOFF2,並在舊版瀏覽器降級使用 WOFF。使用WOFF2的優點是,一套定製的預處理和壓縮演算法(如Brotli),並有大約30%的文件大小減少和改進的解析能力。
在@font-face中定義網頁字體的來源時,請使用format()提示來指定應使用哪種格式。
如果您使用 Google Fonts 或 Typekit 來提供字體,這兩種工具都實施了一些策略來優化其性能。Typekit 現在可以非同步地為所有套件提供服務,防止 FOIT 以及允許其JavaScript套件代碼的10天延長緩存期限(而不是默認10分鐘)。Google Fonts 可以根據用戶設備自動提供最小的文件。
審核字體範圍
無論是否自主託管,字體數量、字體體積和樣式,都將顯著影響您的性能預算。
理想情況下,我們只需要一種包括常規和粗體的字體。如果您不確定如何選擇字體範圍,請參考 Lara Hogan 的 Weighing Aesthetics and Performance。
使用Unicode範圍子集
Unicode範圍子集允許將大字體分割成較小的集合。這是一個相對先進的策略,特別是在處理亞洲語言的時候,可能會帶來顯著的節省(你知道中文字體有平均數為 20,000 個字形嗎?)。第一步是將字體限制為必要的語言集,例如拉丁語,希臘語或西里爾語。如果僅使用Web字體做Logo類使用,則應使用Unicode範圍描述符,來選擇特定字元。
Filament Group 發布了一個開源命令行工具,可以根據文件或URL生成必要字形列表的 glyph hanger。或者,基於 Web 的 Font Squirrel Web Font Generator 提供高級子集和優化選項。如果在字體選擇器界面中內置了使用Google Fonts 或 Typekit 選擇語言子集,則使基本子集更容易。
建立字體載入策略
字體是阻塞渲染的——因為瀏覽器必須首先構建 DOM 和 CSSOM;在使用與現有節點相匹配的CSS選擇器之前,瀏覽器並不會下載Web字體。這種行為會明顯延遲文本呈現,通常會導致前面提到的不可見文本閃動(FOIT)。在較慢的網路和移動設備上,FOIT會更加顯著。
實施字體載入策略,可防止用戶無法訪問您的內容。通常,選擇無樣式文本閃動(FOUT)是最簡單和最有效的解決方案。
font-display是提供非 JavaScript 依賴解決方案的新 CSS 屬性。不幸的是,它僅有部分支持(Chrome 和 Opera),目前正在 Firefox 和 WebKit 中開發。儘管如此,它可以並且應該與其他字體載入機制結合使用。
[font-display 屬性實踐]
幸運的是,Typekit 的 Web Font Loader 和 Bram Stein 的 Font Face Observer 可以幫助管理字體載入行為。此外,網頁字體性能專家 Zach Leatherman 發布了字體載入策略綜合指南,這將有助於為您的項目選擇正確的方法。
字體性能清單
- 選擇正確的格式
- 審核字體範圍
- 使用Unicode範圍子集
- 建立字體載入策略
JavaScript 優化
目前,JavaScript 的平均大小為446 KB,已經使其成為第二大的資源類型(第一為圖片)。
我們可能沒有意識到,我們所愛的JavaScript隱藏著更加嚴峻的性能瓶頸。
監控JavaScript的流量
優化交付只是解決網頁膨脹的第一步。JavaScript 下載後,必須由瀏覽器進行解析、編譯和運行。快速瀏覽一些流行的網站,顯而易見的是,gzip 壓縮的 JS 在解壓之後至少變大三倍。事實上,我們正在發送一大堆代碼。
1MB JavaScript 在不同設備上的解析時間。圖片由 Addy Osmani 和他的 JavaScript Start-up Performance 文章提供。
分析解析和編譯時間,對於理解應用程序是否準備好進行交互至關重要。這些耗時根據用戶設備的硬體能力而異。解析和編譯會很容易在低端手機上高出2-5倍。Addy的研究證實,在常規手機上,一個應用程序將需要16秒才能達到互動式狀態,而在桌面電腦上為8秒。分析這些指標至關重要,幸運的是,我們可以通過 Chrome DevTools 來完成。
[在 Chrome 開發工具中查看解析和編譯過程]
請務必閱讀 Addy Osmani 對 JavaScript 啟動性能的詳細說明。
擺脫不必要的依賴
現代軟體包管理器的工作方式,可以輕而易舉地掩蓋依賴關係的數量和大小。webpack-bundle-analyzer 和 Bundle Buddy 是很好的可視化工具,幫助識別出代碼重複、最大性能問題和過時的、不必要的依賴。
圖 webpack bundle analyzer 實踐(譯者註:原gif太大,只能用外鏈了)
通過 VS Code 和 Atom 中的Import Cost擴展,我們可以使導入依賴成本更加明顯。
圖 VS Code Import Code擴展
實現代碼分割
只要有可能,我們就應只提供用戶體驗所必需的資源。向用戶發送一個完整的
bundle.js 文件,包括他們可能永遠看不到的交互效果處理代碼,並不太理想(假設在訪問著陸頁時,去下載處理整個應用程序的 JavaScript)。同樣,我們不應普遍提供針對特定瀏覽器或用戶代理的代碼。
Webpack,最受歡迎的模塊打包器之一,天生具備代碼分割支持。最簡單的代碼分割可以按頁面實現(如用於著陸頁的home.js,聯繫人頁面的contact.js等),Webpack 還提供了一些高級策略,如動態導入及延遲載入,值得一看。
考慮框架選擇
JavaScript 前端框架日新月異。根據2016年的 JavaScript 調查,React 是最受歡迎的選擇。仔細審視架構選擇,可能會發現,您可以使用更為輕量級的替代方案,例如 Preact(請注意,Preact 並不是一個完整的 React 重新實現,只是一個高性能,功能更輕的虛擬 DOM 庫)。類似地,我們可以將較大的庫更換成更小的版本——moment.js換成date-fns(或者在特定情況, href="https://github.com/distilagency/starward/issues/81">刪除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 的方法新設計與性能預算作為參考。
試用性能預算計算器或Chrome擴展瀏覽器卡路里,以幫助創建預算。
持續監控
監控性能不應該是手動的。市面上有很多強大的工具,還可以提供全面的報告。
Google Lighthouse 是一個可以審核性能、可訪問性、漸進式網路應用程序等的開源項目。您可以在命令行中或直接在 Chrome Developer Tools 中使用Lighthouse。
[Lighthouse 運行一次性能審查]
對於持續的追蹤,選擇選擇 Calibre,它可以提供性能預算、設備模擬、分散式監控和許多其他功能,無需我們仔細構建自己的性能套件即可獲得。
[Calibre 報表]
無論您在追蹤什麼,請確保使整個團隊或組織能夠透明地訪問數據。
性能是一項分擔責任,遠遠超過開發人員團隊——我們都應對所創建的用戶體驗負責,不管是什麼角色或職級。
倡導速度和建立協作流程,以便在產品決策或設計早期階段,儘早暴露可能遇到的瓶頸,是非常重要的。
建立性能意識和同情心
關心性能不僅僅是一個業務目標(但是如果您需要通過銷售統計數據來進行銷售,那麼可以通過PWA統計)。這是關於基本的同情和用戶體驗放在第一位。
作為技術專家,我們的責任是,不要讓用戶的注意力和時間放在等待頁面上,而已可以更開心地花費在其他地方。我們的目標是建立意識到時間和人們關注的工具。
提倡性能意識應該是每個人的目標。讓我們抱著性能和同情心,為大家建立一個更好、更有意義的未來吧。
推薦閱讀:
TAG:前端性能優化 |