[譯]Web 效能優化: 圖片優化讓網站大小減少 62%

這是 Web 效能優化的第二篇,上一篇在下面看點選檢視:
影象是web上提供的最基本的內容型別之一。他們說一張圖片勝過千言萬語。但是如果你不小心的話,圖片大小有時高達幾十兆。
因此,雖然網路影象需要清晰明快,但它們尺寸可以縮小壓縮的,使用載入時間保持在可接受的水平。
在我的網站上,我注意到我的主頁的頁面大小 超過了 1.1MB ,圖片佔了約88%,我還注意到我提供的影象比它們需要的大(在解析度方面),顯然,還有很多改進的空間。

我開始閱讀 Addy Osmani 的優秀 Essential Image Optimization 電子書,並開始在我的網站上按照他們的建議做了一些圖片的優化。,然後再對響應式影象進行了一些研究並應用了它。
這使得頁面大小減少到 445kb ,約 62%
!

什麼是影象壓縮?
壓縮影象就是在圖片保持在可接受的清晰度範圍內同時減少檔案大小,我使用 imagemin 來壓縮站點上的影象。
要使用 imagemin
,確保你已經安裝了 Node.js,然後開啟一個終端視窗, cd
進入專案,並執行以下命令:
npm install imagemin 複製程式碼
然後建立一個名為 imagemin.js
的新檔案,寫入下面的內容:
const imagemin = require('imagemin'); const PNGImages = 'assets/images/*.png'; const JPEGImages = 'assets/images/*.jpg'; const output = 'build/images'; 複製程式碼
你可以根據自己的需要更改 PNGImages
、 JPEGImages
和 output
的值,以符合你的專案結構。
此外要執行圖片壓縮,還需要根據要壓縮的影象型別安裝對應的外掛。
JPEG/JPG
JPG 的優點
JPG 最大的特點是 有失真壓縮 。這種高效的壓縮演算法使它成為了一種非常輕巧的圖片格式。另一方面,即使被稱為“有損”壓縮,JPG的壓縮方式仍然是一種高質量的壓縮方式:當我們把圖片體積壓縮至原有體積的 50% 以下時,JPG 仍然可以保持住 60% 的品質。此外,JPG 格式以 24 位儲存單個圖,可以呈現多達 1600 萬種顏色,足以應對大多數場景下對色彩的要求,這一點決定了它壓縮前後的質量損耗並不容易被我們人類的肉眼所察覺——前提是你用對了業務場景。
JPG 使用場景
JPG 適用於呈現色彩豐富的圖片,在我們日常開發中,JPG 圖片經常作為大的背景圖、輪播圖或 Banner 圖出現。
JPG 的缺陷
有失真壓縮在上文所展示的輪播圖上確實很難露出馬腳,但當它處理向量圖形和 Logo 等線條感較強、顏色對比強烈的影象時,人為壓縮導致的圖片模糊會相當明顯。
此外,JPEG 影象不支援透明度處理,透明圖片需要召喚 PNG 來呈現。
使用 MozJPEG 壓縮 jpeg
這裡使用 Mozilla 的 MozJPEG 工具,該工具可以通過imagemin-mozjpeg 作為 Imagemin 外掛使用。你可以通過執行以下命令來安裝它:
npm install imagemin-mozjpeg 複製程式碼
然後將以下內容新增到的 imagemin.js
中:
const imageminMozjpeg = require('imagemin-mozjpeg'); const optimiseJPEGImages = () => imagemin([JPEGImages], output, { plugins: [ imageminMozjpeg({ quality: 70, }), ] }); optimiseJPEGImages() .catch(error => console.log(error)); 複製程式碼
可以通過在終端中執行 node imagemin.js
來執行指令碼。這將處理所有JPEG影象,並將優化後的版本放 build/images
資料夾中。
我發現將 quality
設定為 70 在大多數情況下可以產生足夠清晰的影象,但你的專案需求可能不同,可以自行設定合適的值。
預設情況下,MozJPEG生成漸進式 jpeg,這會導致影象從低解析度逐漸載入到高解析度,直到圖片完全載入為止。由於它們的編碼方式,它們也比原始的 jpeg 略小。
你可以使用 Sindre Sorhus 提供的這個命令列工具來檢查JPEG影象是否是漸進式的。
Addy Osmani 已經很好地總結了使用漸進式 jpeg 的優缺點。對我來說,我覺得利大於弊,所以我堅持使用預設設定。
如果你更喜歡使用原始的jpeg,可以在 options
物件中將 progressive
設定為 fa l
se。另外,請確保imagemin-mozjpeg 版本的變化,請重新檢視對應文件。
PNG (PNG-8 與 PNG-24)
PNG 的優缺點
PNG(可移植網路圖形格式)是一種無失真壓縮的高保真的圖片格式。8 和 24,這裡都是二進位制數的位數。按照我們前置知識裡提到的對應關係,8 位的 PNG 最多支援 256 種顏色,而 24 位的可以呈現約 1600 萬種顏色。
PNG 圖片具有比 JPG 更強的色彩表現力,對線條的處理更加細膩,對透明度有良好的支援。它彌補了上文我們提到的 JPG 的侷限性,唯一的缺點就是 體積太大 。
PNG 應用場景
前面我們提到,複雜的、色彩層次豐富的圖片,用 PNG 來處理的話,成本會比較高,我們一般會交給 JPG 去儲存。
考慮到 PNG 在處理線條和顏色對比度方面的優勢,我們主要用它來呈現小的 Logo、顏色簡單且對比強烈的圖片或背景等。
使用 pngquant 優化 PNG 影象
pngquant 是我優化PNG影象的首選工具,你可以通過imagemin-pngquant 使用它:
npm install imagemin-pngquant 複製程式碼
然後將以下內容新增到 imagemin.js
檔案中:
const imageminPngquant = require('imagemin-pngquant'); const optimisePNGImages = () => imagemin([PNGImages], output, { plugins: [ imageminPngquant({ quality: '65-80' }) ], }); optimiseJPEGImages() .then(() => optimisePNGImages()) .catch(error => console.log(error)); 複製程式碼
我發現將 quality
設定為 65-80
可以在檔案大小和影象質量之間較好的折衷方案。
有了這些設定,我可以得到一個螢幕截圖,我的網站從 913kb 到 187kb,沒有任何明顯的視覺損失, 驚人的79% 的降幅!
這是兩個檔案。看一看,自己判斷一下:
WebP
WebP 的優點
WebP 像 JPEG 一樣對細節豐富的圖片信手拈來,像 PNG 一樣支援透明,像 GIF 一樣可以顯示動態圖片——它集多種圖片檔案格式的優點於一身。 WebP 的官方介紹對這一點有著更權威的闡述:
與 PNG 相比,WebP 無損影象的尺寸縮小了 26%。在等效的 SSIM 質量指數下,WebP 有損影象比同類 JPEG 影象小25-34%。 無損 WebP 支援透明度(也稱為 alpha 通道),僅需 22% 的額外位元組。對於有損 RGB 壓縮可接受的情況,有損 WebP 也支援透明度,與 PNG 相比,通常提供 3 倍的檔案大小。
將 WebP 影象提供給支援它們的瀏覽器
WebP 是谷歌引入的一種相對較新的格式,它的目標是通過以無損和有損格式編碼影象來提供更小的檔案大小,使其成為 JPEG 和 PNG 的一個很好的替代方案。
WebP 影象的清晰度通常可以與 JPEG 和 PNG相提並論,而且檔案大小要小得多。例如,當我將螢幕截圖從上面轉換到 WebP 時,我得到了一個 88kb 的檔案,其質量與 913kb 的原始影象相當, 減少了90% !
看看這三張圖片,你能說出區別嗎?
就我個人而言,我認為視覺效果是可以比較的,而且節省下來的大小是不容忽視的。
既然我們已經認識到在可能的情況下使用WebP格式是有價值的,那麼很重要的一點是—它不能完全替代 JPEG 和 PNG,因為瀏覽器對 WebP 支援並不普遍。
在撰寫本文時,Firefox、Safari 和 Edge 都是不支援WebP的瀏覽器。

然而,根據caniuse.com 的資料,全球超過70%的使用者使用支援WebP的瀏覽器。這意味著,通過使用 WebP 影象,可以為大約 70% 的客戶提供更快的 web 頁面及更好的體驗。
安裝它,執行以下命令:
npm install imagemin-webp 複製程式碼
然後將以下內容新增到你的 imagemin.js
檔案中:
const imageminWebp = require('imagemin-webp'); const convertPNGToWebp = () => imagemin([PNGImages], output, { use: [ imageminWebp({ quality: 85, }), ] }); const convertJPGToWebp = () => imagemin([JPGImages], output, { use: [ imageminWebp({ quality: 75, }), ] }); optimiseJPEGImages() .then(() => optimisePNGImages()) .then(() => convertPNGToWebp()) .then(() => convertJPGToWebp()) .catch(error => console.log(error)); 複製程式碼
我發現,將 quality
設定為 85
會生成質量與 PNG 相當但小得多的 WebP 影象。對於 jpeg,我發現將 quality
設定為 75
可以在視覺和檔案大小之間取得很好的平衡。
提供 HTML格式的WebP影象
一旦有了 WebP 影象,可以使用以下標記將它們提供給可以使用它們的瀏覽器,同時向不相容 WebP 的瀏覽器使用 png 或者 jpeg。
<picture> <source srcset="sample_image.webp" type="image/webp"> <source srcset="sample_image.jpg" type="image/jpg"> <img src="sample_image.jpg" alt=""> </picture> 複製程式碼
使用此標記,理解 image/webp
媒體型別的瀏覽器將下載 Webp 圖片並顯示它,而其他瀏覽器將下載 JPEG 圖片。
任何不支援 <picture>
的瀏覽器都將跳過所有 source
標籤,並載入底部 img
標籤。因此,我們通過提供對所有瀏覽器類的支援,逐步增強了我們的頁面。

請注意,在所有情況下,img 標記都是實際呈現給頁面的內容,因此它確實是語法的必需部分。 如果省略 img 標記,則不會渲染任何影象。
標籤和其中定義的所有 source
都在那裡,以便瀏覽器可以選擇要使用的圖片的路徑。 選擇源影象後,其 URL 將傳給 img 標記,這就是顯示的內容。
這意味著你無需設定 <picture>
或 source
標記的樣式,因為瀏覽器不會渲染這些標記。 因此,你可以像以前一樣繼續使用 img
標籤進行樣式設定。