web图像优化(5)

避免使用有损编解码器重新压缩图像

建议始终从原始图像压缩。 重新压缩图像有后果。 假设您使用了已经被压缩的质量为60的JPEG。如果您使用有损编码重新压缩此图像,则会变得更糟。 每轮新一轮的压缩都会引入分代丢失 - 信息将会丢失,并且压缩伪像将开始建立。 即使您正在以高质量设置重新压缩。

为了避免这个陷阱,首先设置你愿意接受的最低质量,从一开始你就可以节省最多的文件。 然后避免这种陷阱,因为任何文件大小的降低都会降低质量。

对有损文件进行重新编码几乎总会给你一个更小的文件,但这并不意味着你可以想象得到更多的质量。

image

我们可以看到使用多种格式对再压缩造成的世代性损失的影响。 如果从社交网络上保存(已压缩)的图像并重新上传(导致再压缩),这可能会遇到问题。 质量损失将会增加。

编辑源文件时,请将其存储为像PNG或TIFF这样的无损格式,以便尽可能保持质量。 您的构建工具或图像压缩服务比将输出的压缩版本以最小的质量损失输出给用户

减少不必要的图像解码和调整成本

我们都发送了大量的,更高分辨率的图像,而不是我们以前用户需要的。 这是有成本的。 解码和调整图像大小对于普通移动硬件上的浏览器来说是昂贵的操作。 如果发送大图像并使用CSS或宽度/高度属性重新缩放,则可能会看到这种情况,并且会影响性能


image

当浏览器获取图像时,必须将图像从原始源格式(如JPEG)解码到内存中的位图。 通常图像需要调整大小(例如,宽度已经设置为其容器的百分比)。 解码和调整图像的大小是昂贵的,可以延迟显示图像需要多长时间。

发送浏览器可以呈现的图像而不需要调整大小是理想的。 所以,为您的目标屏幕尺寸和分辨率提供最小的图像,利用srcset和大小 - 我们很快就会介绍srcset。

忽略图像上的宽度或高度属性也会对性能产生负面影响。 如果没有它们,浏览器会为该图像分配一个较小的占位符区域,直到有足够的字节才能知道正确的尺寸。 此时,文档布局必须更新,这可能是一个昂贵的步骤,称为回流。


image

浏览器必须经过多个步骤才能在屏幕上绘制图像。 除了获取它们之外,图像需要被解码并且经常调整大小。 这些事件可以在Chrome DevTools时间轴中审核。

较大的图像也伴随着内存大小成本的增加。 解码图像是每个像素〜4个字节。 如果你不小心,你可以从字面上崩溃的浏览器; 在低端设备上,启动内存交换并不需要太多的工作。 因此,请注意您的图像解码,调整大小和内存成本。


image

在平均和低端手机上解码图像的成本可能会非常高。在某些情况下,解码速度可能会慢5倍(如果不是更长)。

在构建新的移动网络体验时,Twitter通过确保为用户提供适当大小的图像,改善了图像解码性能。 这将Twitter时间线上的许多图像的解码时间从〜400ms一直降低到〜19ms!


image

使用srcset提供HiDPI图像

用户可能通过一系列具有高分辨率屏幕的移动和桌面设备访问您的网站。 设备像素比率(DPR)(也称为“CSS像素比率”)决定CSS如何解释设备的屏幕分辨率。 DPR是由手机制造商创造的,可以提高手机屏幕的分辨率和清晰度,而不会使元素显得太小。

为了匹配用户可能期望的图像质量,将最合适的分辨率图像提供给他们的设备。 可以向支持它们的设备提供清晰的高DPR图像(例如2x,3x)。 低分辨率和标准DPR图像应该提供给没有高分辨率屏幕的用户,因为这样的2x +图像通常会占据更多的字节。


image

设备像素比例:许多网站追踪流行设备的DPR,包括material.io和mydevice.io

srcset允许浏览器为每个设备选择最佳的可用图像,例如,为2x移动显示选择2x图像。没有srcset支持的浏览器可以回退到<img>标签中指定的默认src。

<img srcset="paul-irish-320w.jpg,
             paul-irish-640w.jpg 2x,
             paul-irish-960w.jpg 3x"
     src="paul-irish-960w.jpg" alt="Paul Irish cameo">

一个友好的提醒,客户端提示也可以提供一个替代指定每个可能的像素密度和格式在你的响应式图像标记。 而是将这些信息附加到HTTP请求中,以便Web服务器可以选择最适合当前设备的屏幕密度。

Art direction

尽管向用户发送正确的解决方案很重要,但有些网站也需要从艺术方向来考虑这一点。 如果用户在较小的屏幕上,则可能需要裁剪或放大并显示主题以充分利用可用空间。


image

Image spriting

在网络上拥有悠久历史的图像精灵(或者CSS精灵)受到所有浏览器的支持,并且已经成为减少页面加载的图像数量的一种流行方式,通过将它们结合成一张切片的更大的图像。

image

在HTTP / 1.x下,一些开发者使用spriting来减少HTTP请求。 这带来了许多好处,但是,当您快速遇到缓存失效的挑战时,需要小心谨慎 - 对图像精灵的任何小部分的更改都会使用户缓存中的整个图像无效。

而现在可能是HTTP/2的一个反模式。 对于HTTP/2,最好加载单个图像,因为单个连接中的多个请求现在是可能的。

延迟加载非关键图像

延迟加载是一种Web性能模式,可延迟浏览器中的图像加载,直到用户需要查看它为止。 一个例子是,当您滚动时,图像按需加载异步。 这可以进一步补充您从图像压缩策略中看到的字节节省。

不要将它用于主要图像。

如何实现延迟加载

有许多技术和插件可用于延迟加载。我推荐Alexander Farkas的lazysizes,因为它的体面性能,功能,与Intersection Observer的可选集成以及对插件的支持。

Lazysizes是一个JavaScript库。它不需要配置。下载缩小的js文件并将其包含在您的网页中。

将类“lazyload”与data-src和/或data-srcset属性一起使用到图像/ iframe中。

<!-- non-responsive: -->
<img data-src="image.jpg" class="lazyload" />

<!-- responsive example with automatic sizes calculation: -->
<img
    data-sizes="auto"
    data-src="image2.jpg"
    data-srcset="image1.jpg 300w,
    image2.jpg 600w,
    image3.jpg 900w" class="lazyload" />

<!-- iframe example -->

<iframe frameborder="0"
    class="lazyload"
    allowfullscreen=""
    data-src="//www.youtube.com/embed/ZfV-aYdU4uE">
</iframe>

避免显示:display:none陷阱

较早的响应式图像解决方案错误地设置CSS显示属性时,浏览器如何处理图像请求。 这可能会导致要求的图像数量比您预期的要多得多,这也是装载响应图像的首选<picture>和<img srcset>的原因。

你有没有写过一个媒体查询设置图像显示:在某些断点没有?

img src="img.jpg">
<style>
@media (max-width: 640px) {
    img {
        display: none;
    }
}
</style>

或者使用显示切换隐藏的图像:none class?

<style>
.hidden {
  display: none;
}
</style>
<img src="img.jpg">
<img src=“img-hidden.jpg" class="hidden">

对Chrome DevTools网络面板进行快速检查,将验证使用这些方法隐藏的图像仍然会被抓取,即使我们预计它们不是。根据嵌入式资源规范,此行为实际上是正确的。

display:none没有可以避免触发图像src的请求吗?

<div style="display:none"><img src="img.jpg"></div>

没有。指定的图像仍然会被请求。一个库不能依赖显示:这里没有,因为在JavaScript可以改变src之前,图像将被请求

display:none没有可以避免触发一个背景的请求:url()吗?

<div style="display:none">
  <div style="background: url(img.jpg)"></div>
</div>

<p data-line="144" class="sync-line" style="margin:0;"></p>

是。 一旦元素被解析,CSS背景就不会被获取。 使用display:none为元素的子元素计算CSS样式将不太有用,因为它们不会影响文档的呈现。 子元素上的背景图像不计算也不下载。

再次强调:在可能的情况下,使用<picture>和<img srcset>,而不是依靠display:none。

缓存图像资产

资源可以使用HTTP缓存头指定缓存策略。 具体来说,缓存控制可以定义谁可以缓存响应和多长时间

您交付给用户的大多数图像都是静态资产,将来不会改变。 这种资产的最佳缓存策略是积极的缓存。

在设置HTTP缓存头时,设置一年的最大年限(例如Cache-Control:public; max-age = 31536000)的Cache-Control。 这种积极的缓存类型适用于大多数类型的图像,特别是头像等。

预先加载关键图片资源

关键的图片资源可以使用·<link rel = preload>进行预加载。

<link rel = preload>是声明式读取,允许您强制浏览器在不阻止文档onload事件的情况下请求资源。 它可以提高资源请求的优先级,否则在文档解析过程的后期可能不会被发现。

可以通过指定图像的值来预加载图像:

link rel="preload" as="image" href="logo.jpg"/>
<img>,<picture>,srcset和SVGs的图像资源都可以利用这个优化。

注意:在Chrome和基于Blink的浏览器(如Opera,Safari Tech Preview)中支持并已在Firefox中实现。

image

像飞利浦,FlipKart和施乐公司这样的网站使用<link rel = preload>来预载他们的主徽标资产(通常在文档的早期使用)。 Kayak也使用预加载,以确保他们的主页形象尽快加载。

什么是链接预加载头?

预加载链接可以使用HTML标记或HTTP链接标题指定。 无论哪种情况,预加载链接都会指示浏览器开始将资源加载到内存缓存中,指示页面高度置信地期望使用该资源,并且不希望等待预加载扫描程序或分析程序发现它。

图像的链接预加载标题看起来类似于:

Link: https://example.com/logo-hires.jpg; rel=preload; as=image

使用此优化时应该考虑哪些?
非常确定,值得预先加载图片资源对用户体验是至关重要的话。 通过优先处理图像请求,您可能最终将其他资源推入队列中。

避免使用rel = preload预加载图像格式而不支持广泛的浏览器(例如WebP)是非常重要的。 避免将其用于在srcset中定义的响应图像也很好,其中检索到的源可能会根据设备条件而变化。

总结

最终,选择一个图像优化策略将归结为您向用户提供的图像类型,您决定的是一套合理的评估标准。 它可能是使用SSIM或Butteraugli,或者如果是足够小的一组图像,则脱离人类感知最有意义的东西。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • JPEG 对于图片,一般分光栅图和矢量图 这两种图的对比也是很明显的 光栅图:是基于 pixel像素构成的图像。J...
    技术与健康阅读 1,205评论 0 1
  • WebP WebP是Google最近推出的一种图像格式,旨在以可接受的视觉质量提供较低文件大小的无损和有损压缩。它...
    技术与健康阅读 1,035评论 0 3
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,725评论 1 92
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,391评论 25 707
  • 枝叶是半个月前画的,因为婆婆住院,我忙的不可开交。完全没有时间画画,昨晚终于有时间摸画笔了,可是一下笔,我就感觉不...
    小倩姐姐123阅读 311评论 2 5