Eddie Osmani在“ 2018年JavaScript的价格 ”一文中表达了一个宝贵的想法:处理200 KB大小的脚本和处理具有相同大小的图像所需的时间差异很大。事实是,在处理代码时,浏览器需要比准备使用图像做更多的工作。这是文章所说的:JPEG图像需要解码,光栅化和显示。 JS包是必要的,如果我们简单地考虑它,则可以加载,解析,编译,执行。实际上,引擎在处理JS代码的过程中必须解决其他问题。总的来说,应该记住,处理JavaScript代码需要花费更多的系统资源,而JavaScript代码的大小(以字节为单位)与其他材料的大小相当。这些词写于2018年,但仍不公平。的确,鉴于当前的情况,今天在这里表达的想法有些不同。
考虑到现在世界上已爆发大流行,我注意到我的Internet连接已经变得不稳定。幸运的是,由于Internet受到不受疲劳影响的优秀专家的保护,因此大多数Internet仍然可以正常工作。但是在Internet上肯定正在发生某些事情。我使用100 Mbps的连接,但是我感觉自己坐在3G调制解调器上。这对上述推理进行了一些更改。事实是,我们的设备可以像几周前一样的速度解析和编译JavaScript。但是,数据现在在网络中传输的速度更慢。结果,当加载该资源时,目前在网络上传输多少表示某种资源的数据非常重要。而且站点通常具有超过200 KB的图像。通常情况下,页面包含数兆字节的图片。通常,许多开发人员(我也是!)根本不考虑媒体材料的大小。但是,这非常好,优化网页上使用的图像并不是那么困难。在本文中,我们将讨论如何使用WebP等现代图形格式。用这种格式保存的图像通常比每个人都使用的旧的和众所周知的旧格式(如JPG和PNG)小2-3倍。使用新格式会严重改变这种状况。现代图形格式概述
为了改进Web图形的工作,我们可以使用以下三种格式:- JPEG 2000是一种格式,是常规JPG的改进版本。该格式于1997年开发,主要用于电影院和医学领域。它使您可以压缩比JPEG更强的图像,但失真更少。
- JPEG XR是与JPEG 2000相关的格式。它由Microsoft在2009年开发。
- WebP是Google在2010年为网络创建的一种格式。其开发的主要目标是使用高级方法来优化图像,以减小文件大小。WebP支持透明甚至动画。
在这里,我们将主要讨论WebP。与JPEG相关的格式,我们将讨论在哪里出现浏览器兼容性问题。使用其他图形格式可以赢多少钱?
几个月前,我在一种材质中使用了以下图片。考虑到使用JPG和PNG格式存储原始图像,我在一种材料中使用的图像进行了一些实验。我使用 imagemin优化了图像选项,以便找出WebP可以给我的东西,而不是这些“复古”格式。结果令人难以置信。我对许多图像进行了类似的实验。几乎总是发现,WebP文件比其他格式的图形文件的优化版本还要小30-70%。这可能引发一个问题,即转换为WebP会如何影响SVG图像。我没有使用SVG进行此类实验。SVG是矢量格式。这意味着其中的图像是基于数学指令构建的,而不是基于有关各个像素颜色的信息构建的。将SVG图像转换为WebP意味着放弃缩放SVG图像的功能,我认为这是不可接受的。另外,我怀疑在大多数情况下,这种转换会导致文件大小增加。浏览器兼容性
要了解浏览器如何支持某些图形格式,请访问caniuse.com。大多数浏览器都支持WebP格式。浏览器对WebP格式的支持尽管该格式的支持水平很高,但Safari和Internet Explorer不支持它是非常糟糕的。这是有关JPEG 2000支持的信息。浏览器对JPEG 2000格式的支持因此,现在我们支持 Safari,但是Internet Explorer再次无法使用。JPEG XR呢?浏览器对JPEG XR格式的支持在此Internet Explorer成为了区别。结果,使用这三种格式,我们会覆盖所有现有的浏览器(KaiOS浏览器不支持任何一种格式,我为他的无视向他表示歉意,但我什至不知道它是什么浏览器)现在让我们谈谈如何选择为不同浏览器设计的不同图像格式。抢救的像素
HTML有两个用于输出图像的元素。第一个可以与像麦当娜这样的国际流行歌星相提并论。是的img
。第二个就像是一支新乐队,仅在狭窄的音乐爱好者圈子中广为人知。这是一个要素picture
。该元素picture
出现在HTML中的时间比早得多img
。这个新元素的主要目的是允许开发人员根据屏幕分辨率或浏览器是否支持某种图形格式来下载各种图形资源。使用该元素的HTML代码如下所示picture
:<picture>
<source srcset="/images/cereal-box.webp" type="image/webp" />
<source srcset="/images/cereal-box.jp2" type="image/jp2" />
<img src="/images/cereal-box.jxr" type="image/vnd.ms-photo" />
</picture>
一个元素picture
可以包括许多子元素source
和一个元素img
。浏览器顺序地解析这些元件,选择,基于所述属性type
(一个或多个media
),它们中的一个,可以使用它。找到这样的元素后,浏览器将使用属性找到图像的地址srcset
,然后使用元素显示该图像img
。该属性srcset
具有比通常的功能大得多的功能src
,但幸运的是,我们可以将其视为类似物src
。通常,元素source
就像是与不同图像对应的设置。该img
图像是最好的,其中包括在浏览网页的环境匹配。例如,在Chrome中,在处理完上述标记后,浏览器将或多或少地等效于以下代码:<picture>
<img src="/images/cereal-box.webp" />
</picture>
使用一组连续的元素source
意味着它们中的至少一个将适合每个浏览器。因此,大多数浏览器使用webp图像,Safari会加载jp2图像,即jxr图像。记得Internet Explorer不支持该元素picture
。此项对于该浏览器来说太新了。但是,尽管如此,IE中的上述标记片段仍将按预期工作。事实是,当浏览器偶然发现一个未知元素时,会将其视为元素div
。结果,在解析我们的代码时,IE会看到许多元素div
以及一个标签<img>
其中包含jxr图片的路径。事实证明,这就是Internet Explorer支持的格式。简化的替代方案
上面的代码片段非常好,因为它允许您在所有当前浏览器中使用现代图形格式。但是,此类代码的使用是基于存在与之链接的图像的假设。如果您自己创建此类图像,则必须在其中投入大量的体力劳动。如果自动生成它们,则可能会大大增加项目的构建时间。如您所知,在处理大量图像时,图形处理变得非常缓慢。我博客的访问者很少使用Internet Explorer(在过去的7天中,只有3个使用IE的人试图查看它,占访问量的0.02%)。因此,我决定使用上述解决方案的简化版本:<picture>
<source srcset="/images/cereal-box.webp" />
<img src="/images/cereal-box.jpg" />
</picture>
对于支持这种格式的浏览器(Chrome,Firefox,Edge)和不支持这种格式的浏览器(IE,Safari),我提供了一个紧凑的webp图像,我提供了过去的遗产-jpeg图像。在我看来,这是一个逐步改进的例子。尽管加载图像需要更长的时间,但该项目仍可在旧版浏览器上运行。这是适合我的折衷方案。(确实,我希望WebP支持也将很快出现在Apple的浏览器中)。检查解决方案的运行状况
开发人员工具将始终假定图像包含最初写入src
tag 属性的图像img
。如果使用选项卡检查项目Elements
,则可以看到页面使用的是jpg图像。在我看来,为了检查所有这些文件的可操作性,最好是右键单击图片并 …
在执行命令时选择Chrome中的项目,系统应提供以扩展名保存文件.webp
。但是在Safari中,它将是jpeg文件。为了准确地找到页面加载时从服务器接收到的图形文件,可以参考开发人员工具栏Network
。将图像文件转换为WebP格式
Google已经创建了一套旨在处理webp文件的工具。一种这样的工具称为cwebp。它允许您将其他格式的图形文件转换为WebP。如果您使用的是MacOS,则可以使用Homebrew安装此工具包:brew install webp
在其他平台上,我认为有必要从存储库下载适当的libwebp软件包。安装工具后,可以像这样使用它们:cwebp -q 80 cereal.png -o cereal.webp
考虑以下命令:- 该标志
-q 80
允许您设置图像质量。它的值从1(最差的质量)到100(最佳)不等。您可以尝试不同的值。我发现最好问70-80左右的问题。 - 文件名
cereal.jpg
是需要转换为webp的原始图像。 - 构造
-o cereal.webp
将路径设置为输出文件。
没有人愿意浪费时间手动输入此类命令。幸运的是,该任务可以自动化。在React应用程序中使用现代图像格式
组件是忽略某些元素奇数的好方法<picture>
。我为此使用React组件。我认为这非常方便。看起来是这样的:const ImgWithFallback = ({
src,
fallback,
type = 'image/webp',
...delegated
}) => {
return (
<picture>
<source srcSet={src} type={type} />
<img src={fallback} {...delegated} />
</picture>
);
};
使用该组件ImgWithFallback
与使用常规标签非常相似img
:<ImgWithFallback
src="/images/cereal.webp"
fallback="/images/cereal.png"
alt="A photo showing the expiration date on a box of Lucky Charms"
/>
将现代图形格式与风格化组件结合使用
如果您使用库,styled-components
或者emotion
您可能习惯于特殊的图像设计:const FancyImg = styled.img`
whatever: stuff;
`
很好的是,它可以与我们的组件一起使用ImgWithFallback
。您可以像其他任何组件一样将其包装在适当的包装中:const FancyImg = styled(ImgWithFallback)`
whatever: stuff;
`
该设计可操作性的原因是辅助结构的工作原理styled
。它生成一个类并将其嵌入到文档样式表中。然后,将生成的类的名称作为属性传递给组件:<ImgWithFallback className="sc-some-generated-thing" />
我们将所有属性委派给child标记<img>
,因此,通常会在图像上应用正确的样式。一切都按照您的预期工作。使用gatsby-image软件包
如果您使用的是Gatsby,请注意,gatsby-image
正常使用该软件包时,已经使用了许多图像优化功能。这包括将图像转换为webp格式(尽管如此,您需要启用适当的选项)。该包装gatsby-image
并不声称是替代品img
。它的使用可能不是那么简单,它的内部机制可能会导致意外,给开发人员带来麻烦。如果您对此软件包感兴趣,请查看其文档。WebP的缺点
我设法找到的webp的唯一真正缺点是,使用这种格式的文件非常不方便。大多数桌面映像程序包尚不支持它。例如,我无法在MacOS上的“预览”中打开webp文件。这意味着,如果我从网页保存了Webp图像,将无法在计算机上查看它!将webp文件转换为jpeg文件是一个相当简单的过程。在Internet上,您可以找到许多执行这种转换的免费服务。但是,这又不如使用传统图形格式方便。如果您的站点允许用户从中下载图形文件,则可以决定不需要切换到webp。摘要
我非常喜欢使用webp能够将博客上的图片大小减少约50%的事实。除了在困难时期改善了与他一起工作的用户体验这一事实外,我还希望这将使我节省一些交通费用。当然,手动将图像文件转换为Webp格式的想法似乎是不切实际的。我已经在研究如何自动将jpg和png文件转换为这种格式的问题。理想情况下,在现场组装过程中,开发人员完全不会注意到此过程。Web项目的创建者通常对使用新图像格式的功能并不特别感兴趣。但是我认为了解这个问题非常有用。毕竟,使用WebP可能是将Web项目的大小减少数百千字节的最简单方法。亲爱的读者们!您是否使用WebP格式?