Can I Use 做查詢。
懶人連結附上:WebP, JPEG 2000
不難發現,WebP 及 JPEG 2000 剛好是支援度互補的關係,同時提供這兩個選項,就能支援絕大多數的瀏覽器。
好,那麼依照上面的參考資料,我們可以來實際優化我們的網站了。
那這次我們就先把目標定爲:不需要考慮到使用者下載圖片的需求,只是傳統的文章及插圖。
這樣的情況下,該怎麼做呢?讓我們繼續看下去。
下面我簡單整理了幾個優化圖片的要點,供大家參考。
首先我們已經知道我們需要使用次世代的格式(WebP, JPEG 2000)作爲主要的圖片格式,那麼我們就需要將現有的圖片轉檔為我們需要的格式。
但爲了避免某些瀏覽器的支援度問題,我們還需要一個普遍被支援的備用格式,這邊我選擇 JPEG,原因就不贅述了,可以參考上面的內容來挑選你覺得適合的備用格式。
總之,我們需要的圖片格式有如下三種:
你可以使用自己慣用的轉檔工具或網路上的資源,但這邊我建議你可以試試看一個 CLI 轉檔程式: ImageMagick。
ImageMagick 可以支援不同的作業系統,也提供了相當多種的圖片格式及轉檔的選項,是一個強大的轉檔工具。
其最簡易的轉檔指令如下,安裝完 ImageMagick 之後,在終端機當中輸入:
# 將 JPEG 轉換爲 JPEG 2000
magick image.jpg image.jp2
這個指令就可以快速的將圖片轉換成目標的格式。
但是實際使用上,我們還需要考慮到一些參數:
以下就針對不同的目標格式來說明。
首先我們要先將圖片依照需求縮小,因為過大的解析度在普遍使用的情形下只會增加網站載入的負擔,除非今天網站的目的本身就是有瀏覽高解析度照片的需求,否則一般我們可以直接將解析度做一定程度的減少來降低圖片容量。
架設我們今天需要的是寬度 1920px 的圖片(也是當今普遍的螢幕解析度)。
(在 Retina 螢幕普及的現在,寬度 1920px 仍有可能會不足,請依照自己的情境來選擇解析度)
magick input.jpg -resize 1920x output.jpg
上面我們傳入 -resize
參數來將圖片做縮放,而 1920x
表示我們的目標是轉換爲寬度 1920px 的圖片,而高度則是依照比例自動縮放。
如果你要指定高度的話:
# 只指定高度
magick input.jpg -resize x1080 output.jpg
# 高度寬度一併指定(注意影像寬高比以免產生影像變形)
magick input.jpg -resize 1920x1080 output.jpg
接下來我們將原圖轉為 JPEG。
如果原圖已經是 JPEG 了,仍需要做轉換,以進行圖片的優化。
可參考轉換指令如下:
magick input.jpg -strip -interlace Plane -gaussian-blur 0.05 -quality 50 output.jpg
參數說明:
-strip
: 移除圖片的內嵌資訊、註解、描述等等,減少文件的大小。-interlace Plane
: 將圖片轉換為漸進式圖片,以增加讀取速度及使用者體驗。-gaussian-blur 0.05
: 將圖片做高斯模糊處理,給減少容量大小。此選項可以自行決定要不要加。(某些圖片不適合使用模糊處理,請依照自己的需求增減此參數)-quality 50
: 設定圖片品質為 50%,範圍為 0 - 100,數字越高,圖片的容量大小越大,此參數就對映到 JPEG 的壓縮比 (1-10)。Imagemagick 的 JPEG 轉檔指令可參考這裡。
magick input.jpg -strip -gaussian-blur 0.05 -quality 40 output.webp
由於 WebP 提供了較佳的壓縮效率(失真小),所以我們這邊選定 -quality 40
作爲我們的參數。這個數值跟 JPEG 的壓縮比並不相同,而是屬於 WebP 的品質參數。
Imagemagick 的 WebP 相關轉檔指令可參考這裡。
另一個 WebP 轉檔工具可以參考 Google 所開發的 cwebp。
magick input.jpg -strip -gaussian-blur 0.05 -define jp2:rate=64 output.jp2
JPEG 2000 的壓縮比率需要如上方使用 -define jp2:rate=<比率>
來設定,這邊我們選用 64 作爲壓縮比率(64:1),以求較佳的容量大小,可以視情況自行增減數值。
Imagemagick 的 JPEG 2000 相關轉檔指令可參考這裡。
如果你的網站圖片很多,如果要手動輸入指令做轉換的話將會是一項大工程。因此我這邊提供一段指令以快速產生我們所需的三種格式的檔案:
#!/bin/bash
# Usage: geni [image name] [image format]
geni() {
if [ -f "$1.$2" ]; then
mv "$1.$2" "$1.temp.$2"
magick "$1.temp.$2" -strip -gaussian-blur 0.05 -quality 40 "$1.webp"
magick "$1.temp.$2" -strip -gaussian-blur 0.05 -define jp2:rate=64 "$1.jp2"
magick "$1.temp.$2" -strip -interlace Plane -gaussian-blur 0.05 -quality 50 "$1.jpg"
rm "$1.temp.$2"
else
echo "$1.$2 does not exists."
fi
}
geni
你可以建立一個 shell script 如 geni.sh
,並將上面的內容加入。
接著輸入下面指令,以執行腳本來將 image.jpg
一口氣轉換為 image.jpg
, imgae.webp
, image.jp2
三種格式。
./geni.sh image jpg
# 請注意:不是輸入 image.jpg,而是將 image 及 jpg 分開輸入
如果出現權限相關錯誤,可以輸入下面指令來解決:
chmod u+x ./geni.sh
你也可以將腳本內所定義的 geni()
function 放到你的 .bashrc
, .bash_profile
或 .zshrc
當中:
# ~/.bash_profile
geni() {
if [ -f "$1.$2" ]; then
mv "$1.$2" "$1.temp.$2"
magick "$1.temp.$2" -strip -gaussian-blur 0.05 -quality 40 "$1.webp"
magick "$1.temp.$2" -strip -gaussian-blur 0.05 -define jp2:rate=64 "$1.jp2"
magick "$1.temp.$2" -strip -interlace Plane -gaussian-blur 0.05 -quality 50 "$1.jpg"
rm "$1.temp.$2"
else
echo "$1.$2 does not exists."
fi
}
接著重啟終端機,就可以在終端機當中直接使用指令囉:
geni image jpg
# 簡潔有力
如果覺得轉出來的圖片不符合需求,請自行調整 function 裡面的參數哦。
<picture>
來載入圖片有了圖片資源之後,我們如何將其引入到我們的網站當中呢?
畢竟每張圖片我們現在都擁有三種不同的格式,我們的目的就是讓瀏覽器自動判斷該使用哪張圖片。
而貼心的是,HTML 提供了 <picture>
這個標籤來幫我們處理這件事,首先先來個 MDN 的說明。
用法很簡單:
<!-- 我們的圖片名稱分別為 image.webp, image.jp2, image.jpg -->
<picture>
<source srcset="image.webp" type="image/webp" />
<source srcset="image.jp2" type="image/jp2" />
<source srcset="image.jpg" type="image/jpg" />
<img
src="image.png"
class="image-class-name"
/>
</picture>
在這裡 <source>
這個 tag 做的事情就是載入我們實際圖片的資源,而 <img>
tag 你可以把它當作一位代理人,也就是說:由 <source>
載入的圖片會被放在 <img>
這個位置來顯示。
瀏覽器載入圖片的規則是:由上而下依序判定哪個資源是被瀏覽器所支援,接著就載入它,一旦載入成功,之後的 <source>
就不會再進行載入。而所有 <source>
都載入失敗之後,才會載入 <img>
當中指定的支援以作備用。
這邊測試一下,使用 Edge 瀏覽器(Chromium 版本)做測試。由於 Edge 跟 Chrome 一樣並不支援 JPEG 2000,所以我們預期他應該要使用的是 WebP 格式。但這邊我故意將 .jp2
的檔案擺在第一位:
<picture>
<source srcset="colorful.jp2" type="image/jp2" />
<source srcset="colorful.webp" type="image/webp" />
<source srcset="colorful.jpg" type="image/jpg" />
<img
src="colorful.png"
class="image"
/>
</picture>
接著打開網站,看見圖片正常顯示,但究竟我們載入的是哪張圖片呢?我們可以打開瀏覽器的開發者工具,選擇網路(Network)的頁籤,篩選影像的資源載入情形,可以看見:
由此可知我們載入的圖片仍是 WebP 格式,而這是由瀏覽器自動判定的結果,第一順位的 jp2
格式不支援,因此順位到第二順位的 webp
格式來進行載入,而在之後的 .jpg
以及 .png
都沒有做載入。
那麼圖片在 DOM 當中圖片如何呈現呢?
我們可以將頁籤切換到元素(Element)去,找到我們位於網站上的 img.image
圖片元素,可以看見:
瀏覽器在頁面上仍然是用 <img>
作爲我們的圖片元件,src
欄位雖然寫著 colorful.png
,但其指向 colorful.webp
這個圖片資源的。
如此一來我就不用怕瀏覽器不支援圖片格式的問題,同時也改善了圖片載入的速度並達到減輕瀏覽器負擔的目的。
這邊附加一個技巧,就是在使用 <img>
的情況下實現 background-position: center;
+ background-size: cover;
的效果:
很簡單,只要在 <img>
的 CSS 上加上:
.image {
object-fit: cover;
object-position: center;
}
這樣就可以囉!(光是這個問題我苦惱了好一陣子www)
我的部落格在進行圖片效能的優化之前,載入時間相當久,於是我就對圖片資源做了最佳化之後,記錄前後的載入情形。
使用我的另一篇文章: 使用 Hugo 建立一個部落格並部署至 GitHub Page 來看看優化成果吧!
首先來看看圖片載入時間:
可以看到優化前載入時間耗時 3.27 秒,載入圖片總大小 4.2 MB。
優化後載入時間減少到 0.577 秒,總圖片大小只有 254 kB!
大小從 4.2 MB -> 254 kB,整整減少了 93% 的資源大小。
那麼接下來我們使用 Lighthouse 來檢測一下網站的效能分數吧!
優化前的效能分數只有 37 分,慘不忍睹…
而下方的提示有說到 FCP(First Contentful Paint) 時間太久,最大面積的元素載入過慢 (Largest Contentful Paint) 等等的,都是因為圖片太過肥大所致。
那麼優化之後的分數呢?
哇!這真是…驚人的結果!
從測試分數就可知道,光是簡易的圖片優化已經帶來非常不錯的效果了。更不用說我自己比較優化前後的載入速度,真的是體感差距明顯阿!
做個總結吧:
根據研究統計,使用者在進入網站之後 3 秒內如果沒有看見想看的內容,就有大幅度的機率離開網站。也就是說,載入速度將會是使用者體驗的首要關卡,也是使用者對於網站的第一感受。強化網站的載入速度:透過減少圖片容量、採用漸進式載入等等方法來降低圖片的載入所需時間,將會是一把利刃,可以有效的提升效能。
但為什麼要先從圖片優化起手呢?那是因爲圖片通常是網站當中檔案大小最大的資源,如果可以減少圖片大小,那麼就可以大幅減少總體的網站載入大小。
雖然優化之後效能的部分還是有很多需要加強的地方,但是至少從選擇格式、減少解析度、使用 <source>
來讓瀏覽器自行選擇相容的格式等這些初步的方法來做優化,便可以看見令人滿意的成果。
當然圖片優化還有很多種進階的方法:
等等如上述舉例的進階方法,都可以再更進一步的幫助網站有更好的圖片效能。(有機會再來寫寫相關文章吧)
現在就開始優化你的網站吧,從最致命但效果也最大的目標開始:圖片。