原文:The State of the Web: A guide to impactful performance improvementsjavascript
互聯網發展很是迅速,因此咱們創造了Web平臺。一般咱們會忽視連通性等問題,但用戶們卻不會視而不見。一瞥萬維網的現狀,能夠發現咱們並無用同情心、變通意識去構建它,更不要說性能了。php
因此,今天的Web是什麼狀態呢?css
在這個星球上的74億人中,只有46%能夠上網。平均網絡速度上限爲7Mb/s。更重要的是,有93%的互聯網用戶正在經過移動設備進行訪問——若不適配移動設備將引發用戶反感。一般狀況下,數據比咱們假設的更昂貴——可能須要1到13小時才能購買500MB的數據包(德國 vs. 巴西;更有趣的統計數據參見 Ben Schwarz 的 Beyond the Bubble: The Real World Performance)。html
咱們的網站也不是完美的——平均網站是原始Doom遊戲的大小(約3 MB)(請注意,爲了統計準確,應使用中位數,閱讀 Ilya Grigorik 的優秀「平均頁面」是一個神話,中檔網站大小目前爲1.4MB)。圖像能夠輕鬆佔用1.7 MB的帶寬,而JavaScript平均值也有400KB的體積。這不只是Web平臺的問題,原生應用程序可能更糟,還記得爲了獲取錯誤修復版本,而下載200MB安裝包的情景嗎?前端
技術人員常常會發現本身處於特權狀態。隨着最新的高端筆記本電腦、手機和快速有線互聯網鏈接,很容易讓咱們忘記,這些並非每一個人都有的條件(實際上,真的不多)。java
若是咱們從特權和缺少同情的角度來構建網絡平臺,那麼將致使排他性的糟糕體驗。react
考慮到設計和開發的性能,咱們怎樣才能作得更好?webpack
理解瀏覽器如何分析和處理資源,是顯著提升性能的最強大但未充分利用的方式之一。事實證實,瀏覽器在嗅探資源方面很是出色,同時解析並肯定其優先級。這裏是關鍵請求的來源。git
若是請求中包含用戶視口中呈現內容所必需的資源,則該請求相當重要。github
對於大多數網站,它將是HTML、必要的CSS、logo、網絡字體,也多是圖片。在許多狀況下,幾十個其餘不相關的資源(JavaScript、跟蹤代碼、廣告等)影響了關鍵請求。幸運的是,咱們可以經過仔細挑選重要資源並調整優先級來控制這種行爲。
經過<link rel ='preload'>
咱們能夠手動強制調高資源的優先級,確保所需的內容按時呈現。這種技術能夠顯著改善「交互時間」指標,從而使最佳的用戶體驗成爲可能。
關鍵請求對許多人來講,彷佛仍然是一個黑匣子,可共享資料的缺少並不能改變現狀。幸運的是,Ben Schwarz
發表了關於這個問題的很是全面並平易近人的文章——關鍵請求。另外,請參閱Addy的文章,在Chrome中的預加載、預取和優先級(Preload, Prefetch and Priorities in Chrome)。
[在Chrome開發人員工具中啓用優先級]
要跟蹤在請求優先級處理方面的狀況,請使用Lighthouse性能工具和關鍵請求鏈審覈工具,或查看Chrome開發人員工具中「網絡」選項卡下的請求優先級。
圖片一般佔網頁傳輸的大部分有效載荷,所以圖片優化能夠帶來最大的性能提高。有許多現有的策略和工具能夠幫助咱們刪除額外的字節,可是首先應考慮的問題是:「圖片對於我想傳達的信息和效果相當重要嗎?」。若是能夠消除它,不只能夠節省帶寬,並且還節省了請求。
在某些狀況下,能夠經過不一樣的技術實現相似的結果。好比CSS就具備藝術方向的一系列屬性,例如陰影、漸變、動畫及形狀,容許咱們構造適當風格的DOM元素。
若是不能捨棄圖片,肯定哪一種格式更合適就很重要了。首先要在矢量和光柵圖形之間作出選擇:
作出首個決定後,能夠選擇如下幾種格式:JPEG、GIF、PNG–八、PNG–24,或最新的 WEBP 與 JPEG-XR 格式。有了這麼多的選項,如何確保咱們作出正確的選擇?如下是找出最佳格式的基本方法:
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
和size
屬性中的一組預約義規則,瀏覽器將選擇最佳圖片,相應地提供給視口。這項技術能夠帶來很大的帶寬和請求節省,特別是對於移動用戶。
[srcset 使用示例]
picture
元素和media
屬性旨在使藝術設計變得容易。經過爲不一樣情形提供不一樣圖片(經過媒體查詢進行測試),不管什麼分辨率,咱們都能始終將圖像中最重要的元素保持在焦點。
[picture 元素使用示例]
請務必閱讀 Jason Grigsby 的 Responsive Images 101指南,以便對這兩種方法進行完全的闡述。
視覺優化的最後一步是分發。全部資源均可以從使用 內容分發網絡 中受益,但還有一些針對圖片優化的特定工具,例如 Cloudinary 和 imgx。使用這些服務的好處遠遠超過了減小服務器上的流量,並顯着下降了響應延遲。
CDN能夠很好的解決重圖片網站的複雜度,包括響應式服務與圖片優化。雖然產品不一樣(價格也是如此),可是大多數方案都是根據設備和瀏覽器,調整大小、裁剪來肯定哪一種格式最適合用戶。甚至更多——它們能夠壓縮、檢測像素密度、水印、識別面部,並容許後置處理能力。藉助這些強大的功能,和將參數附加到URL的能力,以用戶爲中心的圖片服務變得十分容易。
srcset
和picture
自定義字體是一項很是強大的設計工具。可是能力伴隨着不少責任。現有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範圍子集容許將大字體分割成較小的集合。這是一個相對先進的策略,特別是在處理亞洲語言的時候,可能會帶來顯着的節省(你知道中文字體有平均數爲 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 發佈了字體加載策略綜合指南,這將有助於爲您的項目選擇正確的方法。
目前,JavaScript 的平均大小爲446 KB,已經使其成爲第二大的資源類型(第一爲圖片)。
咱們可能沒有意識到,咱們所愛的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
擴展,咱們可使導入依賴成本更加明顯。
只要有可能,咱們就應只提供用戶體驗所必需的資源。向用戶發送一個完整的
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。
咱們已經討論了一些策略,在大多數狀況下會對咱們正在創建的產品用戶體驗產生積極的變化。性能多是一個棘手的問題,有必要長期地跟蹤咱們調整的結果。
卓越的性能指標,旨在儘量接近描繪用戶體驗。以往的onLoad
,onContentLoaded
或SpeedIndex
對「用戶多快能與頁面交互」給出的信息很是少。當聚焦到傳輸資源時,量化地感知性能十分困難。好在,有一些時間能夠全面地描述內容的可視性和互動性。
這些指標是首次渲染(First Paint),首次有意義渲染(First Meaningful Paint),視覺完整(Visually Complete)和可交互時間(Time to Interactive)。
這些時間直接對應於用戶的實際體驗,所以能夠做爲重點進行追蹤。若是可能,將它們記錄所有,不然選擇一兩個來更好地監控性能。其餘指標也須要留意,特別是咱們發送的字節數(優化和解壓縮)。
全部這些上報數字可能會很快變得混亂和不易理解。沒有可操做的目標和對象,很容易迷失咱們最初的目的。幾年前,Tim Kadlec 寫過關於性能預算的概念。
遺憾的是,並無一個萬能的神奇公式。性能預算一般歸結爲競爭分析和產品目標,而這是每一個業務所各異的。
設定預算時,重要的是要達到明顯的差別,一般是至少改善20%。實踐和迭代您的預算,利用 Lara Hogan 的方法新設計與性能預算做爲參考。
試用性能預算計算器或Chrome擴展瀏覽器卡路里,以幫助建立預算。
監控性能不該該是手動的。市面上有不少強大的工具,還能夠提供全面的報告。
Google Lighthouse 是一個能夠審覈性能、可訪問性、漸進式網絡應用程序等的開源項目。您能夠在命令行中或直接在 Chrome Developer Tools 中使用Lighthouse。
[Lighthouse 運行一次性能審查]
對於持續的追蹤,選擇選擇 Calibre,它能夠提供性能預算、設備仿真、分佈式監控和許多其餘功能,無需咱們仔細構建本身的性能套件便可得到。
[Calibre 報表]
不管您在追蹤什麼,請確保使整個團隊或組織可以透明地訪問數據。
性能是一項分擔責任,遠遠超過開發人員團隊——咱們都應對所建立的用戶體驗負責,無論是什麼角色或職級。
倡導速度和創建協做流程,以便在產品決策或設計早期階段,儘早暴露可能遇到的瓶頸,是很是重要的。
關心性能不只僅是一個業務目標(可是若是您須要經過銷售統計數據來進行銷售,那麼能夠經過PWA統計)。這是關於基本的同情和用戶體驗放在第一位。
做爲技術專家,咱們的責任是,不要讓用戶的注意力和時間放在等待頁面上,而已能夠更開心地花費在其餘地方。咱們的目標是創建意識到時間和人們關注的工具。
提倡性能意識應該是每一個人的目標。讓咱們抱着性能和同情心,爲你們創建一個更好、更有意義的將來吧。