纯HTML的条件性延迟加载方案(通过preload + media条件查询实现)

存在一个看似有效的变通方案:浏览器不会延迟已获取图片的加载。

常规做法是不对折叠区内的图片添加懒加载,尤其是LCP关键内容图片,因为这会延迟加载直至浏览器确认其完全进入视口。但问题在于“折叠区”取决于屏幕尺寸:同一张图片在桌面端可能位于折叠区上方,在移动端却可能位于下方。采用原生延迟加载与静态HTML(例如不使用服务器端设备检测或JavaScript)时,通常只能选择一种行为模式,这必然导致部分用户体验受损。

但存在一个看似有效的变通方案:浏览器不会延迟已获取图片的加载。可通过媒体查询条件性预加载图片,随后再标记为懒加载。我通过HTTP链接头进行了测试,但<link rel="preload">标签同样适用。

概念说明:

Link: </hero.jpg>; rel=preload; as=image; media="(min-width: 1024px)"
<img src="/hero.jpg" loading="lazy" />

效果:

桌面端:预加载触发 → 图片立即加载(利于LCP指标)

移动端:忽略预加载 → 图片延迟加载

在此布局中,封面图片在桌面端位于折叠线以上,但在较小设备上则不在——因此它在Lighthouse推荐的位置被积极加载,而在合理位置采用延迟加载。

注意事项:

  • 未见任何文档或讨论(但在主流浏览器中运行良好)
  • 需要预加载,这可能并不总是实用(或符合预期)

但这实现了纯HTML的视口依赖型延迟加载。

元素周期表抱枕

共有{25}精彩评论

  1. 行业惯例是不对折叠区内的图片添加懒加载,尤其是最大内容绘制(LCP)图片。

    我此前并不知晓。据克劳德所述,对于预期始终显示的图片不应使用loading=“lazy”属性,因为这会导致图片在浏览器确认其完全进入视口前不会加载,从而造成轻微性能退化。

    LCP = Largest Contentful Paint(最大内容绘制),这是核心网络指标中衡量最大视觉元素完成渲染的时间点,通常对应折叠线以上的最大图片。

    • 没错,但该帖子明确讨论的是仅在特定设备/屏幕尺寸下初始加载的图片,因此需要条件性应用懒加载。

    • 尝试对LCP图像进行延迟加载可能导致其加载延迟高达15%[1]。

      延迟加载是延缓页面初始加载中非关键资源的有效技术。但当应用于LCP图像时会引发显著问题。延迟加载会阻止浏览器立即加载图片,因为它需要时间识别图片是否进入视口区域并需要加载。根据实验室测试,这可能导致LCP性能下降15%。对于从事网页性能优化的人员而言这似乎显而易见,但近五分之一的网页存在此问题的事实表明,大多数开发者对此理解不足。

      [1]: https://calendar.perfplanet.com/2022/lazy-loading-lcp-images

  2. 我欣赏这个方案,它看似简洁,若技术可行本应纳入最佳实践范畴。但我也认为这种权衡机制从根本上存在缺陷——浏览器本应通过内置规则默认决定是否渲染图片,而开发者主动加载图片的决策仅应作为开发者留的后门。当前方案强行将决策权推给应用程序,迫使开发者猜测当前市场设备组合的最佳方案,这带来了持续的维护负担。

    • 浏览器早已具备预扫描机制,能提前识别需加载的元素(如图片),并搭载大量启发式算法。这些启发式算法之所以复杂,部分原因在于许多HTML作者不愿标注图片尺寸。lazy属性能避免加载作者确定不会出现在初始视口范围内的图片,因此可作为优化提示来覆盖部分启发式规则。这既节省带宽,又确保折叠线以上内容在初始视口构建时不会与折叠线以下内容争夺资源。这里涉及两层优化机制,不过浏览器在接收到规范的img标签时本就表现良好。

  3. > 未见任何文档记载(但在主流浏览器中运行良好)

    具体哪部分未被记录?是将设备宽度相关的预加载指令放入HTTP头部吗?MDN文档指出HTTP链接头与link元素具有相同机制,且link元素的a属性支持media属性:https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/

    • 我指的就是这个技巧既未见文档记载也未见讨论。

      • 这并非技巧,但你可能找到更多关于用<link>标签表达等效预加载值的文档。该标签与HTTP Link头几乎完全等效。文章中使用的值在HTML中同样有效。

  4. 纯声明式的响应式优化很棒!

  5. 我不喜欢延迟加载。我的时间比带宽更宝贵。

  6. 纯声明式的响应式优化很棒!

  7. 我不喜欢延迟加载。我的时间比带宽更宝贵。

    • 这很大程度上取决于个人价值取向。我讨厌那些急于加载折叠区下方所有图片的网站,因为我的手机使用的是流量套餐。在许多国家,无限流量套餐仍不常见或价格高昂。例如我每月支付13美元获得650MB流量,这已是所有运营商中最划算的套餐之一(低于40美元/月)。

    • 那你不是应该喜欢这种设计吗?它能节省你的时间,因为页面加载得更快。

  8. 我觉得这行不通。

    我刚用Chrome Android通过远程检查工具测试过,即使图片位于折叠区下方,它依然会加载。

  9. 是否因为链接中的“min-width=1024px”导致小屏幕设备无法加载?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注


京ICP备12002735号