JavaScript 框架生态系统中的合规性
在我们的介绍博文中,我们介绍了在构建和使用框架和工具来开发和维护 Google 搜索、Google 地图、Google 相册等大型 Web 应用的过程中,我们学到了许多知识。通过防止开发者编写会对用户体验产生负面影响的代码,我们证明了框架在提升性能和应用质量方面发挥着关键作用。
在 Google 内部,我们使用“合规性”一词来描述这种方法,本文将介绍我们如何计划将此概念开源到 JavaScript 框架生态系统。
什么是合规性?
在 Google 内部,合规性是一个演变过程。团队依赖于一小部分经验丰富的维护人员进行广泛的代码审核,不仅会标记影响应用质量和可维护性的问题,还会标记正确性问题。为了将此流程扩展到不断壮大的应用开发者团队,我们开发了一套合规性系统,以便以自动化且可强制执行的方式编纂最佳实践。这样一来,无论代码贡献者的数量如何,应用质量和代码库可维护性始终保持着较高的水准。
合规性是一种机制,可确保开发者始终走在正确的道路上;它有助于建立信心,并确保可预测的结果。它可以提高团队的工作效率,并在团队不断壮大且同时开发更多功能时,成为扩展的关键因素。它让开发者能够专注于构建产品功能,从而摆脱各种细节以及性能、无障碍功能、安全性等各个领域不断变化的形势。任何人都可以随时选择停用合规性,并且它应可自定义,以便团队可以选择强制执行他们决定承诺的任何事项。
合规性基于强制性默认值,并提供可在创作时强制执行的切实可行的规则。这可分为以下 3 个原则。
1. 强制性默认值
合规性的一项基本要素是确保开发者使用的工具具有强大的默认设置。这意味着,解决方案不仅内置于框架中,而且框架设计模式可让您轻松做正确的事情,而难以遵循反模式。该框架可为开发者提供应用设计和代码结构方面的支持。
为了提升加载性能,应优化每个资源(字体、CSS、JavaScript、图片等)。 这是一个复杂的挑战,涉及减少字节、减少往返次数,以及分离首次渲染、视觉准备情况和用户互动所需的内容。例如,提取关键 CSS 并为重要图片设置优先级。
2. 可操作的规则
即使完成了基础优化,开发者仍需要做出选择。在优化方面,需要开发者提供多少信息,这取决于多种因素:
- 无需开发者输入的默认设置,例如内嵌关键 CSS。
- 需要开发者选择启用。例如,使用框架提供的图片组件来调整图片大小和缩放图片。
- 需要开发者选择启用并进行自定义。例如,标记要提前加载的重要图片。
- 不是特定功能,而是仍需要开发者做出决定的事项。例如,避免使用会延迟提前呈现的字体或同步脚本。
需要开发者做出任何决策的优化会对应用的性能造成风险。随着功能的增加和团队的扩大,即使是最有经验的开发者也无法跟上不断变化的最佳实践,这也不是他们最有效的利用时间的方式。对于合规性,适当的可操作规则与强制性默认值一样重要,可确保即使开发者继续进行更改,应用也能继续符合特定标准。
3. 创作时间
请务必在开发生命周期的早期发现并排除性能问题。在提交代码之前的编写时间非常适合发现和解决问题。在开发生命周期中发现问题的时间越晚,解决问题的难度和成本就越高。虽然这适用于正确性问题,但也适用于性能问题,因为许多此类问题一旦提交到代码库,就无法回溯解决。
目前,大多数性能反馈都是通过文档、一次性审核等非正规渠道提供的,或者在部署到生产环境后通过指标回归过晚才显示。我们希望在创作时提供此功能。
框架中的合规性
为了保持高水准的加载性能用户体验,需要回答以下问题:
- 什么是最佳加载?哪些常见问题可能会对其产生不利影响?
- 哪些解决方案可以内置,而无需任何开发者输入?
- 如何确保开发者使用这些解决方案并充分利用它们?
- 开发者还可以做出哪些其他选择来影响加载性能?
- 在编写代码时,哪些代码模式可以让我们尽早了解这些选择(上述第 3 点和第 4 点)?
- 我们可以制定哪些规则来评估这些代码模式?如何在编写时向开发者显示这些信息,同时无缝集成到其工作流中?
为了将 Google 内部的一致性模型引入到开源框架,我们的团队在 Next.js 中进行了大量实验,现在很高兴能分享我们经过优化的愿景和计划。我们发现,评估代码模式的最佳规则组合需要结合使用静态代码分析和动态检查。这些规则可跨多个平台,包括:
- ESLint
- TypeScript
- 用户开发服务器中的动态检查(在创建 DOM 后)
- 模块打包器 (webpack)
- CSS 工具(仍处于探索阶段)
通过利用通过不同工具提供规则的优势,我们可以确保规则具有一致性,同时涵盖直接影响加载性能的所有用户体验问题。此外,这些规则还可能会在不同时间向开发者显示:
- 在开发服务器中进行本地开发时,浏览器和用户的 IDE 会显示警告,提示开发者进行小规模的代码更改。
- 在构建时,未解决的问题将再次显示在用户的终端中
简而言之,团队将选择他们关注的结果(例如核心网页指标或加载性能),并启用相关规则集供所有代码贡献者遵循。
虽然这对于新项目非常有用,但要升级大型代码库以遵循完整的规则集并不容易。Google 拥有一套完善的系统,可在不同级别(例如单行源代码、整个目录、旧版代码库或处于非活跃开发阶段的应用部分)选择停用。我们正在积极探索有效的策略,以便使用开源框架为团队提供此功能。
Next.js 中的合规性
ESLint 在 JavaScript 开发者中广泛使用,超过 50% 的 Next.js 应用在其构建工作流的某些部分使用 ESLint。Next.js v11 引入了开箱即用的 ESLint 支持,其中包括自定义插件和可共享的配置,以便在开发和构建期间更轻松地发现特定于框架的常见问题。这有助于开发者在编写时修复重大问题。例如,某个组件以可能损害性能的方式使用或未使用(如网页没有 HTML 链接)。或者,某种字体、样式表或脚本可能会对网页上的资源加载产生负面影响。例如,无同步脚本。
除了 ESLint 之外,从 v9 开始,Next.js 还支持在开发环境和生产环境中进行集成类型检查,并支持 TypeScript。框架提供的多个组件(图片、脚本、链接)已构建为 HTML 元素 (<img>
、<script>
、<a>
) 的扩展,以便为开发者提供一种高性能的方法来向网页添加内容。类型检查可确保分配的属性和选项在支持的值和类型的可接受范围内,从而支持正确使用这些功能。如需查看示例,请参阅必需的图片宽度和高度。
使用 Toast 和叠加层显示错误
如前所述,合规性规则可在多个方面显示。目前,我们正在探索使用 Toast 和叠加层来直接在用户的本地开发环境中的浏览器中显示错误。
开发者依赖的许多错误检查和审核工具(Lighthouse、Chrome 开发者工具“问题”标签页)都是被动的,需要用户以某种方式进行互动才能检索信息。如果错误直接显示在现有工具中,并且提供应采取的具体操作来解决问题,开发者就更有可能采取行动。
其他框架中的合规性
我们将首先在 Next.js 中探索合规性,以便扩展到其他框架(Nuxt、Angular 等)。ESLint 和 TypeScript 已在许多框架中以许多不同的方式使用,但我们正在积极探索协调一致的浏览器级运行时系统的概念。
总结
合规性将最佳实践编码为规则集,以便开发者以简单的代码模式加以利用。Aurora 团队专注于加载性能,但其他最佳实践(例如无障碍功能和安全性)同样适用。
遵循合规性规则应该会带来可预测的结果,而实现高水准的用户体验可能是构建技术栈的副作用。合规性有助于提高团队的工作效率,并确保应用达到高质量标准,即使团队和代码库随着时间的推移而不断扩大也是如此。