网页首先加载内容,然后通过延迟加载高分辨率图像交换来美化它?

Web page that loads content first, then beautifies it by deferred-loading hi res image swap-ins?

我制作的网站看起来可以接受,并且在合理的加载时间和不过分压缩 JPEG 图像之间取得了平衡。一个问题是有一个 100% 拉伸的全屏背景,虽然它在 13 英寸显示器上看起来不错,但在 5K 视网膜显示器上可能会变得丑陋。不过,我无法通过为移动用户提供巨大的图像来证明让他们受苦。我正在寻找的是 "lazy loader" 或 "deferred loader",它将检测显示尺寸和像素密度(视网膜与非视网膜)并尽可能提供最高质量的图像 - 但仅在所有网站内容之后已使用适度压缩的图像加载并处于可浏览状态。如果可能的话,我希望高分辨率换入图像在覆盖和替换默认分辨率图像时进行淡入过渡。我希望用户清楚页面已加载并准备好与之交互,这意味着没有进度条指示内容未完成下载。

目标/步骤

  1. 使用适度压缩的图像快速加载基本页面。该页面现在可以与之交互并且看起来并不糟糕。当搜索引擎抓取页面时,在这个阶段应该认为它已完全加载,否则页面排名可能会受到影响。
  2. 检查设备显示尺寸和像素密度以了解要换入的图像分辨率。
  3. 以适当的分辨率提供图像,但在它们完全加载并准备好淡入之前将它们隐藏起来。
  4. 淡入高分辨率图像。(淡入不需要跨图像同步,每个图像都可以在准备就绪时淡入其低分辨率图像)

我是在祈求奇迹吗?我应该放弃并坚持使用平庸的压缩图像吗?我不可能是唯一一个想这样做的人,所以我正在尝试找出可用的技术。

我在网络上找到了一些零散的答案,但在任何地方我都没有看到将它们联系在一起的解决方案。似乎没有 "best practice" 来处理这个问题,这令人惊讶。我知道如果你在视网膜设备上查看他们的网站,apple.com 会提供视网膜图像,但我不知道他们是怎么做到的(Example: store photo). I have found a script that lazy loads retina images (on jsfiddle, so I'm not going to link and clutter this post with code), but it's triggered by scrolling and I don't know how to rework the code to load them after the page content instead. Here's another lazy loader 使用 jQuery 虽然我没能让它为我工作,我再次不知道如何让它在页面内容之后加载,我也不知道如何使图像淡入现有的低分辨率图像,我也不知道如何结合视网膜显示检测。

没有太多 javascript 知识的人是否有希望能够使用一些现有代码来实现这一目标,或者我应该继续我在 Lowres Land 的微薄生存?

编辑:我认为比 "lazy loading" 更相关的术语可能是 "deferred loading"。我发现延迟加载通常是指在向下滚动页面时呈现的内容。我已经完善了我的搜索。请问post这里有什么发现。我目前正在阅读this,但还没有完全消化。

Edit2:我认为 jQuery 的 deferred 和 fadeIn 一起(与视网膜的媒体查询)可能有答案。我在 jQuery 文档中发现 an example 看起来像是我想要的变体。 但就将所有这些联系在一起而言,我无法理解。

我建议使用 progressive jpeg,因为我认为它适合您的用例。即使对于大图像,渐进式 jpeg 加载时也会提供良好的体验。

此外,与其使用媒体查询来确定图像大小,不如尝试使用 srcset 属性。使用 srcset 时,浏览器将在确定最适合客户端的图像 url 方面完成繁重的工作。

虽然目前只有 browser support there is a polyfill 可用。

首先你应该认真研究 lazySizes。这是一个延迟加载器,它建立在 HTML5 响应式图像标准(和所有 polyfills)之上,还支持将低质量图像交换为高质量图像。 (这称为低质量图像占位符模式或短 LQIP)。

下面是静态宽度图像的示例:

<img src="low-quality.jpg" data-srcset="normal.jpg 1x, retina.jpg 2x" class="lazyload" />

这里是自适应宽度图像:

<img src="low-quality.jpg" data-srcset="low-quality.jpg 300w, image-1 480w, image-2.jpg 600w, image-3.jpg 980w" data-sizes="auto" class="lazyload" />

关于你想做什么的部分内容不清楚或不太好。

  1. 您的 LQIP 计划: 如果您有很多图像(例如页面上超过 6 张图像)。我不会对所有图像都使用 LQIP,而只会对关键图像或 none 使用 LQIP,因为如果添加大量图像,它们仍然需要下载,并且浏览器一次只能处理 6 个请求。这意味着如果您使用大量小图像收集页面,您将不会获得太多性能。在那种情况下,最好根本不下载图像,只加载尽快看到的图像。

  2. 内容后的图片: 我不太确定我是否理解正确。普通图像是内容,从感知性能的角度来看,图像是 most important parts of a page. So what other content are you loading? Or what other content is currently loaded after your images? Do you load your content with AJAX? It is crucial to load visible images as fast as possible. And if you trigger an image download via JS it is already hidden from the preload parser,即使您立即启动它,这也意味着它已经在浏览器的下载队列中延迟。此外,如果您有 1-3 张图像在视图中,大约 10 张图像在视图之外,那么仅下载这 1-3 张图像已经是很大的改进了。

综上所述,如果您想进一步延迟加载可见图像,您可以在一段时间后甚至在 onload 之后简单地添加 class lazyload事件。

举个例子:

<img src="low-quality.jpg" data-srcset="low-quality.jpg 300w, image-1 480w, image-2.jpg 600w, image-3.jpg 980w" data-sizes="auto" class="big-bg" />

这里是 JS:

$(window).on('load', function(){
     $('.big-bg').addClass('lazyload');
});

这里是一个完整的示例,其中还包括使用 CSS 的简单过渡效果: http://embed.plnkr.co/9tii4RTjYL2CpiQdXlbn/preview