網頁加載速度優化

簡介

  • 網頁加載速度,除了會影響使用者體驗,也會影響 SEO 成效
  • 加載速度超過 3 秒的網頁,跳出率會顯著提高
  • 以下紀錄幾種提升網頁載入速度的方法,整理一下自己的筆記

Lazy Loading

  • 優先加載使用者可視區域內的資源,其他次要的資源延遲加載
  • 直到這些資源用到時再載入,減輕伺服器負擔

圖片的 Lazy Loading

  • 使用img標籤原生的loading屬性
  • 設定loading="lazy",瀏覽器會自動實現
  • 當圖片進到 viewport 時,才會載入
<img src="cover.jpg" loading="lazy" alt="cover" />

資料的 Lazy Loading

  • Infinite Scroll 的應用
  • 當使用者滾動到頁面底部時,觸發 AJAX 函式,向伺服器發送請求,載入更多內容
  • 使用Intersection Observer API
  • 設定一個觀察者(observer),用於監測一個或多個元素與其根元素或 viewport 的交叉情況
  • 當所觀察的元素進入或離開 viewport 時,會觸發一個 callback function

注意事項

  • 在畫面一載入就需要顯示的圖片,不適用 Lazy Loading

使用 Lazy Loading 的圖片

  • 可以給一個寬高固定的佔位元素或圖片(Skeleton / Placeholder)
  • 避免頁面在加載過程中,版面抖動或移動,影響使用者體驗和 CLS 分數

做法 1:在圖片外層包一個固定大小的 Container

.image-container {  width: 200px;  height: 150px;  overflow: hidden;}.image-container img {  width: 100%;  height: auto;}

做法 2:使用aspect-ratio屬性

  • 在該元素的實際內容還未加載時,瀏覽器也會根據指定的寬高比預留出相應的空間
.img-container {  width: 100%;  aspect-ratio: 16 / 9;  overflow: hidden;}.img-container img {  width: 100%;  height: auto;}

圖片最佳化

  • 主要專注在圖片大小的壓縮,讓頁面載入速度更快

圖片格式

  • 使用 WebP 格式,可以保持解析度,但大小比 PNG, JPEG 更小

響應式圖片

  • 使用 HTML 的picture標籤或srcset屬性,根據使用裝置顯示不同大小或解析度的圖片
  • 例如使用手機時,只加載手機所需的圖片大小,不必載入桌機的大圖片

picture 使用範例

  1. 建立picture容器
  2. 按照source出現的順序,從上到下解析
  3. 從最優先的條件開始往下寫,在最下面放一個預設條件
  4. media屬性用來設定 media query 條件
  • 視窗寬度小於 600px 時,載入 example-small.jpg
  • 視窗寬度在600px~1200px 時,載入 example-medium.jpg
  • 如果以上條件都不滿足,載入 example-large.jpg
<picture>  <source srcset="example-small.jpg" media="(max-width: 600px)" />  <source srcset="example-medium.jpg" media="(max-width: 1200px)" />  <img src="example-large.jpg" alt="example" /></picture>
  • type屬性,可以指定圖片的 MIME 類型(圖片格式)
  • 根據瀏覽器的支援度提供不同的圖片格式
<picture>  <source srcset="image.webp" type="image/webp" />  <source srcset="image.jpg" type="image/jpeg" />  <img src="image.jpg" alt="example" /></picture>

img 標籤使用範例

  • sizes屬性,告知瀏覽器選擇圖片尺寸的條件
  • srcset屬性,設定在特定條件下,要顯示哪張圖片
  • 視窗寬度小於600px時
    • 圖片寬度設定為 480px (sizes)
    • 瀏覽器從 srcset 中選擇最接近 480px 的 example-small.jpg(srcset)
  • 視窗寬度在600px 至 1200px之間時
    • 圖片寬度設定為 800px (sizes)
    • 瀏覽器選擇最接近 800px 寬度的 example-medium.jpg(srcset)
  • 視窗寬度大於 1200px
    • 圖片寬度設定為 1200px(sizes)
    • 瀏覽器選擇 example-large.jpg(srcset)
<img  srcset="  example-small.jpg 500w,  example-medium.jpg 1000w,  example-large.jpg 1500w"  sizes="  (max-width: 600px) 480px,  (max-width: 1200px) 800px,                      1200px"  src="example-medium.jpg"  alt="example"/>

HTTP Cache 快取

  • 可以在使用者的瀏覽器暫時儲存資源(例如圖片和網站資料)
  • 下次需要時,直接從 cache 取出,不需重新向伺服器發送請求

優點:

  • 減少請求次數
  • 加快資源載入

如何實作

在 HTTP 的Response Header設定

cache-control

  • 指定資源在客戶端儲存的方式

ETag

  • 請求資源時專屬於資源版本的標示
  • 每次更新資源時,伺服器上的 ETag 都會變更

常見設定如下:

  1. cache-control: public
    • 資源可以由任何快取儲存,包括客戶端瀏覽器、中繼代理等
    • 適用不涉及使用者特定資料的資源,例如公共的圖片
  2. cache-control: private
    • 只能由用戶端快取,而不能由中繼代理程式(如 CDN 或代理)快取
    • 適用於使用者私人資訊
  3. cache-control: no-store
    • 無法在任何地方快取
    • 每次使用者請求此資料時,都必須向原始伺服器傳送請求以獲取新複本
    • 適用於個人敏感資訊,例如銀行交易資料
  4. cache-control: no-cache
    • 每次使用快取前,都要先和伺服器確認資源是否被更改
    • 通常與ETag搭配使用
    • 會先傳送快取的 ETag 與伺服器的ETag比對版本
      • 相同 => 不需重新請求資源
      • 不同 => 資源已更新,需重新請求
  5. cache-control: max-age
    • 規定快取資源的過期時間
    • 在時間到之前,不會向伺服器傳送請求
    • HTTP 狀態碼會是Status code 200 (from memory cache))
cache-control: max-age=3600 // 本地快取存留1小時(3600秒)

CDN

  • Content Delivery Network 內容傳遞網路,是一組多個分散部署於各地的中繼伺服器
  • 主要目的是將內容儲存在盡可能靠近請求用戶端電腦的位置,從而減少延遲並縮短頁面載入時間
  • 適合存放一些長時間不會變動的靜態資源,例如圖片、影音等

範例情境

假設有一個網站,服務器位於美國。如果沒有使用 CDN,那麼全球的用戶(包括位於歐洲和亞洲的用戶)在訪問你的網站時,所有數據請求都必須直接傳輸到美國的服務器,這可能導致顯著的延遲和較慢的加載時間。

當使用 CDN 時,網站內容會被複製到全球多個服務器上。例如,當一位位於德國的用戶訪問你的網站時,他們會從最近的 CDN 節點(可能在歐洲)獲得數據。同樣,來自日本的用戶會從亞洲的 CDN 節點獲得數據。這樣可以減少數據傳輸的距離,加快網頁加載速度,提高用戶體驗。

使用 CDN 的優點

縮短頁面載入時間

  • 將內容分發到訪問者(用戶端)附近的 CDN 伺服器,讓訪問者體驗到更快的頁面載入時間

伺服器負載平衡

  • 可以在多個伺服器間分配流量,減輕單一伺服器的壓力
  • 如果一個節點出現問題,流量可以自動轉移到其他運行正常的節點上

減少頻寬成本

  • 通過快取靜態資源來減少向原始服務器的數據請求,從而降低頻寬成本

加強資安防護

  • 可以透過在多個中介伺服器之間分佈負載來處理此類流量高峰,從而減少對原始伺服器的影響
  • 提供額外的安全功能,如 DDoS 攻擊防護、網路防火牆和 SSL 加密,有助於保護網站免受網路攻擊

參考資料

# Web # 效能