前言

上一篇實驗 Imgproxy vs Akamai CDN:圖片下載效能統計實測 確認了:在 CDN 快取建立後,CloudFront → Imgproxy → S3 在「下載速度」上跟 Akamai → S3 已可一較高下。

只下載快沒意義,因為原本用 Imgproxy 的目的是壓縮圖檔讓整體載入更快。所以這篇實驗的問題是:壓縮真的能讓使用者載得更快嗎?


目標

  1. 將圖片壓縮到 50 KB、250 KB、500 KB、1 MB 等不同檔案大小
  2. 對於已小於目標大小的圖片,不進行壓縮以避免檔案變大
  3. 支援多種圖片格式(PNG、JPG、AVIF 等),依需求選擇最佳壓縮格式
  4. 提供不同解析度的圖片給前端,讓前端可以根據用戶網速自動切換合適檔案大小

壓縮設計

步驟 1:判斷檔案大小與格式

  • 從 Akamai → S3 下載原始圖片後,先檢查檔案大小與格式
  • 如果檔案小於欲壓縮格式目標大小(例如欲壓縮至 250 KB 但檔案只有 70 KB),則該規則不做處理,繼續跳往下一級 (50 KB)
  • 如果檔案大於目標大小,進行壓縮或格式轉換

步驟 2:選擇壓縮策略與格式

優先順序:

  1. JPG (JPEG):適合照片、色彩豐富的圖片。壓縮率高但有損
  2. AVIF / WEBP:壓縮率更高、幾乎無損,適合支援新格式的瀏覽器
  3. PNG:適合需要透明背景的圖片。無損壓縮但壓縮率較低

選擇策略:

  • PNG → JPG:如果 PNG 沒有透明背景且圖片過大,轉成 JPG 可大幅縮減檔案大小
  • AVIF → AVIF:AVIF 通常已經很小,不需要轉換,僅調整品質
  • JPG → JPG:降低品質進行壓縮
  • GIF → WEBP:動態 GIF 可轉成 WEBP,通常能縮小 30–50%

步驟 3:壓縮參數設定

通則:

  • JPGquality=70-80 是較理想的平衡點,70 可顯著減少檔案大小、畫質影響有限
  • PNG:使用無損壓縮,或在透明度不重要時轉成 JPG
  • WEBP / AVIFquality=60-70 仍能保持優異畫質、檔案非常小

實測下來的最佳參數搭配:

PNG

原檔大小壓縮參數
> 1 MBq:80/rs:fit:1920:1080
500 KB – 1 MBq:70/rs:fit:1280:720
250 KB – 500 KBq:60/rs:fit:800:600
50 KB – 250 KBq:50/rs:fit:400:300

JPEG / JPG

原檔大小壓縮參數
> 1 MBq:80/mb:1000000/rs:fit:1920:1080
500 KB – 1 MBq:70/mb:500000/rs:fit:1280:720
250 KB – 500 KBq:60/mb:250000/rs:fit:800:600
50 KB – 250 KBq:50/mb:25000/rs:fit:400:300

WEBP

  • 基準:q:80mb:250000
  • 進一步依檔案大小調整,參數同 JPEG

步驟 4:多版本輸出

針對同一張圖片輸出多個版本:

  • original(原圖)
  • large(1 MB)
  • medium(500 KB)
  • small(250 KB)
  • thumbnail(50 KB)

把不同大小的檔案存到 S3 不同路徑,依需求調用。


執行步驟

1. 確認 S3 現有圖片檔案格式

從 stg 環境把所有 user_upload 拉下來檢查。

圖1. S3 檔案類型

圖1. S3 檔案類型

表1. S3 檔案類型總數

表1. S3 檔案類型總數

2. 與前端對齊

目前所有上傳圖檔都會被轉換成 .png 格式。

3. 根據壓縮策略,檢查檔案類型與大小

只有檔案大小大於該 rule 的目標才需要送 Imgproxy 處理,小於則直接略過。例如:

  • PNG 241 KB:略過 > 1 MB500 KB – 1 MB 的步驟
  • JPEG 13 MB:4 個 rules 都要做
  • WEBP 80 KB:只需要做 50 KB – 250 KB

4. 比較指標

每一個 rule 跟 cdn_s3 比較下載速度、紀錄:

  • cdn_s3 下載檔案大小 / 時間
  • 每個 rule 的 cdn_imgproxy 下載檔案大小 / 時間(沒做該 rule 留空)
  • 每個檔案各下載 3 次取平均
  • 計算 cdn_s3 vs 各 cdn_imgproxy rule 的壓縮率
  • 計算 cdn_s3 vs 各 cdn_imgproxy rule 的下載時間縮減量

5. 兩次實驗

一共做了兩次,原因是考慮第一次下載時 CDN 快取機制尚未建立。


第一次實驗(冷快取)

圖 2 為第一次下載 Akamai_S3 與 CloudFront_Imgproxy 壓縮圖檔的資料,根據四種壓縮大小分類做數據分析。

圖2. 第一次壓縮主要分析:壓縮數、時間減少、壓縮率、相關性

圖 2. 第一次壓縮主要分析 — 壓縮檔案數(左上)、下載時間減少數(中上)、壓縮率分布(右上)、下載時間減少率(左下)、變慢案例分析(右下)

壓縮檔案數(左上)

四種壓縮率都成功,沒有越壓越大的案例。大檔案符合 Large 規則的數量最少;Thumbnail 數量最多 — 代表絕大多數檔案都會走到 Thumbnail。

下載時間減少數(中上)

每個 category 真正成功減少下載時間的比例都不到一半 — Akamai 還是比較快。

壓縮率(右上)

Large 規則會出現「越壓越大」的情況,其他 category 都有高比率壓縮成功。

下載時間減少率(左下)— 反直覺發現

規則時間減少率等價於
Large-154.4%載入時間增加約 2.5 倍
Medium-113.0%載入時間增加約 2.1 倍
Small-114.5%載入時間增加約 2.1 倍
Thumbnail-118.6%載入時間增加約 2.2 倍

時間減少率計算方式:

time_reduction = (results['cdn_s3_time'] - avg_time) / results['cdn_s3_time'] * 100

也就是 (S3 下載平均時間 - 該壓縮檔平均下載時間) / S3 平均下載時間 * 100

結論:Imgproxy 處理增加了額外的載入時間,雖然檔案變小,整體載入時間反而增加。

可能的原因:

  1. Imgproxy 處理圖片需要額外時間
  2. CDN 快取機制差異
  3. CDN_S3 原圖已經在 CDN 快取中、本來就比較快
  4. Imgproxy 的伺服器位置或效能瓶頸

變慢案例分析(右下)

針對「壓縮後反而變慢」的 case 做散佈分析:

  • X 軸:原始圖片大小(KB)
  • Y 軸:載入時間增加百分比
  • 顏色:壓縮率(黃→綠→紫,由高到低)

分布特徵:

  • 散點呈現負相關趨勢(紅色趨勢線向下)
  • 大部分數據集中在 0–3 MB 的範圍內
  • 載入時間增加的比例主要分布在 0–600% 之間

發現:

  • 較小的原始圖片(< 2 MB)反而會出現較大的載入時間增加(最高約 900%)
  • 隨著原始圖片變大,載入時間增加的比例趨於降低

實務意義:

  • 小型圖片做壓縮反而會增加載入時間
  • 大型圖片的壓縮效果較好,載入時間增加的風險較低
  • 建議根據原始圖片大小來決定是否進行壓縮

圖3. 壓縮率與時間減少率之間的相關性分析

圖 3. 第一次實驗 — 壓縮率與時間減少率的相關性

各 category 的相關性係數

Categoryr 值解讀
Large0.78最強正相關,壓縮率越高、下載時間減少越多
Medium0.69次強,分散度稍大
Small0.74第二強,數據集中度適中
Thumbnail0.55最弱,數據分散度最大

第一次實驗的小結

Akamai → S3 在「整體載入時間」上仍全面優於 CloudFront → Imgproxy 的各種壓縮 — 看圖 2 左下的時間減少率最直覺。

延伸:

是不是因為快取機制尚未建立、整體加載速度才變慢?所以接著用同一份檔案再做一次。


第二次實驗(暖快取)

目的

Imgproxy 壓縮搭配 CDN 快取建立後,是否能有效提升性能。

圖4. 第二次壓縮主要分析

圖 4. 第二次壓縮主要分析 — 暖快取下的壓縮表現

與第一次的差異

  1. 變慢的數量(中上的橘色部分)減少了
  2. Large 仍然有越壓越大的現象 — 代表參數還需要調整,或是 Akamai 本身的大圖壓縮做得就很好(詳見附錄 1)
  3. 下載時間減少率(左下):除了 Large 之外,Medium、Small、Thumbnail 都從負值翻成正值,代表暖快取後三者有效減少了下載時間

變慢案例分析(右下)

  • 小圖片(< 1000 KB)的載入時間變化最大,有些甚至增加到 700%
  • 大圖片(> 3000 KB)載入時間增加相對較小,多在 50% 以下

結論:

  • > 3 MB 的圖片適合使用 Imgproxy
  • < 1 MB 的小圖片直接走 Akamai → S3 下載原圖效率較好

圖5. 第二次壓縮率與時間減少率相關性分析

圖 5. 第二次實驗 — 壓縮率與時間減少率的相關性

相關性分析

相關係數隨壓縮等級降低而減小(0.77 → 0.47)。所有等級都呈現正相關 — 更高的壓縮率通常帶來更好的時間減少效果。

  • Large 壓縮最可預測(r 最高)
  • Thumbnail 跟 Akamai 比起來效果沒有顯著提升

負值區域代表:

  • 負壓縮率:檔案實際變大
  • 負時間減少率:載入時間實際增加

實務建議

  • 需要可預測的效能改善時,優先選擇 Large 壓縮
  • Thumbnail 雖然壓縮效果最大,但實際效果沒有 Akamai 好
  • Large 壓縮的參數還需調整,減少壓縮後檔案變大、下載時間變長的問題

總結

  1. 不是所有圖都該壓縮。 小於 1 MB 的圖直接走 Akamai → S3 更快
  2. 冷快取下 Imgproxy 壓縮全面輸 Akamai — 載入時間 -113% 到 -154%
  3. 暖快取下,只有 Medium / Small / Thumbnail 受惠 — Large 仍越壓越大
  4. 壓縮率與時間減少率呈正相關(r = 0.77 → 0.47)— Large 最可預測、Thumbnail 最弱
  5. 行動建議:在 imgproxy gateway 上加 if size > 3MB then compress 規則,其他直接走 origin

附錄

1. Akamai 設定

我們家 Akamai 對大圖本來就有 automatic compression,可能是 Large category 表現不如 Akamai 的原因之一。

Akamai 圖片轉檔設定 1

Akamai 設定 1

Akamai 圖片轉檔設定 2

Akamai 設定 2

Akamai 圖片轉檔設定 3

Akamai 設定 3

Akamai 圖片轉檔設定 4

Akamai 設定 4


This post is also available on Medium (cross-posted, link forthcoming).