圖片資源 Base64 化在 H5 頁面裡有用武之地嗎

發表於2016-12-15

cover

將圖片資源轉至base64格式後可直接放入頁面作為首屏直出,也可以放入css檔案中,減少請求,以加快首屏的呈現速度。
不過圖片base64化,將帶來一個臃腫的html或css檔案,是否會影響頁面的渲染效能,瀏覽器又支援如何呢?

如何統計?

通過Navigation Timing記錄的關鍵時間點來統計頁面完成所用的時間,並通過Chrome開發工具來跟蹤細節

以上定義來自chrome官方文件,在其它環境下也許會有差異,從測試結果看,下面的build時間在android+微信環境中一直是0,對此可能是因為渲染機制差別,此處不做深入測試。除osx+chrome之外環境的資料僅作參考。

場景1,內嵌至css檔案中

1、原生引入圖片連結做背景圖

一張大小為50kbjpg格式圖片,應用到9×15=135個dom做背景圖,模擬雪碧圖的模式,多個節點引用同一張圖片做背景,(示例)如圖。
1455676041355
測試環境:Mac OS X EI Capitan 10.xx + Chrome 48.xx
其它輔助測試機器: iPhone 6 plus iOS 9.xx; 魅族Note Android 4.xx

實際使用過程中,其它版本和機型的Android手機還有待測試

關閉快取狀態下,build:150ms | complete: 200ms(總時間受網路狀態等因素影響,資料做比較用)
1455624301638

開啟快取狀態下,build: 7ms | complete: 59ms(包括以下穩定狀態下多次測試的平均值,截圖為最接近平均值的狀態,預設資料來自Mac+Chrome[48.XX版本])

1455624345624

測試環境 build(單位:ms) complete(單位:ms)
OS X+Chrome 7 59
iOS+微信 45 90
OS X+Safari 50 100
Android+微信 0 120

2、引入base64格式圖片做背景圖

將上面50kb大小的jpg圖片轉換為base64格式,加在css檔案中。

關閉快取狀態下,build:80ms | complete: 280ms

1455629551042
開啟快取狀態下,build: 160ms | complete: 210ms

1455629572545

測試環境 build(單位:ms) complete(單位:ms)
OS X+chrome 160 210
iOS+微信 35 100
OS X+Safari 9 90
Android+微信 12 150

3、調整圖片體積

調整上面圖片的(壓縮品質)體積,base64化後,對應的css檔案大小也跟著改變

圖片大小 10kb 20kb 45kb 100kb 180kb
對應css檔案大小 27kb 42kb 76kb 150kb 260kb
Rendering時間 30ms 46ms 81ms 156ms 258ms

data1

4、調整引用次數

50kb大小的圖片,base64化後,調整引用圖片做背景圖的dom的個數

引用次數 10 20 50 100 135
Rendering時間 15ms 19ms 44ms 74ms 83ms

data2

分析和小結:

在OSX+Chrome環境下,將50kb的圖片base64後放入樣式中,build過程拉長了約20倍,使用Timeline工具可以看到,計算樣式阻塞了整個過程。

1455634381569

  1. 比起直接引入圖片地址,css檔案中引入base64格式的圖片對樣式渲染的效能消耗明顯,如果大量使用,會帶來耗電和發熱的問題,需謹慎使用。
  2. Rendering消耗的時間同css檔案大小、引用次數幾乎成正比(未測試其它極限情況),在網路條件優質的4G環境,50~70ms的RTT(往返時延)情況下,通常行動網路的狀況會更差,對於首屏優化,合適的使用還是很值得的。
  3. 圖片轉成base64編碼後,文件大小較原檔案大了一些,而經過 gzip 後兩者幾乎沒有區別。

場景2,內嵌至js檔案中

1、原生方式直接載入多張圖片

大小10~70kb共9張圖片。總大小約300kb

關閉快取:build: 300ms | complete: 310ms

1455634756427
開啟快取:build: 110ms | complete: 120ms

1455634772411

測試環境 build(單位:ms) complete(單位:ms)
OS X+Chrome 110 120
iOS+微信 50 100
OS X+Safari 148 150
Android+微信 50 100

2、轉換成base64格式,合併請求

將上面的圖片轉成base64後,放在js檔案中,載入進來。

關閉快取:build: 0ms | complete: 400ms

1455634859983

開啟快取:build: 0ms | complete: 80ms

1455634882064

測試環境 build(單位:ms) complete(單位:ms)
OSX+Chrome 110 120
iOS+微信 0 35
OS X+Safari 7 70
Android+微信 0 250

3、比較不同網速下同步請求和合並請求的載入效率

使用上述1、2的測試demo分別在3G、4G網速條件下測試結果如下:

  • 在網路環境差的情況下,合併請求明顯縮短了整個載入時間;
  • 在網路環境較好的WIFI和4G下則差別不大。
測試環境 圖片直接載入 complete(單位:ms) base64合併請求 complete(單位:ms)
3G 6000 4500
4G 450 400
WIFI 320 340

data3

分析和小結:

base64後的的js資源達381kb,在一個執行緒里載入,消耗大量時間,從統計結果看,在渲染效能差異上並沒有場景1那麼明顯。
但有快取的情況下,頁面渲染完成的速度甚至更快。
從Timeline裡看到細節,解析這個近400kb的js檔案對整個渲染過程造成了一定壓力,不過總共40ms的解析時間是完全可以接受的。

1455635010603

  1. 從html裡直直接引用圖片連結和base64圖片對渲染效能的影響幾乎沒有區別,在網路條件差的情況下,合併請求卻能大大提高載入效率;
  2. 直接引用至html,無法快取,將base64後的圖片資源放在js檔案中管理,方便設定快取。
  3. 有一個缺點就是圖片資源base64化需要擴充套件構建工具來支援。

使用建議

  1. 圖片資源的base64編碼進css檔案會帶來一定的效能消耗,需謹慎使用。
  2. 將圖片資源編碼進js檔案中,管理和預載入H5應用的圖片資源,合理的合併請求可以大大提高頁面體驗。

相關文章