【译】重要的图像优化之九:几种页面优化技术

注明:本人原创翻译,原版为Essential Image Optimization电子书,这里将其拆分为几篇文章发布。另外,文中部分链接可能会因为“网络”原因无法打开。不必着急,我会慢慢将其中一些比较好的内容翻译过来发表,都会在这个“Web图像技术深究”专题中。

目录

正文:

图像拼合技术

图像拼合技术 (或者说CSS图像拼合技术)在Web开发上其实有着悠久的历史,它受到所有浏览器的支持,这个技术是通过加载单个更大的合并图像来减少页面加载图像数量的一种流行方式。

i2_2ec824b0_1.jpg

图像拼合仍然广泛应用于很多大型网站的生产环境中,包括Google主页。

在HTTP/1.x下,一些开发人员通过合并来减少加载图像的HTTP请求数量。这带来了一些好处,但是它很快遇到了“缓存无效”的挑战,需要小心的是 - 对于图像的任何的一小部分的更改,都将使得用户的缓存中的整个图像无效。

现在,拼合技术在HTTP/2可能是不合适的。使用HTTP/2的话,最好是加载单个图像,因为现在单个链接中的多个请求是可能的。因此,使用之前请评估一下,图像拼合技术是否适用于你的网络设置。

延迟加载非关键图像

延迟加载是一种优化Web性能的模式,它会延迟浏览器中图像的加载,直到用户需要看到它的时候。一个例子是,当您滚动页面时,可视区域的图像会按需异步加载。这可以进一步帮助你节省从图片压缩策略省出来的带宽空间。

scrolling-viewport.jpg

出现在“折叠线之上”或网页中首次出现的图像必须立即加载。然而,在“折叠线下方”的图像对于用户来说尚不可见,它们不必被立即加载到浏览器中。只有当用户向下滚动并且需要显示它们时,再稍后加载或者延迟加载即可。

其实,浏览器本身并没有支持延迟加载(尽管过去曾经讨论过)。因此,我们会使用JavaScript来添加此功能。

为什么延迟加载是有效的?

这种所谓“延迟”,即只有在必要时加载图像的方式,有很多好处:

  • 降低数据消耗:由于你假设用户不需要提前提取每个图像,因此您只需加载最少的资源。这永远是一件好事,特别是在具有更严格的流量控制的移动设备上。
  • 降低电池消耗:减少了用户浏览器的工作量,也可以节省电池的使用寿命。
  • 提高下载速度:将图像占比较大的网站的整体页面加载时间,从几秒缩短到几乎没有,这是对用户体验的巨大提升。事实上,这可能是决定你的用户在你的网站长期驻留还是昙花一现的关键点。

但是,就像所有的工具一样,强大的力量意味着巨大的责任。**

避免在折叠线之上放置图像。延迟加载可以用于长列表的图像(例如产品)或用户头像列表中。但不要用于主页的焦点图像。延迟加载折叠线以上的图像将会使整个页面的加载显得很慢,无论是从技术上还是人类的感知上讲。我们可以使用JavaScript屏蔽浏览器的预加载、增加逐步加载,为浏览器创建额外的工作。

在滚动时延迟加载图像,要非常谨慎。如果你等待用户滚动之后再加载图像,他们可能就会看到图像占位符,并且很有可能在它们已经滚动过去后图像才加载完成。一个建议就是在加载折叠线之上的图像后就开始延迟加载,加载所有图像,而不依赖于用户的操作。

谁在使用延迟加载技术?

有关延迟加载的示例,请查看以托管大量图像为主营业务的所有站点。比较著名的网站是MediumPinterest

Modern-Image35.jpg

在Medium.com上,一个使用高斯模糊在线预览的例子。

一些网站(例如“Medium”)会先显示一个小的高斯模糊的在线预览图像(几百个字节),一旦获取完成,它将转换(延迟加载)到全质量的图像。

JoséM.Pérez曾经写过关于如何使用CSS过滤器实现Medium网站的类似效果,并尝试了不同的图像格式来支持这样的占位符。Facebook也曾为其著名的200字节方式占位符,撰写了一份值得一读的文章“封面照片”。如果你是Webpack的使用者,LQIP加载程序可以帮助你自动完成类似的工作。

事实上,您可以搜索你最喜欢的高清照片来源,然后向下滚动页面。几乎所有情况下,你都将体验到网站一次只能加载几个全分辨率的图像,其余的则是占位符颜色或图像。当你继续滚动时,占位符图像将被替换为全分辨率图像。这就是典型的延迟加载效果。

如何在我的页面使用延迟加载?

有一些技术和插件可支持延迟加载。我推荐Alexander Farkas编写的lazysizes,因为它的性能良好、功能齐全、并可选择通过浏览器的“交叉观察者”API(IntersectionObserver API)集成,还支持插件扩展。

我可以怎样使用Lazysizes?

Lazysizes是一个JavaScript的库。它不需要配置,只需下载压缩后的js文件并将其包含在您的网页中即可使用。

这是从Lazysizes的README文件中获取的一些示例代码:

将CSS类“lazyload”添加到你的包含data-src或data-srcset属性的<img><iframe>标签上。

或者,您也可以添加指向低质量图像的src属性:

<!-- 非响应式示例: -->
![](image.jpg)

<!-- 响应式示例,包括data-sizes为auto: -->
<img
    data-sizes="auto"
    data-src="image2.jpg"
    data-srcset="image1.jpg 300w,
    image2.jpg 600w,
    image3.jpg 900w" class="lazyload" />

<!-- iframe示例 -->

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

实际上,在这本书的网络版本中,我将Lazysizes(尽管可以使用任何替代方案)与Cloudinary配合响应式地返回需求的图像。这允许我自由地尝试不同的尺度、质量、格式的值,而无需在响应式处理上付出很大的精力:

cloudinary-responsive-images.jpg

Lazysizes的功能包括:

  • 自动检测当前和未来的“lazyload”元素的可见性变化。
  • 包括标准的响应图像支持(包括picture和srcset)。
  • 添加多媒体列表功能的自动尺寸计算和别名。
  • 可被用在CSS和JS使用比重较大的网页或网络应用程序上,处理数以百计的images或 iframe标签。
  • 可扩展:支持插件
  • 轻量级但成熟的延迟加载解决方案
  • SEO已改进:不能在爬虫抓取时隐藏图像或资源。

其他延迟加载的可选项

Lazysizes并不是你唯一的选择。这里还有其他的延迟加载库:

延迟加载有什么问题么?

  • 一些阅读器、搜索机器人和任何禁用JavaScript的用户将无法看延迟加载的图像。但是,我们可以通过一个<noscript>标签来提示解决!
  • 对页面滚动进行侦听,例如确定何时加载延迟加载的图像,可能会对浏览器的滚动性能产生不利影响。可能会导致浏览器重绘多次,从而减缓网络爬取的进程 - 但是,智能的延迟加载库将会使用节流阀(throttling)来缓解这种情况。一个可能的解决方案是浏览器的“交叉观察者”API,lazysizes是支持这种模式的。

延迟加载图像是减少带宽占用、降低加载消耗和改善用户体验的一个广泛使用的方式。你可以评估它,对你网站的用户体验是否有意义。需要进一步了解,可以参阅延迟加载图像实现Medium的渐进式加载

避免display:none的陷阱

一些陈旧的响应式图像解决方案,会错误地理解当设置CSS display属性时浏览器处理图像请求的方式(以为display:none的时候就不会请求获取图像)。这可能会是你比你所期望的请求了更多的图像的另一个原因,所以<picture><img srcset>依然是你响应式加载图像的首选方式。

你有没有写过一种@Media语句,它在某些断点上将图像设置为display:none

![](img.jpg)
<style>
@media (max-width: 640px) {
    img {
        display: none;
    }
}
</style>

或者是使用display:none的CSS设置图像隐藏切换?

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

一个快速验证的方法,就是使用Chrome开发者工具的网络面板,可以看到上述方法想要隐藏的图像其实仍然会被获取,即使我们的期望是它们不会被访问。根据嵌入式资源规范,浏览器的这种行为其实是没有问题的。

display-none-images.jpg

使用display:none会避免触发图像src指定的链接请求?

<div style="display:none">![](img.jpg)</div>

答案是否定的。指定的图像仍然将被请求获取。样式display:none无法影响这个请求,因为在JavaScript可以修改src之前,图像请求就已经发出了。

那么使用display:none会避免触发图像background: url()指定的链接请求么?

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

这回答案是肯定的。 上面编写的元素一旦被解析,其中的CSS背景图片就不会被请求获取。CSS样式解析计算时会认为,带有display:none元素的任何子元素都是没有作用的,对于整个文档的显示没有影响。所以,子元素中的任何背景图片都是会被忽略并不被下载的。

Jake Archibald的请求任务解析中对于你响应式图像加载中使用display:none的陷阱有一个很好的测验。当你怀疑你的浏览器是如何处理图像请求加载时,可以打开它的开发者工具并自己验证图像加载的情况。

再次提醒你,在可能的情况下,还是建议使用<picture><img srcset>来处理,而不是依赖于display:none

预加载关键图像资源

对于关键图像资源的预加载,可以使用 <link rel=preload>.

<link rel=preload> 是一个声明式的提取,允许你强制浏览器对资源进行请求,而不会阻止页面文档的onload事件。它可以增加资源请求的优先级,防止在文档解析的后期可能无法找到资源。

可以通过指定 as 的值 image来预加载图像文件:

<link rel="preload" as="image" href="logo.jpg"/>

<img><picture>srcset和SVGs中使用的图像资源,都可以采用这种方式优化加载。

注意: 支持<link rel="preload">浏览器包括Chrome和其他基于Blink的浏览器如Opera、Safari的技术预览版Firefox也已经增加了支持

飞利浦FlipKart施乐等网站都是使用<link rel=preload>来预加载其主要的徽标资源(通常在页面载入的早期)。Kayak也使用了预加载,以确保其页面顶部的焦点图像尽快加载出来。

preload-philips.jpg

HTTP头的预加载是什么?

可以使用HTML标签或者页面<header>的Link中指定预加载链接。在任一种情况下,预加载链接都会指示浏览器开始将资源加载到内存高速缓存中,指明该页面需要高效率的使用此资源,并且不希望等待页面加载或解析器发现它时再获取。

一个<header>中的预加载连接设置,就像下面这样:

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

当“金融时报”在他们的网站网页的头部设置了一个链接预加载之后,显示他们头条图像所花费的时间被减少了1秒钟

preload-financial-times.jpg
底部:使用了<link rel=preload>,顶部:没有使用。WebPageTest使用Moto G4在3G环境下对“金融时报”首页之前之后的载入时间比较。

同样地,维基百科也通过使用预加载链接技术改善了他们徽标的载入时间表现,可以通过他们的此案例研究中的介绍看到。

使用预加载时有哪些注意事项?

首先,你要非常确定指定的图像资源是非常值得被预先加载的;如果它们对你的用户体验不是至关重要的,那么页面上可能会有其他内容需要重点关注要预先加载。通过优先处理图像请求,您可能最终会将其他资源进一步放置到队列中。

一个非常需要注意的是,要避免使用rel=preload预加载那些不被浏览器广泛支持的图像格式(例如WebP)。最好还要避免将其用于使用srcset设置的根据设备条件而变化图像链接位置的响应式图像。

想要了解更多的预加载相关的信息,请查阅一下文章:Chrome中的预加载、预提取和优先级预加载:究竟好在哪里?

最后一篇:【译】重要的图像优化之十:写在最后

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

推荐阅读更多精彩内容