背景:設計師大賽,設計師上傳圖片限制小於10M,這個時候作品大多為數M,展示作品列表每次加載原圖會消耗大量帶寬,圖片完整加載非常耗時。所以需要優化加載速度
方案:1.如果是本地靜態資源圖片的話,可以用webpack打包工具壓縮圖片或者壓縮圖片(
https://tinypng.com/
)網站進行壓縮;
2.如果是網絡圖片的話,則可以使用webp圖片格式,圖片體積至少縮小了40%以上,缺點是部分瀏覽器不兼容;
3.也可以懶加載或者預加載,一般適用於瀑布流滾動的場景,不過我的場景是分頁加載的,所以性價比較低。
難點:1.因為使用的是vue項目的框架,每次組件中復用起來單獨寫比較麻煩,所以封裝成全局指令,方便使用;使用webp的過程中,發現有些webp格式圖片不能正常加載,所以采取加載失敗之后的兼容(即使用原圖地址替換)
//判斷是否支持webp格式圖片 支持 返回true 不支持 返回false function check_support_webp() { return document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0; } Vue.prototype.check_support_webp = check_support_webp() //全局注冊自定義指令,用於判斷當前圖片是否能夠加載成功,可以加載成功則賦值為img的src屬性,否則使用默認圖片 Vue.directive('real-img', async function (el, binding) {//指令名稱為:real-img let imgURL = binding.value;//獲取圖片地址 if (imgURL) { let exist = await imageIsExist(imgURL); if (exist) { el.setAttribute('src', imgURL); } else { el.setAttribute('src', imgURL.split('.w0-h332-q100.webp')[0]); } } }) /** * 檢測圖片是否存在 * @param url */ let imageIsExist = function(url) { return new Promise((resolve) => { var img = new Image(); img.onload = function () { if (this.complete == true){ resolve(true); img = null; } } img.onerror = function () { resolve(false); img = null; } img.src = url; }) }
使用方式:
<img v-real-img="item.pic + (check_support_webp ? '.w0-h332-q100.webp' : '')"
:src="item.pic + (check_support_webp ? '.w0-h332-q100.webp' : '')" alt="">
