兼容性基准线与 Polyfill 的实践指南

作者:林语者 分类:工程代码

发布时间:2025 年 3 月 18 日

什么是 Polyfill?

Polyfill(垫片)长期被集成在 Web 开发者的工具链中,用于为某些浏览器不支持的功能提供兼容实现。虽然 Polyfill 看似是 Web 开发工具箱中不可或缺的工具,但将这类复杂问题归结为一条明确的规则几乎是不可能的。

是否使用 Polyfill 取决于功能在浏览器间的可用性,而 Baseline(基线)可为此判断提供依据。Baseline 本身不决定是否使用 Polyfill,但它能清晰展示 Web 平台功能的支持状态,帮助开发者更精准地决策。过度使用 Polyfill 可能会给应用程序带来显著的负面影响。

Polyfill 是一段用于检测浏览器是否支持某项功能的代码。如果功能不被支持,它会尝试通过 JavaScript 提供缺失的实现。

早期的 Polyfill 例子之一是 Matchmedia.js,它通过 JavaScript 检测 matchMedia 方法是否存在,并在不支持时提供实现。matchMedia 允许开发者在 JavaScript 中评估媒体查询是否与当前视口状态匹配。通过加载 Polyfill 补全缺失功能,开发者就能在所有浏览器中使用 matchMedia。不过,由于目前绝大多数浏览器都已原生支持 matchMedia,该 Polyfill 现已不再必要。

虽然为不支持的功能添加支持有其价值,但 Polyfill 的缺点却常被忽视。随着 Web 应用中 Polyfill 数量的增加,其负面影响也会逐渐显现。

Polyfill 的缺点有哪些?

相较于浏览器原生支持的功能,Polyfill 的实现始终会带来额外开销,且这种成本会随着引入 Polyfill 数量的增加而累积。

由于 Polyfill 由 JavaScript 编写,向 Web 应用添加额外的 JavaScript 可能会对性能产生以下影响:

  • 阻塞渲染
  • 因额外的解析和编译工作,引入长时间任务,阻塞主线程

若 Polyfill 未能完全遵循其模拟功能的规范,还可能影响可访问性。某些功能会以 Polyfill 无法干预的方式修改可访问性树。

与浏览器原生实现相比,Polyfill 可能无法完全复现目标功能的所有方面,这会导致用户体验以意料之外的方式受影响,或限制可用功能的范围。

容器查询 Polyfill 便是一个存在上述缺点的例子。容器查询允许开发者基于 HTML 元素自身的状态(而非视口状态)应用 CSS 规则。该 Polyfill 利用 ResizeObserverMutationObserver API 模拟容器查询功能。特别地,由于 ResizeObserver 的回调恰好在浏览器绘制新帧之前触发,这会增加显示延迟。在优化下一次绘制之前的交互(INP)时,这是一个重要的考量因素。

除了性能问题,容器查询的某些方面是 Polyfill 无法实现的。虽然并非所有 Polyfill 都会导致用户体验问题或不完整的实现,但引入的 Polyfill 越多,应用程序受负面影响的风险就越高。

Baseline 的作用

以往,虽然 browser-compat-data 等数据源被各类工具采用,帮助开发者做出复杂决策,但要准确评估某项 Web 功能是否可以安全使用仍非易事。Can I Use 就是使用此类数据展示 Web 功能支持度的常见矩阵。

Baseline 在此基础上更进一步,通过三种状态指示器,为所有浏览器均支持的功能提供清晰、一致的信息标识:

  • 有限可用:该功能尚未被所有主流浏览器支持
  • 新近可用:该功能在过去 30 个月内被所有主流浏览器引入
  • 广泛可用:该功能已在所有主流浏览器中稳定支持超过 30 个月

Baseline 不将 Polyfill 视为功能支持的一部分。例如,即使某功能在所有浏览器中均可通过 Polyfill 实现,只要其原生支持范围有限,就不会被标记为“新近可用”或“广泛可用”。判断功能是否“新近”或“广泛”可用的关键在于其是否在所有主流浏览器中得到了完整原生实现。这有助于开发者清晰判断哪些功能可以安全使用,以及是否需要借助 Polyfill。

确定 Baseline 阈值

Baseline 的主要优势在于减少开发工作流中需要考量的因素数量。如果您希望无需关心 Polyfill,直接采用“广泛可用”级别以上的功能,那么只需关注该级别之外功能的状态即可。Baseline 在决定如何处理新近可用功能时尤为有用。

一旦某功能在所有目标浏览器中均获支持,它便进入“新近可用”状态。但这并不意味着所有用户在所有浏览器中第一天就能使用该功能。大多数浏览器虽会自动更新,但更新覆盖全体用户仍需时间。其中一个考量因素是,某些设备的浏览器版本与操作系统版本绑定。在此情况下,用户只有在更换设备后才能获得操作系统更新。

Baseline 功能在经历足够时间、成为通用功能集的一部分之前,会按年度分组(如 Baseline 2025、Baseline 2024 等)。将此信息与您的用户数据结合,您就能更明智地决定是直接使用新近可用功能,还是配合 Polyfill 使用。

确定 Baseline 阈值的最佳数据源是您网站的实际用户数据。该领域的工具正逐步集成 Baseline 阈值数据,例如 RUMvision 便是提供此类信息的产品之一。

RUMvision 的解决方案允许您查看支持特定 Web 功能的用户比例。您可借此搜索具体功能,并在决策时参考更多数据。

在 RUMvision 中,您不仅可以查看单个功能的支持情况,还能按年份查看支持特定 Baseline 功能集的用户百分比。

如果您的站点尚未收集 RUM(真实用户监控)数据,RUM 洞察可提供各 Baseline 功能集支持情况的宏观概览。例如,处于通用可用期内的 Baseline 阈值功能,其用户支持率通常超过 98%,而在最早阶段,接近 100% 的用户都支持这些功能。

虽然判断功能支持的方法可以灵活选择,但通常用户支持率越接近 100%,您无需 Polyfill 即可使用该 Baseline Web 功能的可能性就越高。一般来说,当某功能在 98% 或 99% 用户使用的浏览器中得到支持时,您可以较安全地使用它。但同时也需考虑这对少数不支持的用户意味着什么。

何时应该或不应该使用 Polyfill?

是否使用 Polyfill 很大程度上是基于主观判断,并完全取决于 Web 应用的具体需求。然而,鉴于其可能对用户体验产生负面影响,我们应尽可能避免使用。明确功能是否已达到 Baseline 的“新近可用”或“广泛可用”状态,是做出此决定的重要依据。

假设您正在考虑一个 Baseline 新近可用的功能,但当前数据显示仅有 95% 的用户支持它——这意味着 5%(即每 20 人中有 1 人)使用的浏览器不支持此功能。但这并不自动意味着需要 Polyfill,因为需求因功能而异。您还需评估用户在不支持该功能且无 Polyfill 的情况下的体验影响。

尽管判断是否使用 Polyfill 可能具有挑战性,但一个好的思路是:评估功能对不支持浏览器用户的影响程度,以及这种影响是否足以证明使用 Polyfill 是合理的。

注意:此评估前提是您考虑使用 Polyfill 的功能本身是可以通过 Polyfill 实现的。并非所有 Web 功能都能被 Polyfill。

基于此评估框架,可将功能归为以下三类:

  • 功能增强:此类功能在提升用户体验的同时,不会导致视觉变化或功能降级。如果用户无法看到此功能,他们可能根本不会察觉。对于此类功能,即使缺失,也通常不需要使用 Polyfill。
  • 附加功能:这类功能可能影响网页的外观或交互,但不会引发严重问题。事实上,除非用户在另一个支持该功能的浏览器中进行对比,否则他们可能不会注意到该功能的存在。如果 Polyfill 可用,建议尽量避免使用,尤其是在已经为许多其他功能引入 Polyfill 的情况下。额外添加 Polyfill 通常只会带来性能损耗。
  • 必需功能:此类功能若缺失,将导致不可接受的后果,例如 JavaScript 执行错误、布局错乱等,从而损害用户体验。在这种情况下,您应选择使用 Polyfill,或考虑其他替代方案而不使用该功能。

判断功能属于哪一类别有时并不容易,以下是一些具体示例:

  • 功能增强的示例通常与性能相关,例如 fetchpriority 或 HTTP/3。这类功能可提升页面性能,从而改善用户体验,但对于使用不支持浏览器的用户,通常不会产生明显的负面体验。
  • 附加功能的示例包括提升页面视觉吸引力的功能,如色彩空间与颜色函数、subgrid 等。它们属于锦上添花型的功能,用户在不支持时通常难以察觉。
  • 引入关键功能则属于必需功能。例如,某些 HTML 元素若缺失,可能导致次优的用户体验。如果某项功能的缺失会损害部分浏览器上的用户体验,项目相关方可能难以接受。

通常,您可以根据功能的 Baseline 状态来评估其类别归属:

  • 若功能已广泛可用,通常无需使用 Polyfill,除非用户数据明确显示有此必要。
  • 若功能属新近可用,则它很可能即将获得广泛支持。此时应利用用户支持数据,判断遵循哪个 Baseline 阈值最有利于减少干扰或避免不可接受的后果,同时理解其支持度会随时间推移逐步接近 100%。
  • 若功能仅有限可用,则用户遇到问题的风险最高。因此,即使有可用的 Polyfill,也应审慎考虑。

是否应该使用有限可用的功能?

答案是“可以”,但需注意以下几点:

  • 有限可用的 Baseline 功能并不保证在未来会进入“新近可用”状态。必须仔细评估其对用户体验的潜在影响。
  • 若决定结合 Polyfill 使用有限可用功能,应注意除非您有条件地按需加载 Polyfill,否则所有用户都将承担额外的资源开销。即便如此,需要这些功能的用户仍将承受相应的性能成本。
  • 除性能成本外,需要 Polyfill 的用户还可能面临功能实现不完整或与原生实现存在差异的问题,这可能会影响功能本身,甚至波及可访问性。
  • 有限可用功能的行为可能发生变化。特别是那些仅在某一个浏览器引擎中实现的功能,当其他浏览器也开始支持时,其规范或行为可能调整,导致您的代码或 Polyfill 与之不同步。

除非您的用户群体被限制在单一浏览器引擎,否则通常建议优先使用 Baseline 中新近可用,尤其是广泛可用的功能。这意味着您可以将更多时间投入功能使用本身,而非兼容性忧虑,从而将节省的时间用于解决其他问题。

总结

在采用 Web 平台功能时,是否使用 Polyfill 并无绝对规则。与 Web 开发中的所有决策一样,需要仔细权衡利弊。以下是一些可供参考的基本原则:

  • Polyfill 虽有优势,但可能带来性能和可访问性成本,且不一定能完全复现缺失的原生功能。
  • 尽可能使用实际用户数据来确定 Baseline 阈值。若无此数据,建议从广泛可用的 Baseline 功能集开始,并考虑利用 RUM 洞察数据辅助决策。
  • 基于数据评估:若功能不被支持,受影响的用户规模有多大?影响的严重程度如何?
  • 与项目相关方沟通,确认哪些功能符合项目目标与业务需求。
  • 若必须使用有限可用功能,请评估您的受众及使用风险。除非用户被限制在单一浏览器引擎,否则使用 Polyfill 也无法保证完全的兼容性。

正是基于上述原因,Polyfill 未被纳入 Baseline 的考量范围。Baseline 的角色是告知哪些功能已获得所有主流浏览器引擎的原生支持。然而,您仍需了解能使用 Baseline 功能的用户比例,并基于用户与项目需求做出判断。Baseline 的“广泛可用”状态通常是一个安全的默认选择,其在用户中的支持范围往往最为广泛。

当前,Web 平台功能正以前所未有的速度成熟和发展。随着时间推移,互操作性不断提升,广泛受支持的功能也越来越多,这为我们创造了更多机会:能够以更少的 Polyfill,使用更多的 Web 平台功能。

评论

发表评论

正在加载评论...