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

3ce83a0d3af85ffbed16c1c2339c895e.png

webp 是 google 提倡的一种新的 image 格式,意在为 web 提供体积更小的图片格式。通常情况下,无损压缩可以减小 25%-35% 的体积(有例外情况,反而会增大体积,但是是因为转换图片格式不兼容引起的),有损压缩最大可以节省大约 75%-90% 的体积。

兼容性

使用新的浏览器特性,首先应该考虑兼容性问题,它的兼容性如下图:

81daf63b1d2303ea4f8c243a8d91c448.png

可以发现,除了 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 标签的兼容性问题,如下:

b3f674780ad7ff30d8dda11064e39dc4.png

可以发现除了 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>);
};

这里的封装比较简单,但作为演示够用了,效果如下:

aae8e41eb8ca478161b927a54ddd13b7.png

network 中的加载情况:

78d839aaea018f1330aa92c69a5a4df4.png

总结

我示例中的图片,源文件大小为 184kbwebp 副本文件大小为 22kb,如下图:

b6b95049f4fc820626434b03eb483500.png

由于我这里是有损压缩,所以体积减少比例大概是 ~88%,无损压缩的话,会比这个低一些。

参考

https://developers.google.com/speed/webp/https://github.com/DonRai/react-image-webphttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/340617.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么打开网卡rss_RSS 进阶篇:Huginn - 真·为任意网页定制 RSS 源(PhantomJs 抓取)...

定制网页RSS源主要有FEED43和Huginn两种方法。FEED43&#xff1a;简单免费&#xff0c;六小时抓取一次&#xff0c;每次抓取20条静态页面。使用攻略- RSS 入门篇&#xff1a;FEED43&FeedEx-为静态网页定制 RSS 源2. Huginn&#xff1a;自由度高&#xff0c;可设定抓取频率、…

编写junit 测试_编写JUnit测试的另一种方法(Jasmine方法)

编写junit 测试最近&#xff0c;我为一个小型个人项目编写了很多Jasmine测试。 我花了一些时间才终于感到正确地完成了测试。 在此之后&#xff0c;当切换回JUnit测试时&#xff0c;我总是很难过。 由于某种原因&#xff0c;JUnit测试不再那么好&#xff0c;我想知道是否有可能…

python4 什么时候_Python4要来了?快来看看Python之父怎么说

大家好&#xff0c;我是菜鸟哥&#xff0c;今天跟大家一起聊一下Python4的话题&#xff01;从2020年的1月1号开始&#xff0c;Python官方正式的停止了对于Python2的维护。Python也正式的进入了Python3的时代。而随着时间的发展&#xff0c;关于Python4的发布也逐渐的成为了大家…

python类成员变量_Python 类变量和成员变量

Python 类变量和成员变量类与对象的方法我们已经讨论了类与对象的功能部分&#xff0c;现在我们来看一下它的数据部分。事实上&#xff0c;它们只是与类和对象的名称空间 绑定 的普通变量&#xff0c;即这些名称只在这些类与对象的前提下有效。有两种类型的 域 ——类的变量和对…

JDK 14 – JEP 361从预览中切换表达式

在我以前的文章中 &#xff0c;我写了有关作为JDK 12的预览功能发布的开关表达式和相关增强功能的信息。随后&#xff0c;在JDK 13中提出了一些更改&#xff0c;例如使用yield关键字从switch块返回值并在预览中发布。 在即将于明年3月在GA上发布的即将发布的JDK 14版本中&…

输入一个正整数求所有素数因子_一个数如果恰好等于它的因子之和,这个数就称为完数。编写应用程序求1000以内所有的完数...

运行截图&#xff1a;代码import java.util.*;public class wanshu {public static void main(String args[]) {int sum 0,i,j,k,m 0;System.out.println(" 完数有&#xff1a;");for( j 2; j < 1000 ; j){for ( i 2 ; i < j; i){if( j%i 0) //此判…

安卓禁用硬件加速_Android硬件加速详解

从Android3.0(API Level 11)开始&#xff0c;支持硬件加速&#xff0c;可充分利用GPU的特性&#xff0c;使得界面渲染更加平滑。但是硬件加速自身并非完美&#xff0c;在某些Webview版本上&#xff0c;比如Android5初期的一些rom上的Webview版本是chrome37、38版本&#xff0c;…

mac svn工具_程序员或产品经理,这些Mac的效率工具一定不要错过

工欲善其事必先利其器!用好工具能很大的提高我们的工作效率&#xff0c;尤其是程序员和产品经理等。今天给大家介绍一些好用的工具随时记下闪现的灵感人的一天中大脑会产生大约6万个想法, 其中有不少优秀的 idea. 如果我们能学会捕捉哪怕是部分灵感, 也将会收获巨大. 因此工作中…

案例 github_github 项目搜索技巧-让你更高效精准地搜索项目

作者&#xff1a;Suwanbinwww.cnblogs.com/suwanbin/p/12113751.htmlgithub 搜索技巧参考自 B站 up 主 CodeSheep 的视频【如何高效地在网上找开源项目做&#xff01;在职程序员实际演示一波视频教程操作】&#xff0c;然后写着写着一好奇就去看文档了现在这篇博客相当于官方文…

使用Spring和JSR 303进行方法参数验证

Spring提供了一种使用JSR 303 bean验证来验证方法参数的简便方法。 在这篇文章中&#xff0c;我们将看到如何使用此功能。 设定 首先&#xff0c;我们需要通过创建MethodValidationPostProcessor bean添加对方法参数验证的支持&#xff1a; Configuration public class MyCon…

想要导航提示直接进入_北斗导航已开始提供全球服务,你的手机怎样连接北斗?...

如果你是新朋友&#xff0c;请点击上方的蓝色字 关注 “高科技爱好者”&#xff0c;保证不会让你失望的.自从北斗导航全球组网成功后&#xff0c;开始向全球提供导航服务&#xff0c;关于北斗导航的话题就没有断过&#xff0c;最常听到的两个话题&#xff1a;北斗收费吗&#x…

python3异步协程爬虫_Python实现基于协程的异步爬虫

Python实现基于协程的异步爬虫一、课程介绍1. 课程来源本课程核心部分来自《500 lines or less》项目&#xff0c;作者是来自 MongoDB 的工程师 A. Jesse Jiryu Davis 与 Python 之父 Guido van Rossum。项目代码使用 MIT 协议&#xff0c;项目文档使用 http://creativecommons…

python中变量的类型是动态的随时可以变化_python动态类型简介

1、a [1,2,3]其中a是变量名&#xff0c;[1,2,3]是对象&#xff0c;a通过一个指向[1,2,3]的指针引用了对象[1,2,3].2、每一个对象都有两个标准的头部信息&#xff0c;一个是标示这个对象的类型。另外一个是用来决定是不是可以回收这个对象。3、类型属于对象&#xff0c;而不属于…

jpa和hibernate_从JPA到Hibernate的旧版和增强型标识符生成器

jpa和hibernateJPA标识符生成器 JPA定义了以下标识符策略&#xff1a; 战略 描述 汽车 持久性提供程序选择基础数据库支持的最合适的标识符策略 身份 标识符由数据库IDENTITY列分配 序列 持久性提供程序使用数据库序列来生成标识符 表 持久性提供程序使用单独的数据库…

去掉前后空格_mysql批量去掉某个字段字符中的空格

mysql有什么办法批量去掉某个字段字符中的空格&#xff1f;不仅是字符串前后的空格&#xff0c;还包含字符串中间的空格&#xff0c;答案是 replace&#xff0c;使用mysql自带的 replace 函数&#xff0c;另外还有个 trim 函数。 &#xff08;1&#xff09;mysql replace 函数 …

python自己做个定时器_技术图文:如何利用 Python 做一个简单的定时器类?

原标题&#xff1a;技术图文&#xff1a;如何利用 Python 做一个简单的定时器类&#xff1f;背景今天在B站上看有关 Python 最火的一个教学视频 -- “零基础入门学习 Python”&#xff0c;这也是我们 Python基础刻意练习活动 的推荐视频教程。python视频在学习魔法方法的时候&a…

成为Java流大师–第6部分:使用流创建新的数据库应用程序

您是否曾经想开发数据库应用程序的“快速”版本&#xff1f; 在此动手实验文章中&#xff0c;您将学习一种真正简单而直接的方法。 整个Java域模型将自动为您生成。 您只需连接到现有数据库&#xff0c;然后开始使用Java流进行开发。 例如&#xff0c;您将能够在几分钟内为您现…

快速排序 挖坑_由浅入深玩转快速排序算法

由浅入深玩转快速排序算法快速排序可以说是最快的通用排序算法&#xff0c;它甚至被誉为20世纪科学和工程领域的十大算法之一。在众多排序算法中其无论是时间复杂度还是空间复杂度都颇具优势。作为开发工程师&#xff0c;我们很有必要了解它的思想。接下来将由在下为大家一步步…

代码拾取图片某一点的颜色_RPG游戏开发日志7:道具拾取与存放

本项目同步上传于github和coding上&#xff0c;国内读者可以通过在coding下载项目。也欢迎你加入我的UE4学习交流QQ群&#xff1a;872537977。如果你喜欢我写的文章&#xff0c;也希望你点赞、收藏、转发。谢谢&#xff01;如果你喜欢我写的文章&#xff0c;也希望你点赞、收藏…

使用sstableloader恢复Cassandra Priam备份

之前&#xff0c;我曾写过关于设置Cassandra和Priam进行备份和集群管理的文章。 但是&#xff0c;我在此处提供的用于备份还原的示例并不适用于所有情况&#xff0c;例如&#xff0c;它可能不适用于完全独立的群集。 或者在部分还原到一个表而不是整个数据库的情况下。 在这种…