加速網站效能 — 來理解圖片的優化吧!

Sean Chou
Recording everything
11 min readAug 20, 2021

--

from: unsplash @mike_van_den_bos

在開發 side project 時,其實沒有特別注重效能這塊,在開發完到了一個階段後,才回頭來看看效能與SEO能夠有哪些進步的空間。先來看看原本怎麼做,一般傳統的做法,我們都會把頁面上要用的圖片,跟 source code 放在 repo 中,最後打包的時候一起打包。在需要做 RWD 改變圖片大小的時候,就根據不同 breakpoint 直接去改變圖片的寬跟高。

檢視問題

首先,我們先來看看到底問題出在哪裡,先使用 lighthouse 的 report 來 review 一下可能的效能瓶頸:

這裡會列出各種可能影響效能的因素提供參考

從中挑出幾個跟圖片有關的問題:

  • Serve images in next-gen formats
  • Properly size images
  • Avoid enormous network payloads

Serve images in next-gen formats

Image formats like JPEG 2000, JPEG XR, and WebP often provide better compression than PNG or JPEG, which means faster downloads and less data consumption.

由於本來的網頁中使用了一些 png 的圖檔,這裡建議可以使用 jpeg 2000, jpeg xr 或是 WebP 的圖片格式,來讓圖檔的大小更小,讓讀取速度更快。Lighthouse report 會幫你列出來本來的 resource szie 還有你改變之後,可能可以省下的空間提供參考。

more reference: https://web.dev/uses-webp-images/

Properly size images

Serve images that are appropriately-sized to save cellular data and improve load time.

我們在沒有注意圖片效能優化的情況下,往往都是從 Designer 那裡拿到的原始圖片,直接放進去 source 當中,等到要使用的時候,再根據當前需要去做圖片的大小縮放,無形之中其實你浪費了許多不需要的時間來載入太大的圖片檔案,所以這裡建議是,載入符合使用時機所需要的大小圖片即可,不要載入大於你實際 rendered 到畫面的圖片大小。

Anything larger than that just results in wasted bytes and slows down page load time.

more reference: https://web.dev/uses-responsive-images/

Avoid enormous network payloads

Large network payloads cost users real money and are highly correlated with long load times.

Lighthouse 會計算你的 network payload total size,而這個發生的原因也是跟載入的資源太大有關,根據 HTTP Archive data,network payload 的中位數介於 1,700 到 1,900 KiB,目標是讓你的總 network payload size 低於 1,600 KiB。如果我們可以降低圖片的大小,載入合適的圖片大小,也可以改善這塊的效能。

more reference: https://web.dev/total-byte-weight/

解決方案

在檢視了目前網站的問題之後,針對圖片的效能改善,我們可以歸納的重點大概就是以下這兩點:

  • 改變圖片格式以減少圖片大小
  • 載入合適大小的圖片

改變圖片格式以減少圖片大小

顧名思義,由於專案中用到了一些透明的圖片,我們拿到的原始圖檔為 .png,這時候就可以將其改為更高壓縮的檔案來減少網路傳輸。

from: wikimedia

推薦可以使用 WebP,WebP的設計目標是在減少檔案大小的同時,達到和JPEG、PNG、GIF格式相同的圖片品質,並希望藉此能夠減少圖片檔在網路上的傳送時間。目前 WebP 支援所有主流的瀏覽器, latest versions of Chrome, Firefox, Safari, Edge, and Opera,除了 IE。

不過,要注意一點是 WebP 在 iOS 14 之後才加入支援,因此假如使用 iOS 13 的手機不管你用什麼瀏覽器都會不支援喔!

可以到 Can I use 來事先檢查一下支援度:

https://caniuse.com/webp

載入合適大小的圖片

首先,載入合適大小的圖片,不外乎就是要把從 Designer 那裡拿到的原始圖檔,針對我們的需求來製作符合需求 size 的新圖片。然而,在 RWD 的情況下,常常我們會需要不同大小的同一張圖片,難道我們要準備各種大小的同一張圖片嗎?這時候我們就可以用 Image CDNs 的服務來幫助我們了!

Image CDNs (Image content delivery networks)

Image CDNs 是一種網路服務,他主要專注在圖片的轉換與優化,有點像是專門提供圖片的 API,幫助你更方便的管理你網頁上需要的圖片,網路上有很多的服務供應商,有需要可以比較看看哪一種比較合適。

10 Image CDN Providers

https://theguidex.com/best-image-cdn-providers/

這次使用的是 cloudinary,簡單來說用法就是把你的原始圖檔丟上去,可以透過 url 來存取不同大小的同一張圖片,在 resize 這段就不需要自己來改圖片了。再者,也不再需要把圖片跟著你的 code 一起 deploy 到 hosting 上面去,不只浪費空間也不好維護。

舉例來說,想要拿同一張圖片,在長寬各為 600x600 與 300x300 兩種不同情況時,可以這樣做:

這樣就很方便了,我們只需要在不同 breakpoint resize 的時候來拿不同圖片就可以了!

更簡潔的 Responsive Images 寫法

除了在 @media(max-width: 500px) 下去替換圖片這種寫法,有沒有更乾淨漂亮的寫法呢?

我們可以使用 HTML 的 picture sourceimg 來搭配使用。

  • img: 設定 default 的圖片路徑
  • source: 藉由 media 來決定在不同 breakpoint 底下,要使用哪一個 srcset 的值來替換目前的 img source

簡單來說,瀏覽器會在每個 <source> 元素中選出最適當的選項。如果沒有找到最適當的或是瀏覽器不支援 <picture> 元素就會使用 default 的 <img> 屬性的 URL。

更多資訊可以參考 MDN:

改善結果

經過了我們改變圖片格式以減少圖片大小,也使用 Image CDNs 來載入合適大小的圖片之後,再來跑一次 lighthouse 看看成效吧!

第一次的改動中,除了剛剛提到的 image enhance,其實也順便對 Google Fonts 下載加了使用 swap 的方式,不過大方向看起來效能是有變好一點點。

還有其他可以做的嗎?

除了剛剛這些,還有沒有可以做的事呢?除了載入圖片,使用者體驗其實也是很重要的一環。再者,由於我們載入圖片改成從 Image CDNs 來,所以在網路上抓圖片這段的效能也很重要。

from: unsplash @jakegivens

Preload, Preconnect and Prefetch

為了加速圖片的下載與增進使用者體驗, 這裡我們想做的事有兩個:

  • 先將不同 size 的圖片 preload 好,增進使用者體驗
  • 預先解析需要用的資源的 domain name,來加速下載

Preload

Preload 是 Link tag 下 rel 屬性的一個值,意思是可以告訴瀏覽器這份資源很重要,需要事先下載。由於 preload 下載的資源與一般 HTTP request 拿到的資源一樣都會放在 cache,因此等到後續這個資源(圖片)要被用到的時候,就可以直接從 cache 拿來使用了。

Preconnect and DNS-prefetch

Preconnect 的功用在於提前建立連線,由於建立連線需要通過 DNS Lookup + TCP Handshake + SSL Negotiation 三個步驟,如果事先與要下載的資源建立連線,就可以省下當中很多的請求時間。

再者當瀏覽器請求資源時,必須先將 domain 解析為 IP 位置,然後瀏覽器才能發出請求,DNS-prefetch 可以提示瀏覽器預先處理 DNS lookup,解析你所需要資源的 domain 來找到實際的位置。

例如我們的 images 都放在 cloudinary 上面,所以就可以預先建立連線並解析路徑的位置。

最後再來看一次結果,好像又增進了不少:

延伸閱讀:

如何 Preload Google Fonts?

對於酒類知識有興趣,歡迎參觀 Mixtini.co

https://www.instagram.com/mixtini.co/

官方網站 & 調酒搜尋器 (Work in progress)

Special thanks:

感謝 Summer 大大協助與提點的幾個調整方向,更多更詳細的效能議題,可以參考:

如果你覺得這篇文章對你有幫助,歡迎買杯咖啡贊助 ☕️ 謝謝

--

--