摘要
web性能的終極目標是減少資源到客戶端的延遲,但是我們在HTTP1.0/HTTP1.1協議中經常會遇到加載的圖片太多或者太大導致頁面加載完成慢的問題:圖片太多導致向服務器請求的次數太多,圖片太大導致每次請求的時間過長.
本篇將針對圖片太多或者太大總結幾種優化方案.
一.當圖片太多時
方案一:將圖片服務和應用服務分離(從架構師的角度思考)
了解到這一點,此方案是架構師在架構過程中必須要考慮到的.
對於服務器來說,圖片始終是最消耗系統資源的,如果將圖片服務和應用服務放在同一服務器的話,應用服務器很容易會因為圖片的高I/O負載而崩潰,所以當網站存在大量的圖片讀寫操作時,建議使用圖片服務器.
(注:圖片服務器是專門為圖片讀寫操作優化的獨立服務器,運行網站的服務器稱為應用服務器)
另外瀏覽器在同一時間對同一域名下的資源的並發請求數目是有限制的,一般在2-6之間,超過限制數目的請求就會被阻塞.一些主流瀏覽器對 HTTP1.1 和 HTTP 1.0 的最大並發連接數目,可以參考如下圖一:

圖一(來源於網絡)
把圖片服務器與應用服務器分開,圖片服務器采用獨立域名 ,css、js和圖片就可以並發請求了
方案二:簡單粗暴的壓縮方案
我們可以借助一些第三方軟件來進行壓縮,比如https://tinypng.com/,壓縮后分辨率不變,肉眼看不失真

圖二
方案三:圖片懶加載
像淘寶或者京東這樣的APP頁面上有很多圖片,當我們滑到下一屏時下一屏的圖片才會加載,這就采用了圖片懶加載的方式.
圖片懶加載,簡單來說就是在頁面渲染過程中,圖片不會一次性全部加載,會在需要的時候加載,比如當滾動條滾動到某一個位置時觸發事件加載圖片,如下代碼:
通過js將img標簽的data-src屬性賦值給src屬性
方案四:css Sprites
當網站或者APP有大量小icon,如果上傳到圖片服務器比如CDN, 要加載所有這些小icon將增加大量請求,而CDN是按流量收費的,這無疑將增加很多成本.
CSS Sprites 技術早已不新鮮,就是將這些小icon合並成一張圖片,只需要加載一次,每次通過background-position來控制顯示icon,這樣就可以節約大量請求,節約成本.
此方案是將網站上的一些小logo拼合成一個大圖,如圖

圖三(圖片來源於網絡)
不過這也有一定的缺點:在長期開發多人合作的項目中,會不好維護這些sprites,每次對icon做修改,都得相應的改動css里background-position的值,相當繁瑣.
方案五:將圖片壓縮成base64格式來節約請求
將圖片壓縮成base64,隨html或者css一起下載到瀏覽器,不需要額外的請求,這樣就節約了請求.
我們知道圖片在傳輸過程中是流傳輸,如果將圖片轉換成base64,實際上是變大了,並且瀏覽器在decode base64編碼的圖片時需要耗費很多時間的,所以如果我們選擇此種方案的話,最好選擇一些小圖片,不然得不償失,在webpack中可以設置最大多少byte的圖片壓縮成base64

圖四
針對decode base64編碼的圖片比較慢的問題,我們可以選擇使用canvas來加速.當向canvas發出繪畫命令時,瀏覽器直接將指令發到圖形加速器而不需要開發者更多的干預,硬件圖形加速器則以難以執行的運算速度實時繪畫和渲染圖形.因此,我們可以使用canvas來渲染base64編碼后的圖片
具體代碼如下: (代碼出處: http://www.jianshu.com/p/ea7c0ee8aa64)

原作者:瓦斯程序媛
鏈接:https://www.jianshu.com/p/637cba4079ae