picturectrl控件中加载图片并显示_在 CRA 中使用 webp 图片提升加载性能
webp 是 google 提倡的一種新的 image 格式,意在為 web 提供體積更小的圖片格式。通常情況下,無損壓縮可以減小 25%-35% 的體積(有例外情況,反而會增大體積,但是是因為轉(zhuǎn)換圖片格式不兼容引起的),有損壓縮最大可以節(jié)省大約 75%-90% 的體積。
兼容性
使用新的瀏覽器特性,首先應(yīng)該考慮兼容性問題,它的兼容性如下圖:
可以發(fā)現(xiàn),除了 ie 和 safari 之外,基本都支持了該格式,而且 safari 14 也即將支持該格式,到目前為止,全球瀏覽器的 ~75.9%(粗略統(tǒng)計) 份額的瀏覽器均可使用該功能。
如何判定兼容性
https://github.com/DonRai/react-image-webp/blob/master/modules/utils/index.js核心代碼如下:
const el = document.createElement('canvas') el.toDataURL('image/webp').indexOf('data:image/webp') === 0;如果瀏覽器支持 ?webp? 這種 ?mime-type? 的話,則輸入的 ?base64 字符串會包含特定的關(guān)鍵字(這種手段也可以用來檢測瀏覽器是否支持別的格式)。
js 解決方案
由于可以通過 js 來判定瀏覽器是否支持該特性,所以問題也很好解決,只需要做一個邏輯判定即可,比如:
{ isWebpSupported() ? <img src={require('./path/to/img.webp')} /> : <img src={require('./path/to/img.png')} /> }html 解決方案
另一種解決方案是,我們把圖片的選擇邏輯,委托給瀏覽器,恰好 html 規(guī)范中,有一個 ?picture 標簽,這個標簽配合 ?source 和 ?img 標簽,可以完美地解決這個問題,如下:
<picture> <source srcset="logo.webp" type="image/webp"><img src="logo.png" alt="logo"> </picture>瀏覽器當遇到這段代碼時,會自動匹配 ?source 中的備選多媒體資源,盡可能地使用最恰當?shù)哪且粋€資源。
這里可能有一個問題,就是 ?picture 標簽的兼容性問題,如下:
可以發(fā)現(xiàn)除了 ie 和 opera mini 均支持,由于 ie 本身也不支持 ?webp 格式,所以我們可以忽略它。
在 create-react-app 中使用它
CRA 本身已經(jīng)支持 ?webp 格式的圖片,但是圖片需要是靜態(tài)的,即你首先應(yīng)該有一個 ?webp 圖片,如果是對于未來的圖片,那沒什么問題,但對于之前已經(jīng)使用的圖片,就必須手動一張一張轉(zhuǎn)換,有點繁瑣,有沒有解決方案能夠自動將之前的 ?jpg 或者 ?png 的圖片轉(zhuǎn)換為 ?webp 格式,或者在打包時,同時生成一個 ?webp 格式的副本呢? 答案是有的,可以使用 ?ImageminWebpWebpackPlugin 這個插件來完成這個工作,如下:
new ImageminWebpWebpackPlugin({config: [{test: /.(jpe?g|png)/,options: {quality: 75,},},],overrideExtension: true,detailedLogs: false,silent: false,strict: true,})在 CRA 中,可以通過 ?eject 或者 ?react-app-rewired 來覆蓋 webpack 配置,我這里使用的是 customize-cra 這個庫中的 addWebpackPlugin 方法。
該插件的默認的生成規(guī)則是,xxx.png 在打包時,同時會生成一個 ?xxx.webp 的副本,當然這個規(guī)則也可以在插件的配置中進行更改。
最后只需要把 img 元素簡易封裝一下即可,如下:
const WebpImage: React.FC<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>,HTMLImageElement> > = props => {const { src } = props;const webpSrc = React.useMemo(() => {const nameChunks = src.split('.');nameChunks.pop();nameChunks.push('webp');return nameChunks.join('.');}, [src]);return (<picture><source srcSet={webpSrc} type="image/webp" /><img {...props} /></picture>); };這里的封裝比較簡單,但作為演示夠用了,效果如下:
network 中的加載情況:
總結(jié)
我示例中的圖片,源文件大小為 184kb,webp 副本文件大小為 22kb,如下圖:
由于我這里是有損壓縮,所以體積減少比例大概是 ~88%,無損壓縮的話,會比這個低一些。
參考
https://developers.google.com/speed/webp/https://github.com/DonRai/react-image-webphttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture總結(jié)
以上是生活随笔為你收集整理的picturectrl控件中加载图片并显示_在 CRA 中使用 webp 图片提升加载性能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 3.5.2设计页面_怎么解
- 下一篇: 输入一个正整数求所有素数因子_一个数如果