這篇文章是我閱讀 Web Performance 101 以後的進行的粗糙的翻譯做爲筆記,英語還行的童鞋能夠直接看原文。css
這篇文章主要介紹了現代 web 加載性能(注意不涉及代碼算法等),學習爲何加載性能很重要、有哪些優化的方法以及有哪些工具能夠幫助咱們對網站進行優化。html
首先,加載緩慢的網站讓人很不舒服!react
最明顯的例子就是當一個移動網站加載太慢的時候,用戶體驗如同觀看一部恐怖電影。webpack
圖片來源: Luke Wroblewskinginx
第二,網站性能直接影響你的產品質量。git
—— 2016 年,AliExpress 將他們網站的性能提高了三分之一,而後他們收到的訂單增長了 10.5%!github
——2006 年,谷歌曾經嘗試將他們的搜索放慢 0.5 秒而後發現用戶的搜索(請求)次數減小了 25%。web
——2008 年,Aberdeen 集團發現將網站放慢 1s,會致使用戶滿意度降低 16%。算法
此外還有一系列如上的數據,無論是新的仍是舊的:(wpostats.com · pwastats.com)。chrome
這就是爲何網站性能很重要。
如今,咱們須要弄懂當咱們說一個網站很快意味着什麼。
在什麼狀況下能夠說一個網站很快?
——它必須加載很快(文件下載、界面渲染),
——而後,在加載以後,它必須很快的執行(好比動畫不跳幀、滾動很絲滑)。
網站加載很快意味着:
——服務器對於客戶端請求響應很快,
——網站自身加載渲染很快。
在這篇文章中,咱們將會討論這個因素:如何讓網站快速加載以及渲染。
先從 JavaScript 開始吧。一般狀況下,JavaScript 是網站加載緩慢的根源。
第一種 JavaScript 優化方式是壓縮,若是你已經知道了的話,直接跳過吧。
什麼是壓縮?在通常狀況下,人們寫 JavaScript 代碼會使用一種方便的格式,包含縮進、富有含義的長變量名、寫註釋等等。由於這種方式,代碼具備很高的可讀性,可是多餘的空格和註釋會使得 JavaScript 文件變得很大。
爲了解決這個問題,人們想到了代碼壓縮。在壓縮的過程當中,代碼會被去掉全部沒必要要的字母,替換成短的變量名,去掉註釋等等。在最後,代碼文件變得比以前更小,可是代碼的功能並不受影響。
代碼壓縮能夠將代碼文件減少大約 30% ~ 40%。
主流的代碼打包工具都支持代碼壓縮:
—— mode: production
in webpack,
—— babel-preset-minify
in Babel,
—— gulp-uglify
in Gulp
async
和 defer
接下來,你寫了一個 JavaScript 腳本,而後進行了壓縮,如今想要在頁面中加載它。該如何作呢?
最簡單的方式就是寫一個 script 標籤,而後 src 屬性指向你所寫腳本的路徑,而後它就能夠照常開始工做啦!
可是,你知道這種方法有什麼問題嗎?
問題就在於 JavaScript 會阻塞渲染。
這是什麼意思?
當你的瀏覽器加載頁面的時候,它會轉換 HTML 文檔成爲標籤,而後構建 DOM 樹。隨後它會使用 DOM 樹渲染頁面。
問題在於,JavaScript 代碼能夠改變 DOM 樹的構建方式。
例如,JavaScript 能夠經過 document.write 寫一個 HTML 註釋的起始標籤到文檔中,而後整個 DOM 樹都會被毀掉。
這就是爲何瀏覽器在碰到 script 標籤的時候會中止渲染頁面,這樣作能夠防止 document 作多餘的工做。
從瀏覽器的角度來看:
——瀏覽器遍歷文檔,而後會解析它
——在某些時刻,瀏覽器遇到了 script 標籤,而後中止了 HTML 轉換,它開始下載並執行那些 script 代碼
——一旦代碼執行完畢,瀏覽器繼續遍歷 HTML 文檔,而後渲染頁面
實際上,這意味着當你添加一個 script 標籤到頁面中時,它後面的內容在它下載並執行完畢以前都是不可見的。若是你添加一個 script 到 head 標籤中,全部的內容都會變得不可見——直到 script 被下載執行完畢。
那咱們該怎麼辦呢?應該使用 async
和 defer
屬性。
這些屬性讓瀏覽器直到 script 腳本能夠在後臺下載,沒必要阻塞文檔渲染,下面是詳細的介紹:
——async
讓瀏覽器異步下載(在後臺)script 代碼,而後繼續解析渲染 HTML。(若是在頁面渲染完畢以前,script 代碼已經下載好了,那麼就先中止渲染,先執行 script 代碼。因爲下載所消耗的時間一般大於 HTML 轉化,因此這種狀況實際上很少見)。
——defer
會告訴瀏覽器在後臺異步下載 script 代碼,直到 HTML 轉化渲染完畢纔開始執行這些 script 代碼。
這裏有兩大不一樣點:
——async
script 標籤會在下載以後儘快地執行,它們的執行順序沒有規律。這就意味着有 async 屬性的 React bundle script 和 app bundle script 在同一時刻開始下載,因爲 app bundle 更小因此會先下載完畢,致使 app 的 bundle script 先執行。而後網站就崩掉了~
——defer
不像 async
,會在加載以及文檔渲染完畢以後按照 script 標籤的順序開始執行,所以,defer
是更適合的優化方案。
繼續。
不少時候,應用都是打包到一個 bundle 裏面,而後每次請求都發送到客戶端。可是這樣作的問題在於有些頁面咱們見到的場景不多,可是它們的代碼一樣被打包到了咱們的 bundle 中,這樣每次頁面加載的代碼多於實際須要,形成了性能浪費。
這個問題一般使用代碼切割進行解決,把大的 bundle 切割成一個個小的。
經過代碼切割,咱們把不一樣功能的代碼打包到了不一樣的文件,只在必要的時候加載必要的代碼。因爲使用這樣的作法,用戶不再會下載他們不須要用到的代碼了。
那麼咱們怎麼切割代碼呢?
首先,你須要一個代碼打包工具,好比 Webpack、Parcel 或者 Rollup。全部的這幾個工具都支持一個特殊函數 import()
。
在瀏覽器中,import()
接受傳遞給它的 JS 文件並異步下載該文件。這能夠用於加載應用程序一開始不須要可是接下來可能會用到的庫。
可是在打包工具中,import()
的功能又有所不一樣。若是你在代碼中傳遞了一個文件給 import()
而且在以後進行打包,打包工具會把這個文件以及其全部的依賴打包到一個單獨的文件中。app 運行到 import 函數時會單獨下載這個文件。
所以,在上方的例子中,webpack 會把 ChangeAvatarModal.js
及其依賴打包到單獨文件中。在代碼執行到 import 時,這個單獨文件會被下載。
這就是實際的代碼切割。
第二,在 React 和 Vuejs 中,會有基於 import()
的工具可以讓你的代碼切割工做更加輕鬆。
例如,react-loadable
是一個組件,用於等待其餘組件加載,在其餘組件加載時,它會進行佔位。React 16.6 添加了一個類似的內置功能組件,叫作 Suspense
。此外 Vuejs 也已經支持異步組件一段時間了。
若是優化得很好的話,咱們能夠減小不少沒必要要的數據的下載,代碼切割可以成爲最重要的流量優化工具。
若是你的 app 只能作一種優化的話,那就是代碼切割。
另一個重要的優化點在於包的依賴。
——例如,momentjs 這個庫,用於進行時間操做,它包含了大約 160 kb 大小的不一樣語言的文件包。
——React 甚至把 propTypes
包含在生產環境的包中,儘管這不是必要的。
——Lodash,你頗有可能引入了整個完整的包,儘管你可能只須要其中的一兩個方法。
上面這些就是把沒必要要的代碼引入打包的狀況。
爲了幫助開發者移除多餘的代碼,做者和谷歌一塊兒維護了一個 repo 收集關於如何在 webpack 中優化你的依賴,使用這些建議可讓你的 app 更快更輕巧!
→ GoogleChromeLabs/webpack-libs-optimizations
以上都是 JavaScript 的優化方式,總結起來就是:
——壓縮你的 js 代碼
——使用 async
和 defer
加載 script
——切割你的代碼,讓應用只加載必須的代碼
——移除依賴中實際未使用的代碼
接下來是如何優化 css 代碼。
首先,壓縮 CSS,就像 JavaScript 代碼同樣。刪除沒必要要的空格和字母來使你的代碼更小。
這些工具能夠幫助你壓縮 CSS 代碼:
—— webpack’s postcss-loader
with cssnano
—— PostCSS’s cssnano
—— Gulp’s gulp-clean-css
第2、styles 阻塞渲染,就像以前 script 那樣。
由於沒有樣式的網站看起來很奇怪。
若是瀏覽器在樣式加載以前渲染頁面,那麼用戶就會看到上面那樣的狀況。
而後頁面就會閃爍,而後就會看到上面截圖這樣子,很難說是一種好的用戶體驗。
這就是爲何樣式加載的時候頁面會是空白的。
如今有一種比較機智的優化方式。瀏覽器在加載樣式以前保持空白頁是頗有理由的,咱們沒必要從這一點下手。可是咱們仍然能夠想辦法讓頁面渲染更快——讓頁面只加載渲染初始界面所必要的樣式,剩餘的樣式在以後加載,這些渲染初始界面所必要的樣式稱爲「Critical CSS」。
讓咱們看看是怎麼作的。
一、把頁面樣式分爲 critical 的和 non-critical 的。
二、把 critical CSS 嵌入到 HTML,真可以讓它們儘快地被加載。
如今,當你加載頁面的時候,頁面可以很快地被渲染,可是你仍然得加載那些不重要的 CSS。
有多種方式能夠加載剩餘的 CSS,下面的方式是我所傾向的:
三、使用<link rel="preload">
獲取非必要的 CSS。
四、一旦文件被加載到緩存之後,把 rel
屬性從 preload
切換爲 stylesheet
。這可讓瀏覽器從緩存中獲取 CSS 並應用到頁面中。
那咱們怎麼知道哪些 CSS 是必須的,哪些 CSS 是沒必要須的呢?一般狀況下,規則以下:
移除 CSS 樣式知道頁面看起來變得滑稽,那麼剩下的 CSS 就是必要的。
複製代碼
例如,頁面的佈局樣式或者文章的文本樣式是必須的,由於缺乏它們會使得頁面看起來很爛。而 JavaScript 彈出窗或者頁腳的樣式是非必須的,由於用戶不會在一開始就看到它們,缺乏那些樣式,頁面看起來仍然十分完美。
聽起來可能比較複雜,可是有不少自動化工具能夠幫助咱們完成這項工做。
—— styled-components
. It’s a CSS-in-JS library that extracts and returns critical styles during server-side rendering. It works only if you already write styles using styled-components
, but if you do, it works really well.
——critical
. It’s a utility that takes an HTML page, renders it in a headless browser and extracts styles for above-the-fold content. Because critical
runs only over a single page, it might not work well for complex single-page apps.
—— penthouse
. It’s similar to critical
but works with URLs instead of HTML pages.
這種作法通常能夠節約 200 ~ 500 ms 左右的首屏渲染時間。
瞭解更多 Critical CSS 的知識,閱讀 the amazing Smashing Magazine’s guide.
這就是 CSS 優化的主要策略,總結起來就是:
——壓縮 CSS 代碼
——提取必要的 CSS,讓頁面首先加載它們
如今讓咱們看看 HTTP 的優化。
讓 HTTP 傳輸較少數據的方式仍然是壓縮代碼,本節主要說壓縮 HTML 代碼,JS、CSS 的代碼壓縮在以前已經講過了。
壓縮代碼的第二種方式是 GZIP 壓縮。
Gzip 是一種算法,它可使用複雜的歸檔算法壓縮你發送到客戶端的數據。在壓縮以後,你的文件看起來像是沒法打開的二進制文件,可是它們的體積會減少 60% 到 80%。瀏覽器接受這些文件以後會自動進行解壓縮。
基本上,使用 Gzip 已是生產環境的標準,所以若是你使用一些流行的服務器軟件好比 Apache 或者 Nginx,你就能夠修改配置文件開啓 Gzip 壓縮。
Apache instructions · Nginx instructions
注意:
使用這些說明啓用 Gzip 將會致使服務器動態壓縮資源,這會增長服務器響應時間。在大多數狀況下你不須要關心這一點,但若是你但願提升響應時間,能夠在構建的時候進行資源預壓縮。
注意:
不要對文本文件以外的文件進行 Gzip 壓縮!
圖像、字體、視頻或者其餘二進制文件一般已經被壓縮過了,所以對它們進行 Gzip 壓縮只會延長響應時間。SVG 圖片是惟一的例外,由於它也是文本。
Gzip 有一個替代品,一種叫 Brotli 的算法。
__Brotli 的優勢:__一樣的 CPU 載荷下,它壓縮效率比 Gzip 高 20% 到 30%。就是說能夠減小 30% 下載量!
__Brotli 的缺點:__它很年輕,瀏覽器以及服務器的支持度還不夠,因此你不能用它來替代 Gzip。可是能夠針對不一樣的瀏覽器使用 Gzip 或者 Brotli。
Apache 從 2.4.26 開始支持 Brotli,Nginx 有外部模塊支持 Brotli。
Apache instructions · Nginx module
注意:
不要把 Brotli 的壓縮等級設置到最大,那樣會讓它壓縮得比 Gzip 慢。設置爲 4 是最好的,可讓 Brotli 壓縮得比 Gzip 更小更快。
如今,咱們聊聊 CDN。
什麼是 CDN?假設你在美國假設了一個應用。若是你的用戶來自華沙,他們的請求不得不從波蘭發出,一路顛簸來到美國,而後又得回到波蘭。這個請求過程將會消耗不少時間:
——網絡請求要跨越很長的一段距離
——網絡請求要通過不少路由或者相似設備(每一個設備都有一段處理時間)
若是用戶想要獲取 app 數據,並且只有美國的服務器知道如何處理數據,那上面這些過程好像都是必要的。但對於靜態內容而言,上面的請求過程徹底沒有必要,由於它們請求的只是一些靜態內容,徹底能夠部署到任何服務器上。
CDN 服務就是用來解決這個問題的。CDN 表明「Content Delivery Network(靜態內容分發)」,CDN 服務在全世界提供許多服務器來 「serve」 靜態文件。若是要使用的話,只須要在一個 CDN 服務註冊,而後上傳你的靜態文件,而後更新 app 中引用的文件的地址,而後每一個用戶都會引用離他們最近的服務器上的靜態文件了。
根據咱們的經驗,CDN 基本上能把每一個請求的延遲從上百毫秒減小到 5-10 毫秒。考慮到當頁面打開時有不少資源要加載,CDN 的優化效果是很驚人的。
你知道嗎?谷歌在你開始點擊搜索以前已經在加載搜索結果的第一項了。這是由於三分之一的用戶會首先點擊第一個搜索結果,預加載內容可讓用戶更快的看到目標頁面。
若是你肯定你的頁面或者資源會在不久以後被用到,瀏覽器容許你進行預加載。
有五種方法能夠實現預加載,它們每一種的適用場景都不一樣:
——<link rel="dns-prefetch">
提示瀏覽器對一個 IP 地址提早進行 DNS 請求。這對於 CDN 請求頗有用,此外一些你知道域名可是不知道具體地址的資源的預加載也可使用。
——<link rel="preconnect">
提示瀏覽器提早鏈接到某臺服務器。在 dns-prefetch
適用的場景一樣適用,但它能夠創建完整的鏈接並節約不少時間。缺點是打開新的鏈接很消耗資源,所以不要過分使用。
——<link rel="prefetch">
會在後臺對資源進行低優先級預加載而後緩存,這個比較有用,好比在進入 SPA 的下一個頁面以前加載 bundle。
——<link rel="preload">
會在後臺對資源進行高優先級的預加載。這對於加載短期內即將用到的資源而言比較有用。
——<link rel="prerender">
會在後臺預加載特定頁面,而後在不可見的 tab 中渲染頁面。當用戶進入這個頁面時,頁面能夠立馬呈如今用戶面前。這是谷歌用於預加載第一條搜索結果的方案。
注意:
不要過分使用預加載,雖然預加載可以提高用戶體驗、加速應用,可是會致使沒必要要的流量消耗;尤爲是在移動端,用戶會消耗過多的不要的流量,這一樣會下降用戶體驗。
閱讀更多:Preload, prefetch and priorities in Chrome · Prefetching, preloading, prebrowsing
HTTP 優化方式:
—— 使用 CDN 節省靜態資源的下載時間
—— 預加載一會將要用到的資源
繼續,說說圖片優化。
圖片消耗了大量的流量,但慶幸的是圖片加載不阻塞渲染。但圖片優化仍然是必要的,咱們須要讓圖片加載更快、消耗更少的流量。
第一,也是最重要的一點,選擇合適的圖片格式。
最多見的圖片格式是:svg
、jpg
、png
、webp
和 gif
。
svg
最適合矢量圖,好比 icon 和 logo。
jpg
最適合照片,由於它壓縮圖片時質量損耗最小,以致於肉眼難以發現。
png
適合沒有任何質量損失的光柵圖形 - 例如光柵圖標或像素藝術。
webp
最適合照片或者光柵圖片,由於它支持有損或者無損壓縮。它的壓縮比也比 jpg
和 png
更優秀。
不幸的是 webp
只能在 chrome 使用,可是你仍然可使用 jpg
和 png
來實現一個 fallback。
上面就是具體實現。
這樣寫的話,支持 webp
的瀏覽器會加載 webp
格式的圖片,不支持 webp
格式的瀏覽器會加載 jpg
最爲備用方案。
最後是 gif
。
不要使用 gif
,它很是笨重。超過 1M 的 gif 最好使用視頻文件代替,能夠更好的壓縮內容。
See also: Replace Animated GIFs with Video at WebFundamentals
除了使用合適的圖片格式之外,圖片壓縮也能夠是優化方案。下面是幾種圖片壓縮方式:
首先是 svg
:
——壓縮。由於 svg 圖片是文本,因此能夠移除空格和註釋
——簡化 path,若是 svg 是自動工具生成的,其內部的 path 可能會很複雜,這種狀況下,移除那些不影響 svg 樣式的 path
——簡化 svg 文件結構,若是 svg 是自動工具生成的,一般會包含不少多餘的 meta 元素,移除它們能夠減少文件體積
這些優化方式均可以直接使用 svgo
實現,它還有 UI 界面:a great UI for svgo
第二個:jpg
。
——減少圖片維度。根據個人經驗,這是一個開發人員使用 jpg 常犯的錯誤
這種狀況常發生於咱們把一張大尺寸的圖片塞進一個小尺寸的容器中時。好比咱們把一張 2560 * 1440 px 的圖片放到一個 533 * 300 px 的容器中。
當這種狀況發生時,瀏覽器會加載過大的文件,而後還要花時間縮小圖片,知道可以塞進去那個小小的容器,這些都是無用功。
要解決這個問題,能夠直接在你的 PS 或者其餘工具中對圖片進行編輯;或者你也可使用 webpack loader(好比 responsive-loader
)。若是要使用大尺寸圖片適配高分屏,能夠經過 <picture>
或者 <img srcset>
代替。
還能夠對 jpg 進行圖片降維壓縮,圖片質量壓縮到原來的 70 ~ 80,圖片壓縮致使的質量損失會很難發現。
上面能夠看出壓縮後圖片質量損失不大。
可是咱們能夠看到圖片的大小減少了不少。這就是爲何推薦對 jpg 圖片進行 70-80 水平的壓縮,由於圖片信息損失很小,可是體積壓縮很大。
除了以上方式外,咱們還可使用漸進式圖片。
上方是非漸進式圖片加載的方法。
這是一張漸進式的圖片的加載方式。
能夠經過 PS 或者 Gimp 製做漸進式圖片。也可使用 webpack-loader(好比 image-webpack-loader
)或者其餘工具。
注意:
漸進式圖片可能比常規圖片更大,並且解碼更慢。
第三,png
。
——使用隔行掃描 PNG。 隔行掃描 PNG 的工做方式與漸進式 JPEG 相同:它從低質量開始渲染,但在加載時進行改進。 但它不是適合全部場景。例如,逐步加載 PNG 圖標看起來很奇怪 - 但它可能適用於其餘某些圖像。
——使用索引顏色。 經過使用索引顏色,PNG 圖片將其全部顏色放入調色板中並使用它來引用每種顏色。 這使得每一個像素所需的字節數更小,而且可能有助於下降總體圖像權重。 因爲調色板大小有限(最多256種顏色),所以此解決方案不適用於具備大量顏色的圖像。
這兩種方式均可以經過圖片編輯器或者 image-webpack-loader
或者其餘工具實現。
以上的全部優化均可以使用自動化工具完成,以前都已經提到過,可是這裏再總結一下:
— webpack has image-webpack-loader
which runs on every build and does pretty much every optimization from above. Its default settings are OK
— For you need to optimize an image once and forever, there’re apps like ImageOptim and sites like TinyPNG.
— If you can’t plug a webpack loader into your build process, there’re also a number of CDNs and services that host and optimize images for you (e.g., Akamai, Cloudinary, or imgix).
圖片優化總結:
——經過圖片降維、質量壓縮或者使用漸進式圖片優化圖片加載時間
最後一個優化方式就是字體了。
有時候頁面加載好了,全部的樣式、佈局都已經可見了,可是字體尚未出現或者顯示異常,這就是字體問題所致使的,自定義字體還沒有下載完畢,這個時候瀏覽器會等待幾秒,若是仍然未下載,瀏覽器纔會使用備用字體做爲替代。
這種行爲在某種程度上避免了字體的閃爍,可是在緩慢的網絡條件下,這種行爲使得頁面加載變得緩慢。
咱們須要瞭解一下如何優化這種狀況。
首先,要記得設置 fallback 字體。
fallback 字體會在自定義字體沒法下載或者下載時間過長時被使用。它在 CSS 的 font
或者 font-family
的第一個指定字體後面指定,好比上方的Arial, sans-serif
。
fallback 字體應當是比較流行的內置字體(好比 Georgia);也能夠是比較通用的字體系列(如 serif 或者 sans-serif);一般狀況下,即便你指定了內置的字體做爲 fallback,可是你仍然須要添加一個通用的字體系列——由於內置字體可能也會在某些設備上缺失。
沒有 fallback 字體的話,一旦自定義字體缺失,瀏覽器會使用默認的 serif font 進行渲染。這樣可能會致使頁面比較難看。
使用 fallback 字體,至少你有機會定義一個和你的自定義字體相近的字體做爲備用方案。
font-display
第二點優化,使用 CSS 的 font-display
屬性指定自定義字體。
font-display
屬性會調整自定義字體的應用方式。默認狀況下,它會設置爲 auto
,在大部分主流瀏覽器中,意味着瀏覽器會等待自定義字體加載 3s。這意味着若是網絡太慢的話,用戶須要等待 3s 後字體纔會顯示。
這很很差,爲了優化這一點,指定 font-display
。
Note: in Microsoft Edge, the font-display: auto
behavior is different. With it, if the custom font is not cached, Edge immediately renders the text in the fallback font and substitutes the custom font later when it’s loaded. This is not a bug because font-display: auto
lets browsers define the loading strategy.
有兩個 font-display
的值我認爲比較適用於大部分狀況。
第一個是 font-display: fallback
。這樣指定的話,瀏覽器會使用最先可以得到的字體當即渲染,無論是已經緩存的自定義字體仍是 fallback 字體。若是自定義字體沒有被緩存的話,瀏覽器會下載它。若是下載得足夠快(一般是 3s 內),瀏覽器會使用自定義字體替換 fallback 字體。
這種狀況下,用戶可能會在讀 fallback 字體的文本時,瀏覽器忽然進行字體替換,這對於用戶體驗而言並非不好,總比不顯示任何字體要強。
第二個適用的 font-display
值是 optional
。使用這個值,瀏覽器一樣會當即使用可得到的字體進行文本渲染:無論是已緩存的自定義字體仍是 fallback 字體。可是當自定義字體未緩存時,在下載好自定義字體後,瀏覽器不會當即替換已有的 fallback 字體,直到頁面下一次刷新。
這種行爲意味着用戶始終只會看到一種字體,不會出現字體替換的狀況。
那咱們該如何選擇這兩個值呢?
我相信這是一個品味問題。 我我的更喜歡用自定義字體展現文本,所以我選擇 font-display:fallback
值。 若是你以爲訪問者第一次訪問時看到 fallback 字體的頁面沒有什麼關係,那麼 font-display:optional
對您來講很是有用。
Note: this font-display
trick is not applicable to icon fonts. In icon fonts, each icon is usually encoded by a rarely used Unicode character. Using font-display
to render icons with a fallback font will make random characters appear in their place.
字體優化方案的總結:
—— 指定合適的 fallback(備用)字體 (還有通用的字體系列)
—— 使用 font-display
來配置自定義字體的應用方式。
最後是一些有助於頁面性能優化的工具。
第一個是 Google PageSpeed Insights。
第二個是 Lighthouse。
第三個是 WebPageTest。
最後一個是 webpack 插件:webpack-bundle-analyzer。
具體的介紹就沒寫了,點進去直接用就知道啦。
感謝閱讀!
原做者推特:@iamakulov。
Thanks to Arun, Anton Korzunov, Matthew Holloway, Bradley Few, Brian Rosamilia,Rafael Keramidas, Viktor Karpov, and Artem Miroshnyk (in no particular order) for providing feedback on drafts.
譯者水平有限,不免存在紕漏,敬請各位斧正。