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 标签的兼容性问题,如下:

可以发现除了 ieopera 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 中的加载情况:

总结

我示例中的图片,源文件大小为 184kbwebp 副本文件大小为 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

picturectrl控件中加载图片并显示_在 CRA 中使用 webp 图片提升加载性能相关推荐

  1. vue base64图片不显示_技巧 | word中插入的图片显示不完整怎么办?

    已经好久没有更新了,都快忘记有这个公众号存在了~ 这几个月发生了很多事情,工作上的任务也迟迟没有减轻,之前保持的日记也已经很久没有写了.但是觉得要是没有什么用什么方式将脑袋中时不时飘过的念头记录下来的 ...

  2. unity中链接字符串和变量显示_理解Unity中的优化(六):字符串和文本

    字符串和文本: 在Unity项目中,处理字符串和文本经常会产生性能问题.在C#中,字符串是不变的.任何对字符串的操作都会重新分配新的字符串,这个代价是非常昂贵的.如果在多重循环中重复地执行字符串连接操 ...

  3. vue上线后图片不显示_解决Vue打包后访问图片/图标不显示的问题

    大家可否遇到过 npm run build打包后,项目在线上运行时,资源文件 (图片.图标)不显示 的问题, 接下来,我给大家分享一下我的解决方案~ 1.检查打包后dist中的css文件 打开此文件后 ...

  4. 怎样把vc6的MSComm控件接受的数据实时的显示在编辑框,并把数据实时惠存txt文件中

    怎样把vc6的MSComm控件接受的数据实时的显示在编辑框,并把数据实时存入txt文件中 我在做一个基于VC6的MSComm控件的电机上位机控制,数据帧格式采用9600bps,8位数据位,奇校验,1位 ...

  5. 当前安全设置禁止运行该页中activeX控件,该页无法正常显示

    运行services查看服务时,当前安全设置禁止运行该页中activeX控件,该页无法正常显示:打开一个project文件时,也显示 当前安全设置禁止运行该页中activeX控件,该页无法正常显示. ...

  6. C#中的Chart控件——当数据源很多时可以显示进度条拉动观察,也可以记录到后台文本详细对照

    C#中的Chart控件--当数据源很多时可以显示进度条拉动观察,也可以记录到后台文本详细对照 本文源码下载地址:https://download.csdn.net/download/qq_427579 ...

  7. 站点某些网页想显示母版页内的用户控件,某些网页不想显示,怎样实现

    "我有一个站点,这个站点使用了masterpage,还两个用户控件(ascx),是拉至masterpage内的,一个是作为网页首(Header.ascx),另一个作为网页脚(Foot.asc ...

  8. svg上传服务器无法显示,让WordPress支持上传SVG格式图片并显示在媒体库中的方法...

    让WordPress支持上传SVG格式图片并显示在媒体库中的方法 发布时间:2020-12-11 14:18:12 来源:亿速云 阅读:167 作者:小新 这篇文章将为大家详细讲解有关让WordPre ...

  9. 利用MSCOMM控件通过串口MODEN实现来电显示-c# source code

    利用MSCOMM控件通过串口MODEN实现来电显示-c# source code 注:此代码都已调试通过 处理方式 MSComm控件提供了两种处理通信的方式:一种为事件驱动方式,该方式相当于一般程序设 ...

最新文章

  1. mysql,mairadb启动脚本
  2. springboot创建单个对象
  3. python --- 使用socket创建tcp服务
  4. linux so文件支持系统,让linux支持xfs jfs reiserfs 文件系统
  5. CreateCompatibleDC用法[转]
  6. 【学习笔记】深入理解js原型和闭包(9)—— 简述【执行上下文】下
  7. DBSCAN聚类算法初探(五)
  8. 修改CentOS默认yum源为国内镜像
  9. Python实现机器学习
  10. 程序员的一种境界【转的】
  11. MOVE降低高水位 HWM
  12. 最新麻瓜编程实用主义学Python分享
  13. java struts2_Java struts2面试题及答案
  14. linux如何卸载干净mysql
  15. 阿里免费网盘teambition使用初体验
  16. 【JS笔记】JS中的DOM对象以及通过JS获取DOM结点,操作DOM属性、DOM增删改查
  17. Apad Qzone项目总结(二)---换肤功能实现!!!
  18. 51nod 1326 遥远的旅途 最短路建模
  19. Beyond Compare 4访问手机或媒体播放器上的文件
  20. 「RocketMQ技术专题」帮你梳理RocketMQ/Kafka的选择理由及二者PK

热门文章

  1. gradle web_简单的Gradle Web应用程序
  2. 资源泄漏:救援的命令模式
  3. Java:不朽的对象和对象复活
  4. jcmd:一个可以全部统治的JDK命令行工具
  5. JavaOne 2015:为JDK 9做准备– blog @ CodeFX
  6. 推销自己的海盗猫王运营商
  7. 快速的骆驼和云消息传递
  8. 使用Stream API的类Java产量
  9. 扩展Spring Batch –步骤分区
  10. 使用Maven设置您的应用服务器