- 原文地址:The State of the Web
- 原文做者:Karolina Szczur
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:undead25
- 校對者:sun、IridescentMia
互聯網正在爆發式地增加,咱們建立的 Web 平臺也是如此。咱們一般都沒有考慮到用戶網絡的連通性和使用情景。即便是萬維網現狀的一瞥,也能夠看出咱們尚未創建起同理心和對形勢變化的認知,更不用說對性能的考慮了。javascript
那麼,現今的網絡情況是怎樣的呢?php
地球上 74 億人口中,只有 46% 的人可以上網,平均網絡速度爲 7Mb/s。更重要的是,93% 的互聯網用戶都是經過移動設備上網的 —— 不去迎合手持設備是不可原諒的。數據每每比咱們想象中要昂貴得多 —— 購買 500MB 數據的價格在德國要爲此工做 1 個小時,而在巴西須要 13 個小時(更多有趣的統計能夠看看 Ben Schwarz 的《泡沫破滅:真實的性能》)。css
咱們的網站表現得也不盡如人意 —— 平均體積大概是初版 Doom 遊戲的大小(3MB 左右)(請注意,爲了統計準確度,須要使用中位數,推薦閱讀 Ilya Grigorik 的 《「平均頁面」是一個神話》。中位數統計出的網站體積目前爲 1.4MB)。圖片能夠輕鬆佔用 1.7MB,而 JavaScript 平均爲 400KB。不只僅只有 Web 平臺,本地應用程序也有一樣的問題,你是否遇到過爲了修復某些 bug,不得不下載 200MB 的應用呢?html
技術人員常常會發現本身處於特權地位。擁有新型高端的筆記本、手機和快速的網絡鏈接。咱們很容易忘記,其實並非每一個人都有這樣的條件(實際上只有少部分人而已)。前端
若是咱們只站在本身而不是用戶的角度來構建 web 平臺,那這將致使糟糕的用戶體驗。java
咱們如何經過在設計和開發中考慮性能來作得更好呢?react
最能明顯提高性能但未被充分利用的方式是,從瞭解瀏覽器如何分析和處理資源開始。事實證實,當瀏覽器解析和當即肯定資源的優先級時,在資源發現方面表現得很是不錯。下面是關於關鍵請求的解釋。android
若是請求包含用戶視口渲染所需的資源,那該請求就是關鍵請求。webpack
對於大多數網站,關鍵請求能夠是 HTML、必要的 CSS、LOGO、網絡字體,也多是圖片。事實證實,在大多數狀況下,當資源被請求時,許多其餘不相關的(JavaScript、追蹤代碼、廣告等)也被請求了。不過咱們可以經過仔細挑選重要資源,並調整它們的優先級來避免這種狀況發生。ios
經過 <link rel ='preload'>
,咱們能夠手動強制設置資源的優先級,來確保所指望的內容按時渲染。這種技術能夠明顯改善「交互時間」指標,從而使最佳用戶體驗成爲可能。
因爲相關資料的缺少,關鍵請求對許多人來講彷佛仍然是一個黑盒子。幸運的是,Ben Schwarz 發表了一篇很是全面且通俗易懂的文章 —— 《關鍵請求》。另外,你也能夠查看 Addy 關於預加載的文章 —— 《Chrome 中的預加載和優先級》。
🛠 要追蹤優先處理請求的效果,你可使用 Lighthouse 性能檢測工具和關鍵請求鏈路評測,或者查看 Chrome 開發者工具網絡標籤下的請求優先級。
📝 通用性能清單
頁面傳輸的大部分數據一般都是圖片,所以優化圖片能夠帶來很大的性能提高。有許多現有的策略和工具能夠幫助咱們刪除多餘的字節,但首先要問的是:「圖片對於傳達後續的信息和效果相當重要嗎?」。若是能夠移除,不只能夠節省帶寬,還能夠減小請求。
在某些狀況下,咱們能夠經過不一樣的技術來實現一樣的效果。CSS 有不少具備藝術性的屬性,例如陰影、漸變、動畫和形狀,這就容許咱們用具備合適樣式的 DOM 元素來替代圖片。
若是必須使用圖片,那肯定哪一種格式比較合適是很重要的。通常都在矢量圖和柵格圖之間進行選擇:
作出上面的決定後,有這樣的幾種格式供咱們選擇:JPEG、GIF、PNG-八、PNG-24 或者最新的格式,例如 WEBP 或 JPEG-XR。既然有這麼多的選擇,那如何確保咱們選擇的正確性呢?如下是找到最佳格式的基本方法:
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
和 sizes
屬性中一些預約義的規則,瀏覽器將會根據視口選擇最佳的圖片進行展現。這種技術能夠節省帶寬和減小請求,特別是對於移動端用戶。
picture
元素和 media
屬性旨在更容易地通往藝術殿堂。經過爲不一樣的條件提供不一樣的來源(經過 media-queries
測試),不管分辨率如何,咱們始終能聚焦在最重要的圖像元素上。
📚 閱讀 Jason Grigsby 的《響應式圖片 101》 能夠全面地瞭解這兩種方式。
圖片性能的最後一步就是分發了。全部資源均可以從使用 CDN 中受益,但有一些特定的工具是專門針對圖片的,例如 Cloudinary 或者 imgx。使用這些服務的好處遠不止於減小服務器流量,它還能夠顯著減小響應延遲。
CDN 能夠下降重圖片站點提供自適應和高性能圖片的複雜度。他們提供的服務各不相同(價格也不一樣),可是大多數均可以根據設備和瀏覽器進行尺寸調整、裁剪和肯定最合適的格式,甚至更多 —— 壓縮、檢測像素密度、水印、人臉識別和容許後期處理。藉助這些強大的功能和可以將參數附到 URL 中,使得提供以用戶爲中心的圖片變得垂手可得了。
📝 圖片性能清單
srcset
屬性和 picture
元素使用自定義字體的能力是一個很是強大的設計工具。但權利越大,責任就越大。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 子集容許將大字體分割成較小的集合。這是一個相對先進的策略,但它可能會明顯地減小字體體積,特別是在針對亞洲語言的時候(你知道中文字體的平均字形數是 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 是網絡字體性能的專家,他發佈的《字體加載策略綜合指南》將幫助你爲你的項目選擇正確的方法。
📝 網絡字體性能清單
目前,JavaScript 包的平均大小爲 446KB,這使得使其成爲第二大致積類型的資源(僅次於圖片)。
咱們可能沒有意識到,咱們所鍾愛的 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 性能清單
在大多數狀況下,咱們討論過的一些策略會對咱們正在打造的產品的用戶體驗產生積極的變化。性能多是一個棘手的問題,有必要長期跟蹤咱們調整的效果。
卓越的性能指標,旨在儘量接近描繪的用戶體驗。以往的 onLoad
、onContentLoaded
或者 SpeedIndex
對於用戶多久能與頁面進行交互給出的信息很是少。當僅關注資源傳輸時,咱們很難量化感知獲得的性能。幸運的是,有一些時間能夠很好地描述內容的可視性和互動性。
這些指標是白屏時間、首次有效渲染、視覺完整和可交互時間。
這些時間和用戶體驗息息相關,所以能夠做爲重點進行追蹤。若是可能,將它們所有記錄,不然選擇一兩個來更好地監控性能。其餘指標也須要關注,特別是咱們發送的字節數(優化和解壓縮)。
全部數據可能會很快變得使人困惑和難以理解。沒有可執行的目標,很容易迷失咱們最初的目的。幾年前,Tim Kadlec 寫過關於《性能預算》的概念。
遺憾的是,沒有什麼神奇的公式能夠設置它們。性能預算一般歸結爲競爭分析和產品目標,而這是每一個業務所獨有的。
設定預算時,重要的是要有明顯的差別,一般狀況下,至少要有 20% 的改善。實驗和迭代你的預算,能夠參考 Lara Hogan 的使用性能預算來接近新設計。
使用性能預算計算器或者 Browser Calories Chrome 拓展程序來幫助你建立預算。
性能監控應該是自動化的,市面上有不少提供全面報告的強大工具。
Google Lighthouse 是一個開源項目,它能夠審查性能、可訪問性、PWA 等。你能夠在命令行中或者直接在 Chrome 開發者工具中使用它。
對於持續的追蹤,能夠選擇 Calibre,它提供的性能預算、設備仿真、分佈式監控和許多其餘功能是咱們不在構建本身的性能套件上花費大量精力是完成不了的。
不管你在哪裏追蹤,請確保數據對於整個團隊或者小型組織裏的整個業務線都是透明和可訪問的。
性能是共同的責任,不只僅是開發團隊 —— 咱們都應對所建立的用戶體驗負責,無論是什麼角色或職級。
在產品決策或者設計階段,提倡速度和創建協做流程以發現可能的瓶頸是很是重要的。
關心性能不只僅是一個業務目標(但若是你須要經過銷售統計數據來進行銷售,那可使用 PWA 統計)。這關乎於基本的同理心,並把用戶的最大利益放在第一位。
做爲技術人員,咱們的責任是,不要讓用戶的注意力和時間放在等待頁面上。咱們的目標是,創建有時間觀念和以人爲本的工具。
提倡性能意識應該是每一個人的目標。讓咱們抱着性能和同理心,爲全部人創建一個更好、更有意義的將來吧。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、React、前端、後端、產品、設計 等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。