vivo悟空活動(dòng)中臺(tái) - 基于 WebP 的圖片高性能加載方案

本文首發(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è)案例:

image

使用 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è)試:

image

下面列出了上述圖片分別使用 WebP 無(wú)損和有損壓縮進(jìn)行測(cè)試的樣本數(shù)據(jù)丽蝎。

(1)WebP無(wú)損壓縮:

execFileSync(cwebp, ['-lossless', filePath, '-o', webpPath]);

結(jié)果統(tǒng)計(jì)

image

(2)WebP有損壓縮(90%壓縮率):

execFileSync(cwebp, ['-q', '90', filePath, '-o', webpPath]);

結(jié)果統(tǒng)計(jì)

image

根據(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ì)

image

(2)Webp 有損壓縮(默認(rèn)值 75%壓縮率):

execFileSync(cwebp, ['-q', '75', filePath, '-o', webpPath]);

結(jié)果統(tǒng)計(jì)

image

為什么要拿 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í)行輸出信息:

image

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)]

  1. node 執(zhí)行 cwebp 指令對(duì)圖片文件進(jìn)行轉(zhuǎn)碼;

  2. 當(dāng)轉(zhuǎn)碼后的圖片體積大于源文件時(shí)籽暇,在 WebP 圖片的文件名后追加“nwebp”字符串標(biāo)記温治,以便前端識(shí)別;

  3. 將編碼后的 WebP 文件和源文件一同上傳至文件服務(wù)器戒悠,并拿到返回的 URL熬荆;

  4. 將圖片名稱、存儲(chǔ)資源路徑等存儲(chǔ)至素材中心服務(wù)數(shù)據(jù)庫(kù)中绸狐;

  5. 存儲(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):

image

為了保證悟空中臺(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)性能欠佳:

image

該方案下 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í),瀏覽到下述說明:

image

webp_js 還有一個(gè)WebAssembly版本凤粗。

(2)使用WebAssembly提升解碼性能

WebAssembly 作為 Web 標(biāo)準(zhǔn)酥泛,在各個(gè)瀏覽器均有較好的支持今豆,兼容性遠(yuǎn)強(qiáng)于WebP:

image

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é)果如下:

image

由以上測(cè)試基本可以得出:

  • 當(dāng) WebP 素材較小時(shí),wasm 解碼相相對(duì)于純 js 解碼燎竖,可以節(jié)省接近一半時(shí)間璃弄;

  • 當(dāng) WebP 素材較大時(shí),wasm 方案可以使解碼速度提升超過 100%构回,且隨著素材增大夏块,提升越明顯。

有了 WebAssembly 的加持纤掸,我們將原有圖片加載流程進(jìn)行了如下圖所示升級(jí):

image

以 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 指令(加載圖片原文件):

image

2托猩、頁(yè)面元添加 v-webp 指令(前端解碼WebP):

image

可以看出在不支持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):

  1. 壓縮格式選擇
  2. 壓縮形式和壓縮率選取
  3. 前端指令集成
  4. 提升兼容性

等一系列手段,探索出一套基于 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)】系列往期精彩文章:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市展东,隨后出現(xiàn)的幾起案子赔硫,更是在濱河造成了極大的恐慌,老刑警劉巖盐肃,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爪膊,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡砸王,警方通過查閱死者的電腦和手機(jī)推盛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谦铃,“玉大人耘成,你說我怎么就攤上這事【匀颍” “怎么了瘪菌?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嘹朗。 經(jīng)常有香客問我师妙,道長(zhǎng),這世上最難降的妖魔是什么骡显? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任疆栏,我火速辦了婚禮曾掂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘壁顶。我一直安慰自己珠洗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布若专。 她就那樣靜靜地躺著许蓖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪调衰。 梳的紋絲不亂的頭發(fā)上膊爪,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音嚎莉,去河邊找鬼米酬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛趋箩,可吹牛的內(nèi)容都是我干的赃额。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼叫确,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼跳芳!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起竹勉,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤飞盆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后次乓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吓歇,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年檬输,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了照瘾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丧慈,死狀恐怖析命,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情逃默,我是刑警寧澤鹃愤,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站完域,受9級(jí)特大地震影響软吐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吟税,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一凹耙、第九天 我趴在偏房一處隱蔽的房頂上張望姿现。 院中可真熱鬧,春花似錦肖抱、人聲如沸备典。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)提佣。三九已至,卻和暖如春荤崇,著一層夾襖步出監(jiān)牢的瞬間拌屏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工术荤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留倚喂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓瓣戚,卻偏偏與公主長(zhǎng)得像务唐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子带兜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容