懒加载(lazy loading)是一种 Web 优化技术,延迟加载不可见资源——图片、视频、组件、数据——直到用户滚动到它们出现的页面区域,从而减少初始加载时间和带宽消耗。
这是很少有团队想听到的悖论:懒加载对用户来说很棒,但对视觉测试来说很糟糕。这项技术设计为不加载内容直到它可见。但视觉测试工具需要看到内容才能测试。两个目标本质上存在张力。
这种张力不是选择其一放弃其另的理由。您的网站需要懒加载来提升性能——Google 的数据很明确,加载时间是 SEO 排名因素,也是跳出率的主要决定因素。您的网站也需要视觉测试来确保懒加载不引入回归——一个永远不消失的占位符、一张以错误尺寸加载的图片、一个内容出现时跳动的布局。
本文解释如何协调两者。
为什么懒加载使视觉测试复杂化
不可见内容无法被测试
懒加载的基本原理是首屏以下的内容在初始加载时不会加载。加载后立即截取的屏幕截图只显示首屏内容——其余部分要么不存在,要么被占位符替代。
这是一个覆盖率问题。如果您的页面高 5,000 像素而视口为 900 像素,初始截图只覆盖页面的 18%。剩余的 82% 未被测试。在电商产品页上,这意味着描述、用户评价、推荐产品和页脚永远不会被视觉验证。
有些团队认为全页截图能解决这个问题。但全页截图不会触发懒加载——它捕获的是截图时刻页面渲染的样子,包含占位符和未加载的元素。您得到的是不完整页面的完整图像。
捕获时机:永恒的两难
到底该在什么时候截取屏幕截图?问题看似简单。实际并非如此。
如果在页面加载后立即截图,您捕获的是带占位符的初始状态。速度快但不完整。如果在截图前滚动到页面底部,您触发所有延迟内容的加载——但当每个资源加载完成时,页面顶部的内容可能已经变化(动画、实时更新、头部重新显示)。
而且,滚动本身会改变页面的外观。一个滚动时出现的固定头部、一个出现的"回到顶部"按钮、一个逐渐填充的阅读进度指示器——所有这些元素都随滚动位置变化,它们在截图时的状态在不同运行间可能不同。
图片占位符和布局偏移
图片懒加载使用占位符在布局中预留空间:灰色矩形、低分辨率模糊(LQIP — Low Quality Image Placeholder)、彩色 SVG,或者干脆什么都不用。当实际图片加载时,它替换占位符。
问题出现在用图片替换占位符时改变了元素的尺寸。这就是臭名昭著的累积布局偏移(CLS)——一种可见的位移,会推移周围元素。如果在偏移过程中截图,您捕获的是一个既非占位符也非最终状态的过渡状态。
Web 最佳实践建议在图片上定义明确的尺寸(HTML 中的 width 和 height)以避免布局偏移。但并非所有团队都遵循这些实践,而且具有可变尺寸的响应式图片使事情更加复杂。
无限滚动:无尽的页面
无限滚动将懒加载问题推向极端。您不再是一个有延迟内容的固定大小页面,而是一个长度潜在无限的页面。每次向下滚动都加载新元素并延长页面。
如何视觉测试一个没有终点的页面?您无法截取全页截图——页面没有"完整"可言。您必须武断地决定何时停止滚动、多少元素构成足够样本、以及如何处理无限滚动加载的内容通常由变化的数据驱动(新文章、新帖子、新产品)这一事实。
无限滚动还造成内存问题。每批加载的内容都向 DOM 添加元素。经过足够多的滚动后,浏览器可能变慢、渲染可能变得不流畅、操作时序可能变化——给您的测试引入不确定性。
视觉测试懒加载内容的策略
策略1:增量滚动与多次捕获
与其寻求一整页的单一截图,不如将页面分成多个段并分别截取每一段。滚动一个视口高度,等待延迟内容加载,截取屏幕截图,然后继续。
这种方法产生一系列截图——视口1、视口2、视口3等——您将它们各自与对应的基线进行比较。每张截图覆盖一个特定页面段,且所有内容已加载。
优点是您获得了完整覆盖率且内容已完全加载。缺点是需要维护多个基线以及管理每次滚动和每次截图之间的时序。滚动后的稳定时间——图片加载、过渡动画完成、布局稳定所需的时间——必须足够但不过长。
对于无限滚动,定义固定滚动次数(例如5或10次)并测试对应的段。您无法测试无限,但可以测试具有代表性的样本。
策略2:捕获前强制完全加载
某些工具允许在测试环境中禁用懒加载。HTML 属性 loading="eager" 强制立即加载所有图片。Intersection Observer 脚本可以被修补为将所有元素视为立即可见。在组件级别实现懒加载的框架如 React 和 Vue 可以配置为在测试模式下加载所有组件。
这种方法将您的懒加载页面转变为完全加载的页面,您可以截取经典的全页截图。简单、直接,解决了覆盖率问题。
但您不再测试懒加载本身。如果您的懒加载实现有缺陷——一个永远不加载的组件、一个一直显示的占位符、一个破坏布局的过渡动画——您在"eager"模式下看不到它。您测试的是内容,不是加载机制。
如果您的目标仅是检测设计中的视觉回归,这是一个可接受的妥协。如果您还想验证懒加载是否正常工作,则需要下一个策略。
策略3:测试过渡状态
不绕过懒加载,而是显式地测试它。在加载周期的每个阶段截取屏幕截图:带占位符的初始状态、加载中(过渡)的状态、以及内容完整的最终状态。
每个状态都有自己的基线。测试初始状态验证占位符是否正确调整大小和定位。测试最终状态验证加载的内容是否正确替换占位符且不破坏布局。过渡测试验证没有过度的布局偏移。
这是最全面的方法,但也是维护成本最高的。每个懒加载组件三个基线意味着设计演进时三倍的维护量。将其保留给懒加载行为对用户体验至关重要的关键组件。
策略4:结构化比较,不关心像素内容
结构化方法优雅地同时解决了多个懒加载问题。它不比较占位符的像素和最终图片的像素,而是比较元素的结构:它的 DOM 位置、计算尺寸、CSS 属性和可见性。
一个正确尺寸的占位符与最终图片占据相同空间——即使像素完全不同,结构也相同。一个正确加载的懒加载组件与其占位符保持相同的位置和尺寸。结构化方法验证这种等价性,而不关心图片的像素内容。
这就是 Delta-QA 原生使用的方法。当一个 400x300 像素的占位符被 400x300 像素的图片替换时,结构没有变化——不告警。当一个 400x300 的占位符被 400x200 的图片替换(纵横比缺陷)时,结构发生变化——合理告警。
无限滚动的特有挑战
无限滚动值得特别关注,因为它将懒加载问题与其独有的挑战结合在一起。
可重复性问题
无限滚动通常从 API 加载分页内容。第2页的内容取决于第1页的内容。如果数据集在两次测试运行之间变化(发布了新文章、移除了产品),页面不会具有相同内容,比较就会失败。
要获得可重复的结果,您必须冻结底层数据。使用一个始终以相同顺序返回相同数据的模拟 API,或者针对具有固定数据集的预发布环境进行测试。
边距渲染和分组问题
无限滚动列表通常显示带分组标题的内容——"今天"、"昨天"、"上周"。这些标题取决于当前日期并逐日变化。一篇"今天"发布的文章明天会在"昨天"标题下。
解决方案与任何时间性内容相同:在测试环境中冻结系统日期。
性能退化问题
经过20或30次连续滚动后,浏览器性能可能因 DOM 元素数量而退化。这种退化影响渲染时序,并可能给您的截图引入不确定性。
设计良好的应用实现了虚拟化——它们只将当前可见的元素保留在 DOM 中,随着用户滚动回收 DOM 节点。如果您的应用虚拟化了 DOM,无论滚动多少次元素数量保持恒定,性能保持稳定。
如果您的应用没有使用虚拟化,在测试中限制滚动次数以保持在可接受的性能范围内。
将懒加载集成到视觉测试策略的实用建议
对于懒加载图片,最低要求是测试最终状态——视口中所有可见图片已加载的状态。使用增量滚动触发加载,等待稳定,然后截取。设定明确期望:视口中的所有图片必须已加载(无可见占位符),且加载后不应发生布局偏移。
对于懒加载组件(代码分割、动态导入),在两种模式下测试:"全部加载"模式用于验证组件渲染,"自然加载"模式用于验证过渡状态和回退。
对于无限滚动,定义现实的测试范围。测试前3到5次加载(滚动),覆盖初始行为、分页逻辑和批次间的过渡。不要尝试测试整个流程——既不实际也不必要。
对于占位符,显式测试它们。占位符是用户体验的一部分——尺寸不当的占位符导致布局偏移,缺失的占位符在页面中留下白色空白。截取初始状态(滚动前)的屏幕截图并验证占位符是否正确调整大小和定位。
对于时序,优先使用条件等待而非固定延迟。等待图片加载完成(通过 img 元素上的 load 事件)而非等待任意秒数。固定延迟很脆弱——2秒在本地可能够用,在 CI 负载下可能不足。
懒加载是盟友,不是敌人
懒加载优化您网站的性能。它减少初始加载时间、带宽消耗和客户端资源使用。这些都是对用户真实且可衡量的益处。
它使视觉测试复杂化这一事实不是放弃它的理由——而是调整测试策略的理由。现代视觉测试工具,尤其是 Delta-QA,正是为此而设计,无需您在性能和可测试性之间做选择。
懒加载不是视觉测试的障碍。它是一个有技术解决方案的技术约束。实现它们,您就能两全其美:快速页面和可靠测试。
常见问题
懒加载是否使全页视觉测试不可能?
不,但它需要与经典全页截图不同的方法。要么在截图前强制完全加载(loading="eager"),要么逐步滚动,分别截取每一段。两种方法都提供完整覆盖率——第一种更简单,第二种更忠实于页面实际行为。
如何视觉测试无限滚动页面?
定义现实的测试范围:3到5次滚动覆盖初始行为、分页逻辑和批次间过渡。使用模拟数据保证可重复性。将每段作为独立截图捕获,配以各自基线。不要尝试测试无限——测试一个具有代表性的可靠样本。
是否应在测试环境中禁用懒加载?
取决于您的目标。如果您测试内容(检测设计中的视觉回归),禁用懒加载以简化截图。如果您测试加载机制(验证占位符、过渡和延迟加载是否正常),保持懒加载启用并显式测试不同状态。
如何处理延迟加载图片导致的布局偏移?
始终在图片上定义明确的尺寸(width 和 height)以在布局中预留空间。使用与最终图片同尺寸的占位符(LQIP 或彩色矩形)。视觉测试初始状态(带占位符)和最终状态(带图片)以验证尺寸不变且无偏移发生。
懒加载的视觉测试比经典测试慢吗?
是的,不可避免。每步带加载等待的增量滚动比瞬间捕获完全加载的页面需要更多时间。这是完整覆盖率的代价。通过并行化测试、将滚动次数限制到最低限度、使用条件等待而非固定延迟来最小化等待时间来优化。
Delta-QA 能处理懒加载和无限滚动吗?
能。Delta-QA 的结构化方法特别适合懒加载,因为它比较的是结构而非像素。正确尺寸的占位符和最终图片具有相同结构——无误报。工具处理增量滚动、加载等待和段比较,全部无需编写一行代码。
延伸阅读
懒加载优化您网站的性能。Delta-QA 确保它不会引入视觉回归。 两者并非矛盾——它们互补。用测试静态页面同样的严谨度来测试您的动态页面。