《 Akamai + S3 與 CloudFront + Imgproxy + S3 使用分析二:壓縮圖片設計流程:檔案大小 vs 載入時間的權衡》

要透過 Imgproxy 客製化每種圖檔要被壓縮的方法,真的超難啦!

目標

  1. 將圖片壓縮到 50 KB、250 KB、500 KB、1 MB 等不同檔案大小。

  2. 對於已小於目標大小的圖片,不進行壓縮以避免檔案變大。

  3. 支援多種圖片格式(PNG、JPG、AVIF 等),依據需求選擇最佳壓縮格式。

  4. 提供不同解析度的圖片給前端,讓前端可以根據用戶網速自動切換合適檔案大小。


壓縮設計

目的

利用 Imgproxy 壓縮圖檔下載是否可以有效增加下載圖片效率

步驟 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:壓縮參數設定

  • JPG:

    • quality=70-80 是較理想的平衡點,70 可顯著減少檔案大小,畫質影響有限。

  • PNG:

    • 使用無損壓縮,或轉換成 JPG 若透明度不重要。

  • WEBP / AVIF:

    • quality=60-70 仍能保持優異畫質,檔案非常小。

  • 根據以上制定規則,以下為測試參數搭配在不同檔案類型下有最佳效果的測試
    • png:

      • > 1MB: q:80/rs:fit:1920:1080

      • 500 KB - 1 MB: q:70/rs:fit:1280:720

      • 250 KB - 500 KB: q:60/rs:fit:800:600

      • 50 KB - 250KB: q:50/rs:fit:400:300

    • jpeg or jpg

      • > 1MB: q:80/mb:1000000/rs:fit:1920:1080

      • 500 KB - 1 MB: q:70/mb:500000/rs:fit:1280:720

      • 250 KB - 500 KB: q:60/mb:250000/rs:fit:800:600

      • 50 KB - 250KB: q:50/mb:25000/rs:fit:400:300

    • webp

      • q:80

      • mb:250000

      • > 1MB: q:80/mb:1000000/rs:fit:1920:1080

      • 500 KB - 1 MB: q:70/mb:500000/rs:fit:1280:720

      • 250 KB - 500 KB: q:60/mb:250000/rs:fit:800:600

      • 50 KB - 250KB: q:50/mb:25000/rs:fit:400:300

步驟 4:多版本輸出

  • 針對同一張圖片,輸出多個版本,包含不同大小與格式:

    • original (原圖)

    • large (1 MB)

    • medium (500 KB)

    • small (250 KB)

    • thumbnail (50 KB)

  • 將不同大小的檔案存到不同的 S3 路徑或資料夾,依需求調用。

執行步驟

  1. 確認 S3 現有圖片檔案格式
    • S3 下載檔案確認
      • stg 上的所有 user_upload 都拉下來檢查
        圖1. S3 檔案類型

      • 表1. S3 檔案類型總數

    • 與前端確認:目前都會把圖檔轉換成 .png 格式
  2. 根據壓縮策略,檢查檔案類型與大小
  3. 如果檔案大小大於 rules 才需要去 imgproxy 下載圖片,如果小於直接略過
    • 例如 png 檔 241 KB,則略過 > 1MB 跟 500 KB - 1 MB 的步驟
    • jpeg 檔 13MB 則 4 個 rules 都要做
    • 根據壓縮策略,檢查檔案類型與大小
    • wepb 80KB 則只需要做 50 KB - 250KB
  4. 比較每一個 rules 與 cdn_s3 下載的速度,紀錄

    1. cdn_s3 下載檔案大小

    2. cdn_s3 下載檔案時間

    3. 每個 rules 的 cdn_imgproxy 下載檔案大小,如果沒做該 rules 就留空

    4. 每個 rules 的 cdn_imgproxy 下載檔案時間,如果沒做該 rules 就留空

    5. 每個檔案都下載三次計算平均

    6. 計算 cdn_s3 與每個 cdn_imgproxy rule 的壓縮率

    7. 計算 cdn_s3 與每個 cdn_imgproxy rule 縮減的下載時間

  5. 一共做了兩次,以下為兩次數據結果。會想做兩次是考量到,第一次下載時 CDN 緩存機制尚未成熟建立的可能。

數據分析

圖2. 為第一次下載 Akamai_S3 與 CloudFront_Imgproxy 壓縮圖檔的資料。依據上述規則,根據四種壓縮大小分類做數據分析。
圖2. 壓縮檔案數(左上)、下載時間減少數(中上)、檔案依據不同規則之壓縮率(右上)
下載時間減少率(左下)、壓縮後下載時間變長的案例,分析其檔案大小、壓縮率與增加時間關係(右下)

壓縮檔案數(圖2. 左上)

四種壓縮率都成功,沒有越壓越大的例子,大檔案壓縮的數量最少,表示影較少的檔案 > large 規則;Thumbnail 的壓縮數最多,表示大部分檔案都 > Thumbnail 的規則。

下載時間減少數(圖2. 中上)

成功減少下載時間的比例,比 Alkamai 快的數量在每個 category 不到一半

壓縮率(圖2. 右上)

Large 的 category 會越壓越大,其他 category 都有高比率壓縮成功

下載時間減少率(圖2. 左下)

  • 大圖:-154.4% → 載入時間增加了約2.5倍

  • 中圖:-113.0% → 載入時間增加了約2.1倍

  • 小圖:-114.5% → 載入時間增加了約2.1倍

  • 縮圖:-118.6% → 載入時間增加了約2.2倍

減少時間計算方式:(S3 下載平均時間 - 該壓縮檔平均下載時間) / S3 平均下載時間 *100
time_reduction = (results['cdn_s3_time'] - avg_time) / results['cdn_s3_time'] * 100
這表示 Imgproxy 的處理增加了額外的載入時間,雖然檔案大小有所減少,但整體載入時間反而增加

可能的原因:

  1. Imgproxy 處理圖片需要額外時間

  2. CDN 快取機制的差異

  3. CDN_S3 原始圖已經在 CDN 快取中,理應會比較快

  4. Imgproxy 的服務器位置或性能問題

下載速度增加的 Case 分析:Analysis of Cases with Increased Load Time(圖2. 右下) 

始圖片大小與加載時間增加之間的關係:

1. 軸向說明:

X軸:Original Image Size (KB) - 原始圖片大小(以KB為單位)

Y軸:Load Time Increase (%) - 加載時間增加的百分比

右側色條:Compression Ratio (%) - 壓縮率百分比

2. 數據分布特徵

散點的分布呈現負相關趨勢(紅色趨勢線向下)

大部分數據點集中在圖片大小 0-3 MB 的範圍內

加載時間增加的比例主要分布在 0-600% 之間

3. 發現

較小的原始圖片(< 2000KB)可能會出現較大的加載時間增加(最高達到約 900%)

隨著原始圖片大小增加,加載時間增加的比例趨於降低

點的顏色表示壓縮率,從黃色到綠色到紫色,代表壓縮率從高到低

4. 實務意義

對於小型圖片,壓縮可能反而會增加加載時間

大型圖片的壓縮效果較好,加載時間增加的風險較低

建議根據原始圖片大小來決定是否進行壓縮


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

Large Compression (r = 0.78)

最強的正相關性(r = 0.78)

X軸範圍:-250% 到 100% 的壓縮率

Y軸範圍:-1000% 到 100% 的時間減少率

趨勢線呈現明顯的正斜率,表示壓縮率越高,下載時間減少越多

Medium Compression (r = 0.69)

次強的正相關性

X軸範圍:-200% 到 100% 的壓縮率

Y軸範圍:-700% 到 100% 的時間減少率

數據點分散度較 Large 稍大

Small Compression (r = 0.74)

第二強的正相關性

X軸範圍:-150% 到 100% 的壓縮率

Y軸範圍:-800% 到 100% 的時間減少率

數據點集中度適中

Thumbnail Compression (r = 0.55)

最弱的正相關性

X軸範圍:-250% 到 100% 的壓縮率

Y軸範圍:-800% 到 100% 的時間減少率

數據點分散度最大

發現

Akamai + S3 的速度還是優於 CloudFront + Imgproxy 的各種壓縮,看圖 2 的下載時間減少率(左下)最直覺

延伸

是否因為快取機制尚未建立,因此整體加載速度變慢?因此再次做了一模一樣的實驗數據搜集與分析

------

目的

Imgproxy 壓縮圖檔搭配 CDN 緩存機制建立後,是否能有效提升性能

圖4. 為第二次下載 Akamai_S3 與 CloudFront_Imgproxy 壓縮圖檔的資料。

圖4. 壓縮檔案數(左上)、下載時間減少數(中上)、檔案依據不同規則之壓縮率(右上)
下載時間減少率(左下)、壓縮後下載時間變長的案例,分析其檔案大小、壓縮率與增加時間關係(右下)
與第一次相比,下載時間變長(中上的橘色部分)的數量減少了,Large type 依然有越壓越大的現象,代表參數還需要調整,或是 Akamai automatically 的大圖壓縮機制做得比較好,詳見附錄1. 有我們家的 Akamai 設定。
左下下載時間除了 Large 之外,都從負的變成正的,代表 Medium, Small, Thumbnail 都有效減少了下載時間。
右下的圖是壓縮後下載時間變長的例子,可以發現

小圖片(< 1000KB)的加載時間變化最大,有些甚至增加到 700%

大圖片(> 3000KB)的加載時間增加相對較小,多在 50% 以下

小圖片使用 imgproxy 可能會顯著增加加載時間,大圖片透過 imgproxy 處理反而較有效率

建議根據原始圖片大小來決定是否使用 imgproxy:

  • > 3000KB 的圖片適合使用 imgproxy
  • <1000KB 的小圖片使用 Akamai + S3 下載原圖有較好的效率


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

相關係數隨壓縮等級降低而減小(0.77 → 0.47)

所有等級都呈現正相關,表示更高的壓縮率通常帶來更好的時間減少效果

Large 壓縮最可預測,Thumbnail 則是和 Akamai 比起來效果沒有顯著提升

負值區域表示:

負壓縮率:檔案實際變大

負時間減少率:加載時間實際增加

實務建議:

當需要可預測的效能改善時,優先選擇 Large 壓縮

Thumbnail 壓縮有最大的壓縮效果,但其效果沒有 Akamai 好

在 Large 壓縮率還需調整,減少壓縮後檔案變大,下載時間變長的問題。


附錄

1. Akamai 設定





Comments

Popular posts from this blog

《 Imgproxy 使用分析一:圖片下載速度優化分析:Akamai CDN vs Imgproxy 效能比較》

程式語言初學者 Docker 入門第二章 —— 安裝與驗證 (Mac)