本文首發(fā)于 vivo互聯(lián)網(wǎng)技術(shù) 微信公眾號(hào)
鏈接:https://mp.weixin.qq.com/s/rSpWorfNTajtqq_pd7H-nw
作者:悟空中臺(tái)研發(fā)團(tuán)隊(duì)
一体谒、背景
移動(dòng)端網(wǎng)頁(yè)的加載速度對(duì)用戶體驗(yàn)極為重要坑雅,是影響頁(yè)面轉(zhuǎn)化率的關(guān)鍵因素读规,H5 活動(dòng)頁(yè)往往使用大量的圖片素材來(lái)豐富活動(dòng)效果谦疾,素材加載的快慢會(huì)對(duì)用戶感知造成重要的影響已维。
在《悟空活動(dòng)中臺(tái) - H5 活動(dòng)加載優(yōu)化》一文中我們提到過圖片壓縮也是提升悟空中臺(tái)產(chǎn)出 H5 頁(yè)面加載性能的重要手段之一俩垃,對(duì)本篇將從技術(shù)選型吗购、架構(gòu)設(shè)計(jì)到方案落地,全方位的呈現(xiàn)悟空活動(dòng)中臺(tái)基于 WebP 的圖片高性能加載方案遣臼。
為什么要做圖片加載性能優(yōu)化?
包含了大量圖片素材的 H5 頁(yè)面铐料,呈現(xiàn)給用戶之前定铜,至少要等待首屏加載完成改基;要提升加載速度繁疤,一方面請(qǐng)求的響應(yīng)速度要足夠快,另一方面要盡量減小傳輸?shù)臄?shù)據(jù)量秕狰。
二稠腊、方案選型
1、演進(jìn)
原始做法是:拿到圖片文件后鸣哀,使用圖片壓縮工具進(jìn)行壓縮麻养,頁(yè)面再引入壓縮后的小體積文件;
該方案存在嚴(yán)重的問題:效率低下——需要開發(fā)者或者設(shè)計(jì)師針對(duì)每張素材圖進(jìn)行手動(dòng)壓縮诺舔、肉眼審核質(zhì)量、壓縮得到的文件手動(dòng)上傳备畦。
我們從高清晰度低飒、高壓縮比、小體積的訴求出發(fā)懂盐,最終選擇了使用WebP作為首選圖片文件格式褥赊。
2、為什么是WebP
WebP 是 Google 推出的一種同時(shí)提供了有損壓縮與無(wú)損壓縮(可逆壓縮)的圖片文件格式莉恼。派生自影像編碼格式 VP8拌喉,被認(rèn)為是 WebM 多媒體格式的姊妹項(xiàng)目速那,是由 Google 在購(gòu)買 On2 Technologies 后發(fā)展出來(lái),以 BSD 授權(quán)條款發(fā)布尿背。
WebP 的優(yōu)勢(shì)體現(xiàn)在它具有更優(yōu)的圖像數(shù)據(jù)壓縮算法端仰,能帶來(lái)更小的圖片體積,而且擁有肉眼識(shí)別無(wú)差異的圖像質(zhì)量田藐;同時(shí)具備了無(wú)損和有損的壓縮模式荔烧、Alpha 透明以及動(dòng)畫的特性,在 JPEG 和 PNG 上的轉(zhuǎn)化效果都相當(dāng)優(yōu)秀汽久、穩(wěn)定和統(tǒng)一鹤竭。
相比于其他相同大小、不同格式的壓縮圖像景醇,WebP 格式的圖片擁有更小的體積以及更高的質(zhì)量臀稚,優(yōu)勢(shì)十分明顯。
下圖是一些實(shí)測(cè)案例:
使用 WebP 對(duì)圖片進(jìn)行有損壓縮三痰,在默認(rèn)配置75%的壓縮比下吧寺,可以將 PNG 圖片大小壓縮至原圖體積的13%左右,JPG 圖片甚至可以壓縮至原圖體積的10%左右(可參考官方測(cè)試頁(yè)面)酒觅,實(shí)際效果顯著撮执。
三、圖片服務(wù)
1舷丹、素材服務(wù)
悟空中臺(tái)的素材服務(wù)架構(gòu)如下圖所示抒钱,在 node server 節(jié)點(diǎn)中,我們集成了圖片轉(zhuǎn) WebP 以及轉(zhuǎn)碼后文件存儲(chǔ)的服務(wù)颜凯。
[圖片上傳失敗...(image-b1cedd-1597632523493)]
2谋币、圖片壓縮
圖片壓縮服務(wù)實(shí)現(xiàn)了將用戶上傳的圖片數(shù)據(jù),進(jìn)行格式校驗(yàn)症概、WebP 格式轉(zhuǎn)碼蕾额、上傳文件服務(wù)器以及存儲(chǔ)的過程。
使用 cwebp 進(jìn)行壓縮
cwebp 是 Google 官方提供的用于將 PNG彼城、JPEG诅蝶、TIFF 或原始 Y'CbCr 格式的文件壓縮轉(zhuǎn)換為 WebP 格式的命令行編碼工具(安裝方法請(qǐng)參考官網(wǎng)安裝說明)。
使用方法如下:
cwebp [options] input_file -o output_file.webp
其中 options 是壓縮參數(shù)配置募壕,包含是否啟用無(wú)損壓縮-lossless调炬,壓縮系數(shù)-q(0~100) 等,如使用 80 的壓縮系數(shù)對(duì)目標(biāo)文件進(jìn)行有損壓縮:
cwebp -q 80 image.png -o image.webp
Node 服務(wù)使用 cwebp-bin
cwebp-bin模塊提供了 Node.js 使用 cwebp 能力進(jìn)行圖片壓縮轉(zhuǎn)碼的接口舱馅,我們的圖片壓縮服務(wù)引入該模塊模塊實(shí)現(xiàn)常見格式圖片到WebP的轉(zhuǎn)碼缰泡。
(1)工具安裝
首先需要在服務(wù)器執(zhí)行下述指令以安裝模塊內(nèi)部集成的 WebP 工具程序(libwebp-x.x.tar.gz):
npm install --global cwebp-bin
(2)網(wǎng)絡(luò)優(yōu)化
在實(shí)際使用時(shí),打包上線時(shí)會(huì)偶發(fā)該安裝包資源請(qǐng)求失敗的問題代嗤;為了安裝過程的順利進(jìn)行棘钞,悟空中臺(tái)的開發(fā)者將該安裝包的url由原github下載地址改為了更加穩(wěn)定的google官方下載地址:
// node_modules/@vivo/cwebp-bin/lib/install.js - line 14
binBuild.file(path.resolve(__dirname, '../vendor/source/libwebp-1.1.0.tar.gz'), [
`./configure --disable-shared --prefix="${bin.dest()}" --bindir="${bin.dest()}"`,
'make && make install'
]).then(() => {
...
}).catch(error => {
...
});
改為
// node_modules/@vivo/cwebp-bin/lib/install.js - line 14
var cfg = [
'./configure --disable-shared --prefix="' + bin.dest() + '"',
'--bindir="' + bin.dest() + '"'
].join(' ');
var builder = new BinBuild()
.src('http://downloads.webmproject.org/releases/webp/libwebp-0.5.1.tar.gz')
.cmd(cfg)
.cmd('make && make install');
return builder.run(function (err) {
...
});
(3)圖片壓縮
圖片壓縮服務(wù)中使用以下代碼調(diào)用 cwebp 工具進(jìn)行原圖到 WebP 的轉(zhuǎn)碼:
const {execFileSync} = require('child_process');
const cwebp = require('cwebp-bin');
execFileSync(cwebp, ['input.png', '-o', 'output.webp'])
壓縮形式選取
通過上文我們了解到缠借,WebP支持有損壓縮和無(wú)損壓縮兩種形式,下面我們將針對(duì)性的測(cè)試兩種壓縮形式的差異并選出適合的方案宜猜。
之所以要對(duì)比有損與無(wú)損的區(qū)別泼返,主要是考慮到時(shí)間上的效率和空間上的節(jié)約。如果在損失 20~30% 的精度后宝恶,用戶的肉眼上難以區(qū)分符隙,那么這個(gè)精度的損失就是有意義的,因?yàn)橄鄬?duì)于無(wú)損壓縮垫毙,有損壓縮帶來(lái)的體積的縮小以及壓縮時(shí)的效率霹疫,都比無(wú)損壓縮更適合用于企業(yè)的生產(chǎn)模式下。
我們選取了特點(diǎn)分別為色彩單一综芥、色彩較為豐富和色彩極為豐富的三張圖片進(jìn)行測(cè)試:
下面列出了上述圖片分別使用 WebP 無(wú)損和有損壓縮進(jìn)行測(cè)試的樣本數(shù)據(jù)丽蝎。
(1)WebP無(wú)損壓縮:
execFileSync(cwebp, ['-lossless', filePath, '-o', webpPath]);
結(jié)果統(tǒng)計(jì)
(2)WebP有損壓縮(90%壓縮率):
execFileSync(cwebp, ['-q', '90', filePath, '-o', webpPath]);
結(jié)果統(tǒng)計(jì)
根據(jù)上面兩份測(cè)試數(shù)據(jù)可以得出,對(duì)于同一張圖片:
從壓縮比角度來(lái)看膀藐,90%壓縮率的有損壓縮得到的圖片體積小于無(wú)損壓縮產(chǎn)出圖片體積的20%屠阻。
從壓縮時(shí)間角度來(lái)看,90%壓縮率的有損壓縮耗費(fèi)的時(shí)間是無(wú)損壓縮20%以內(nèi)额各。
對(duì)于不同圖片国觉,色彩越豐富,壓縮花費(fèi)的時(shí)間越長(zhǎng)虾啦,壓縮比越小麻诀;甚至?xí)霈F(xiàn)壓縮的到的圖片體積超過原圖的情況(具體原因見下文)。
通過以上測(cè)試數(shù)據(jù)反映的結(jié)果來(lái)看傲醉,有損壓縮的優(yōu)勢(shì)更大蝇闭。
壓縮率選取
使用 WebP 有損壓縮來(lái)進(jìn)行圖片的壓縮,就不得不考慮接下來(lái)的問題:WebP 壓縮比設(shè)置為多少才是最佳實(shí)踐硬毕?
同樣的呻引,我們對(duì)上述圖片進(jìn)行了以下抽樣數(shù)據(jù)對(duì)比:
(1)Webp 有損壓縮(90%壓縮率):
execFileSync(cwebp, ['-q', '90', filePath, '-o', webpPath]);
結(jié)果統(tǒng)計(jì)
(2)Webp 有損壓縮(默認(rèn)值 75%壓縮率):
execFileSync(cwebp, ['-q', '75', filePath, '-o', webpPath]);
結(jié)果統(tǒng)計(jì)
為什么要拿 75% 壓縮率來(lái)做對(duì)比?原因是 cwebp 有損壓縮的默認(rèn)壓縮率是 75%吐咳,這個(gè)比例也是通常情況下官方推薦的逻悠。
但是在實(shí)際業(yè)務(wù)場(chǎng)景下,75% 的壓縮比例并不能滿足產(chǎn)品需求韭脊。比如說一張圖片經(jīng)過壓縮后同時(shí)在移動(dòng)端和 PC 端使用蹂风;或圖片的色彩空間尤其復(fù)雜等等這些情況,再經(jīng)過 75% 的有損壓縮乾蓬,我們觀察到色彩對(duì)比度明顯的圖片局部有模糊的情況。
經(jīng)過與設(shè)計(jì)師同學(xué)一起反復(fù)的測(cè)試實(shí)驗(yàn)慎恒,我們使用了 90% 的壓縮率來(lái)代替默認(rèn)的 75% 任内。此時(shí)轉(zhuǎn)換后的圖片與原圖片結(jié)構(gòu)化差異值SSIM不會(huì)小于 0.88 撵渡,視覺效果上用戶基本發(fā)現(xiàn)不了圖片已經(jīng)進(jìn)行了壓縮。
結(jié)構(gòu)相似性指標(biāo)(英文:structural similarity index死嗦,SSIM index)是一種用以衡量?jī)蓮垟?shù)位影像相似程度的指標(biāo)趋距。當(dāng)兩張影像其中一張為無(wú)失真影像,另一張為失真后的影像越除,二者的結(jié)構(gòu)相似性可以看成是失真影像的影像品質(zhì)衡量指標(biāo)节腐。相較于傳統(tǒng)所使用的影像品質(zhì)衡量指標(biāo),像是峰值信噪比(英語(yǔ):PSNR)摘盆,結(jié)構(gòu)相似性在影像品質(zhì)的衡量上更能符合人眼對(duì)影像品質(zhì)的判斷翼雀。
關(guān)于 WebP 壓縮質(zhì)量與 SSIM 的比例關(guān)系,請(qǐng)參考 Google 官方說明WebP Compression Study孩擂。
我們可以通過在 cwebp 的執(zhí)行命令中加入-print_ssim選項(xiàng)狼渊,令壓縮結(jié)果中呈現(xiàn) SSIM 信息:
await execFileSync(cwebp, ['-print_ssim', '-q', '90', filePath, '-o', webpPath])
執(zhí)行輸出信息:
WebP 壓縮后反而比原圖更大?
我們?cè)跍y(cè)試的過程中還觀察到有一些圖片轉(zhuǎn)換為 WebP 格式后得到文件體積比原圖更大类垦。經(jīng)過查閱Google 官方文檔狈邑,得出是由于格式差異以及轉(zhuǎn)碼算法導(dǎo)致的:
WebP 的壓縮率設(shè)置超過 75%時(shí),在遇到在遇到一些特殊編碼的圖片時(shí)蚤认,會(huì)調(diào)整壓縮時(shí)的算法米苹,如:
- 當(dāng)圖片的編碼類型處理后發(fā)生變化時(shí),壓縮后的圖片體積就會(huì)變大砰琢。比如說編碼類型從索引類型變化到了真彩類型蘸嘶,這種場(chǎng)景下壓縮時(shí)需要處理的像素點(diǎn)數(shù)就會(huì)大三倍,所以壓縮圖片的體積就大了氯析。
- 當(dāng)原圖片中重復(fù)的顏色數(shù)目比較多時(shí)亏较,Webp 有損壓縮時(shí)會(huì)根據(jù)原像素值計(jì)算出新的像素值,而壓縮時(shí)重點(diǎn)會(huì)處理的就是重復(fù)的顏色數(shù)目掩缓,所以壓縮后的圖片體積自然就大了雪情。
- 當(dāng)原圖中包含透明管道時(shí),由于 Webp 并不支持灰度圖帶上透明通道這種類型你辣,帶上透明通道就將格式固定成了 RGBA 格式巡通。因此導(dǎo)致了要保存的數(shù)據(jù)變大。
面對(duì)這個(gè)問題舍哄,我們與設(shè)計(jì)和產(chǎn)品同事共同制定了相應(yīng)策略:如果壓縮后的文件體積大于原圖宴凉,則使用原圖。
3表悬、服務(wù)流程
在確定合適的壓縮比例和壓縮方案后弥锄,就可以對(duì)圖片壓縮服務(wù)進(jìn)行整體設(shè)計(jì),流程如下:
[圖片上傳失敗...(image-6d4a1b-1597632523493)]
node 執(zhí)行 cwebp 指令對(duì)圖片文件進(jìn)行轉(zhuǎn)碼;
當(dāng)轉(zhuǎn)碼后的圖片體積大于源文件時(shí)籽暇,在 WebP 圖片的文件名后追加“nwebp”字符串標(biāo)記温治,以便前端識(shí)別;
將編碼后的 WebP 文件和源文件一同上傳至文件服務(wù)器戒悠,并拿到返回的 URL熬荆;
將圖片名稱、存儲(chǔ)資源路徑等存儲(chǔ)至素材中心服務(wù)數(shù)據(jù)庫(kù)中绸狐;
存儲(chǔ)完成后將圖片名稱卤恳、存儲(chǔ)資源路徑等通過接口返回前端展示。
四寒矿、頁(yè)面邏輯
1突琳、優(yōu)先使用WebP
前端頁(yè)面策略是當(dāng)網(wǎng)頁(yè)運(yùn)行在支持 WebP 格式的宿主環(huán)境(如 Chrome、Android Webview 等)中時(shí)劫窒,優(yōu)先使用 WebP 圖片資源本今,在不支持的宿主環(huán)境中,使用原始圖片資源主巍。
(1)判斷宿主環(huán)境是否支持WebP
頁(yè)面首先需要判斷當(dāng)前宿主環(huán)境是否支持 WebP :
const supportWebP = (function () {
var canvas = typeof document === 'object' ? document.createElement('canvas') : {}
canvas.width = canvas.height = 1
return canvas.toDataURL ? canvas.toDataURL('image/webp').indexOf('image/webp') === 5 : false
})()
(2)素材加載
前面講解了后臺(tái)圖片壓縮和存儲(chǔ)服務(wù)的設(shè)計(jì)冠息,接下來(lái)我們來(lái)一起了解一下前端邏輯上是如何加載 WebP 圖片的。其流程如下圖所示:
[圖片上傳失敗...(image-69c15a-1597632523493)]
(3)使用指令獲取圖片url
獲取圖片 url 的方式有多種孕索,我們的需求是在圖片資源加載前獲取真實(shí)的圖片 url逛艰,并對(duì)其進(jìn)行處理,而 Vue 提供的自定義指令可以幫助我們以侵入性極小的形式的拿到目標(biāo)元素的相關(guān)信息搞旭。
這里我們使用bind指令進(jìn)行一次性的初始化設(shè)置散怖,在當(dāng)指令第一次綁定到元素時(shí)調(diào)用,通過獲取到元素關(guān)聯(lián)的素材的 url肄渗,以 img 元素為例:
bind: function (el, binding) {
if (el.tagName.toLowerCase() === 'img' && el.src && el.src.indexOf('data:image') === -1 && supportWebP) {
// 通過 src 屬性獲取 img 元素關(guān)聯(lián)的圖片地址
var _src = el.src
// ... 對(duì)img的后續(xù)處理
}
}
2镇眷、****處理圖片 url
首先判斷當(dāng)前 url 中是否有素材上傳時(shí)標(biāo)記的“nwebp”字樣,如果有則說明該圖片轉(zhuǎn)為 WebP 格式后體積反而大于原圖翎嫡,此時(shí)無(wú)需使用 WebP 素材替換原有素材欠动;否則,則加載體積更小的 WebP 文件代替原素材文件惑申。
然后判斷當(dāng)前運(yùn)行環(huán)境是否支持 WebP 格式圖片的渲染具伍,如果支持,則加載 WebP 素材資源圈驼,否則使用原文件鏈接人芽。
(1)img 元素處理
我們?cè)?img 標(biāo)簽上添加上文定義的v-webp指令如下:
<img src="https://someurl" v-webp />
在 img 元素的 create 階段, v-webp 指令被 bind 并執(zhí)行定義好的 hook绩脆。
在 hook 中萤厅,我們對(duì)于 img 元素我們可以根據(jù) el.src 獲取到元素關(guān)聯(lián)素材的 url橄抹,當(dāng)判斷需要采用 WebP 格式文件時(shí),在原素材 url 后拼接.webp祈坠,從而使得對(duì)應(yīng)圖片元素加載的是 WebP 編碼后的素材:
// ... 對(duì)img的后續(xù)處理
// 帶有 nwebp 標(biāo)記的圖片不做轉(zhuǎn)換
if (_src.indexOf('nwebp') > -1) {
return
}
let webpSrc = ''
if (_src.indexOf('.webp') > -1) {
webpSrc = _src
} else {
webpSrc = _src + '.webp'
}
el.src = webpSrc
el.onerror = function() {
// WebP加載失敗則回退至源文件
el.src = _src
}
對(duì)于運(yùn)行環(huán)境不支持 WebP 加載的情況害碾,則無(wú)需做任何處理,直接加載原圖即可:
if (!supportWebP) {
return
}
(2)background-image 處理
對(duì)于 img 之外的元素赦拘,我們?cè)?v-webp 指令中傳入要作為 backgroundImage 屬性值的 url:
<div v-webp="https://someurl"></div>
在 hook 中,根據(jù) binding.value 獲取指令的綁定值芬沉,即圖片 url躺同,當(dāng)判斷需要采用 WebP 格式文件時(shí),在原素材 url 后拼接“.webp” 構(gòu)造頁(yè)面用 url丸逸,否則直接使用原圖 url蹋艺,然后為該 DOM 元素設(shè)置內(nèi)聯(lián)的 backgroundImage style 即可:
if (supportWebP) {
el.style.backgroundImage = 'url("' + webpSrc + '")'
} else {
el.style.backgroundImage = 'url("' + binding.value + '")'
}
五、提升兼容性
WebP 格式雖然優(yōu)點(diǎn)眾多黄刚,但是有一個(gè)嚴(yán)重的問題——兼容性并不理想捎谨。下面我們將從 “擴(kuò)展WebP兼容范圍” 的訴求出發(fā),探索前端解碼WebP文件的可行性憔维。
1涛救、WebP的兼容性問題
WebP 格式雖然存在壓縮率高、體積小等優(yōu)勢(shì)业扒,但是其自身并不是通用瀏覽器圖片格式規(guī)范检吆,像 Safari 和 FireFox 等宿主環(huán)境均沒有很好的支持該格式(參考自can i use):
為了保證悟空中臺(tái)產(chǎn)出的專題頁(yè)在更多的瀏覽器中能夠以更快的速度加載、渲染程储,我們又向前走了一步蹭沛,對(duì) WebP 格式的純前端解碼做出了下面的探索。
2章鲤、在頁(yè)面解碼
核心理念是將 WebP 圖片作為傳輸介質(zhì)摊灭,保證了頁(yè)面圖片數(shù)據(jù)的下載速度;在拿到 WebP 圖片后败徊,對(duì)于不支持的宿主環(huán)境帚呼,將 WebP 圖片進(jìn)行解碼成通用的Base64格式進(jìn)行渲染。
(1)使用JS解碼
純前端是否可以實(shí)現(xiàn) WebP 格式到 Base64 格式的解碼呢集嵌?Google 官方團(tuán)隊(duì)提供了 js 解碼 WebP 的庫(kù)——libwebp.js萝挤;但是我們隨機(jī)挑選一些 WebP 圖片實(shí)際測(cè)試下來(lái)發(fā)現(xiàn)性能欠佳:
該方案下 WebP 圖片實(shí)際的加載時(shí)間為網(wǎng)絡(luò)數(shù)據(jù)傳輸用時(shí) + 解碼用時(shí),面對(duì)性能要求較高的場(chǎng)景根欧,WebP 的加載速度真要受限于 JS 不擅長(zhǎng)的編解碼運(yùn)算能力了么怜珍?當(dāng)我們?cè)俅窝芯?a target="_blank">libwebp的資料時(shí),瀏覽到下述說明:
webp_js 還有一個(gè)WebAssembly版本凤粗。
(2)使用WebAssembly提升解碼性能
WebAssembly 作為 Web 標(biāo)準(zhǔn)酥泛,在各個(gè)瀏覽器均有較好的支持今豆,兼容性遠(yuǎn)強(qiáng)于WebP:
WebAssembly 可以作為 C/C++/Rust 等語(yǔ)言的編譯目標(biāo)在瀏覽器環(huán)境中以接近原生的速度運(yùn)行,計(jì)算性能要遠(yuǎn)遠(yuǎn)優(yōu)于 JavaScript柔袁。
WebAssembly的工作流程如下(圖片來(lái)自MDN):
[圖片上傳失敗...(image-c38669-1597632523494)]
其中膠水JS(JS“glue”code)的作用是提供 JS 調(diào)用 wasm 能力的接口呆躲。
編譯并測(cè)試 libwebp
我們將 libwebp 編譯成 wasm 文件供 JavaScript 調(diào)用,提供高速解碼 WebP 的能力捶索。具體的編譯過程可以參照 libwebp/webp_js 的編譯說明插掂,編譯環(huán)境建議使用linux/unix,其余步驟此處不再贅述腥例。
編譯后我們得到了 wasm 文件(gzip壓縮后體積51kb)和膠水 js(gzip壓縮后體積44kb) 辅甥,然后使用上述同樣的素材進(jìn)行性能測(cè)試結(jié)果如下:
由以上測(cè)試基本可以得出:
當(dāng) WebP 素材較小時(shí),wasm 解碼相相對(duì)于純 js 解碼燎竖,可以節(jié)省接近一半時(shí)間璃弄;
當(dāng) WebP 素材較大時(shí),wasm 方案可以使解碼速度提升超過 100%构回,且隨著素材增大夏块,提升越明顯。
有了 WebAssembly 的加持纤掸,我們將原有圖片加載流程進(jìn)行了如下圖所示升級(jí):
以 img 元素為例脐供,代碼處理邏輯如下:
// 如果當(dāng)前瀏覽器環(huán)境不支持WebP格式,則使用wasm將WebP文件解碼為Base64
if (supportsWebP) {
el.src = webpSrc
} else {
// 使用fetch請(qǐng)求拿到WebP文件
const res = await fetch(webpSrc)
// 設(shè)置拿到的文件的編碼茁肠,以符合wasm解碼的入?yún)l件
const webp_data_buffer = await res.arrayBuffer()
const webp_data = new Uint8Array(webp_data_buffer)
// 調(diào)用碎wasm編譯生成的膠水js的解碼方法患民,將解碼后的Base64值作為圖片素材的url使用
el.src = wasmDecode(webp_data)
}
3、效果對(duì)比
我們構(gòu)造了一個(gè)圖片素材較多的H5專題在 Safari 中測(cè)試垦梆,效果如下(為了更好的體現(xiàn)加載過程匹颤,下放動(dòng)圖相對(duì)實(shí)際速度均 放慢了3倍 ):
1、頁(yè)面元素不添加 v-webp 指令(加載圖片原文件):
2托猩、頁(yè)面元添加 v-webp 指令(前端解碼WebP):
可以看出在不支持WebP的宿主中印蓖,使用了 v-webp 指令后,頁(yè)面的響應(yīng)速度(白屏?xí)r間短)和圖片渲染速度均有較為明顯的提升京腥;至此赦肃,我們已經(jīng)設(shè)計(jì)并實(shí)現(xiàn)了一套相對(duì)完善的圖片素材加載性能優(yōu)化方案。
六公浪、小結(jié)
悟空活動(dòng)中臺(tái)從提升 H5 頁(yè)面圖片加載性能的訴求出發(fā)他宛,歷經(jīng):
- 壓縮格式選擇
- 壓縮形式和壓縮率選取
- 前端指令集成
- 提升兼容性
等一系列手段,探索出一套基于 WebP 的圖片高性能加載方案欠气,更好的賦能了 H5 活動(dòng)的開發(fā)和運(yùn)營(yíng)厅各。悟空中臺(tái)開發(fā)團(tuán)隊(duì)將永不止步,持續(xù)研究和思考预柒,為大家?guī)?lái)更多的實(shí)戰(zhàn)技巧队塘,感謝您的閱讀袁梗。
【悟空活動(dòng)中臺(tái)】系列往期精彩文章:
《揭秘 vivo 如何打造千萬(wàn)級(jí) DAU 活動(dòng)中臺(tái) - 啟航篇》 主要為大家講述 vivo 活動(dòng)中臺(tái)的能力與創(chuàng)新。
《悟空活動(dòng)中臺(tái) - 微組件狀態(tài)管理(上)》介紹了活動(dòng)頁(yè)內(nèi) RSC 組件之間的狀態(tài)管理和背后的設(shè)計(jì)思路憔古。
《悟空活動(dòng)中臺(tái) - 微組件狀態(tài)管理(下)》探索平臺(tái)和跨沙箱環(huán)境下的微組件狀態(tài)管理遮怜。
《vivo 悟空活動(dòng)中臺(tái)-基于行為預(yù)設(shè)的動(dòng)態(tài)布局方案》本文以“滿屏”場(chǎng)景下的頁(yè)面布局思考為切入點(diǎn),以微組件為元素單元鸿市,提供了一種新的布局方案設(shè)計(jì)思路——基于行為預(yù)設(shè)的動(dòng)態(tài)布局方案锯梁,并詳細(xì)的分享了設(shè)計(jì)目的及具體實(shí)現(xiàn)方案。
《vivo悟空活動(dòng)中臺(tái) - 微組件多端探索》是基于自助多端擴(kuò)展焰情,也就意味著多端 微 組件選擇越豐富涝桅,內(nèi)容越通用,玩法越多樣烙样,產(chǎn)品價(jià)值也會(huì)越高。
《悟空活動(dòng)中臺(tái) - H5 活動(dòng)加載優(yōu)化》從提高資源請(qǐng)求速度蕊肥,資源壓縮谒获、緩存、渲染等多種角度出發(fā)壁却,尋找悟空活動(dòng)專題加載優(yōu)化方案批狱。