在 CRA 中使用 webp 图片提升加载性能
2020/8/27 14:33:40
本文主要是介绍在 CRA 中使用 webp 图片提升加载性能,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
webp 是 google 提倡的一种新的 image 格式,意在为 web 提供体积更小的图片格式。通常情况下,无损压缩可以减小 25%-35%
的体积(有例外情况,反而会增大体积,但是是因为转换图片格式不兼容引起的),有损压缩最大可以节省大约 75%-90%
的体积。
兼容性
使用新的浏览器特性,首先应该考虑兼容性问题,它的兼容性如下图:
可以发现,除了 ie 和 safari 之外,基本都支持了该格式,而且 safari 14 也即将支持该格式,到目前为止,全球浏览器的 ~75.9%
(粗略统计) 份额的浏览器均可使用该功能。
如何判定兼容性
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
字符串会包含特定的关键字(这种手段也可以用来检测浏览器是否支持别的格式)。
js 解决方案
由于可以通过 js 来判定浏览器是否支持该特性,所以问题也很好解决,只需要做一个逻辑判定即可,比如:
{ isWebpSupported() ? <img src={require('./path/to/img.webp')} /> : <img src={require('./path/to/img.png')} /> }
html 解决方案
另一种解决方案是,我们把图片的选择逻辑,委托给浏览器,恰好 html 规范中,有一个 picture
标签,这个标签配合 source
和 img
标签,可以完美地解决这个问题,如下:
<picture> <source srcset="logo.webp" type="image/webp"> <img src="logo.png" alt="logo"> </picture>
浏览器当遇到这段代码时,会自动匹配 source
中的备选多媒体资源,尽可能地使用最恰当的那一个资源。
这里可能有一个问题,就是 picture
标签的兼容性问题,如下:
可以发现除了 ie
和 opera mini
均支持,由于 ie
本身也不支持 webp
格式,所以我们可以忽略它。
在 create-react-app 中使用它
CRA
本身已经支持 webp
格式的图片,但是图片需要是静态的,即你首先应该有一个 webp
图片,如果是对于未来的图片,那没什么问题,但对于之前已经使用的图片,就必须手动一张一张转换,有点繁琐,有没有解决方案能够自动将之前的 jpg
或者 png
的图片转换为 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
方法。
该插件的默认的生成规则是,xxx.png
在打包时,同时会生成一个 xxx.webp
的副本,当然这个规则也可以在插件的配置中进行更改。
最后只需要把 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 中的加载情况:
总结
我示例中的图片,源文件大小为 184kb
,webp
副本文件大小为 22kb
,如下图:
由于我这里是有损压缩,所以体积减少比例大概是 ~88%
,无损压缩的话,会比这个低一些。
参考
https://developers.google.com/speed/webp/
https://github.com/DonRai/react-image-webp
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture
这篇关于在 CRA 中使用 webp 图片提升加载性能的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-30毕设私活神器
- 2024-05-30html
- 2024-05-09一定要避坑:关于微信H5分享,温馨提示你不要再踩坑了!!!
- 2024-05-09本地项目放到公网访问!炒鸡煎蛋!
- 2024-04-07金融企业区域集中库的设计构想和测试验证
- 2024-03-11前端CSS的工程化——掌握Sass这四大特性就够了
- 2024-02-21h5关联css样式(html怎么和css关联)-icode9专业技术文章分享
- 2024-02-07Firefox禁止远程字体加速网页加载及图标字体补充安装
- 2024-02-07一个菜鸡前端的3年总结-「2023」
- 2024-01-18最火前端Web组态软件(可视化)