框架一致性

JavaScript 框架生态系统中的一致性

Shubhie Panicker
Shubhie Panicker

简介博文中,我们介绍了在构建和使用框架及工具以开发和维护大型 Web 应用(例如 Google 搜索、地图、Google 相册等)的过程中,我们学到了很多知识。通过防止开发者编写可能对用户体验产生负面影响的代码,我们证明了框架可以在性能和应用质量方面的变化方面发挥关键作用。

在 Google 内部,我们使用“一致性”一词来描述此方法,并且本文介绍了我们计划如何将此概念开源给 JavaScript 框架生态系统。

什么是一致性?

在 Google,合规性是一种演变。这些团队依赖了一小部分经验丰富的维护人员,他们进行了大量代码审核,标记出影响应用质量和可维护性的问题(不仅限于正确性问题)。为了适应不断壮大的应用开发者团队,我们开发了一个一致性系统,以自动化且可强制执行的方式将最佳实践标准化。这可确保无论代码贡献者有多少,应用质量和代码库可维护性始终保持高标准。

一致性可确保开发者始终遵循良好的发展路径;它可以建立信心并确保结果可预测。随着团队的成长和同步开发更多功能,这种方式可以提高团队的工作效率,对规模变得至关重要。它使开发者能够专注于构建产品功能,使其摆脱性能、无障碍功能、安全性等各个方面(如性能、无障碍功能、安全性等)的细枝末节和不断变化的环境。任何人都可以随时选择退出合规性,并且应该可以自定义,团队可以选择强制执行他们决定承诺的内容。

一致性基于强默认值,并提供可在编写时强制执行的可操作规则。这分为以下 3 项原则。

1. 强有力的默认值

合规性的一个基本方面是确保开发者使用的工具具有强有力的默认值。这意味着解决方案不仅被融入到框架中,而且框架设计模式还使开发者能够轻松做正确的事,并难以遵循反模式。该框架可为开发者提供应用设计和代码结构方面的支持。

为了提升加载性能,应优化每种资源(字体、CSS、JavaScript、图片等)。这是一个复杂的挑战,涉及删减字节、减少往返,以及分离首次渲染、视觉准备和用户互动所需的内容。例如,提取关键 CSS 以及设置重要图片的优先级。

2. 可操作的规则

即使已经进行基本的优化,开发者仍然必须做出选择。当涉及到所需的开发者输入量时,有各种可能的优化机会:

  • 无需开发者输入(例如内嵌关键 CSS)的默认设置。
  • 需要开发者选择启用。例如,使用框架提供的图片组件调整图片大小和缩放比例。
  • 需要开发者选择启用和自定义。例如,标记要尽早加载的重要图片。
  • 不是具体功能,而是需要开发者自行决定的功能。例如,避免使用会延迟提前渲染的字体或同步脚本。

此图显示了自动和手动开发者优化之间的范围

需要开发者做出任何决策的优化都会给应用的性能带来风险。随着功能的不断添加和团队规模的扩大,即使是最有经验的开发者也无法跟上不断变化的最佳实践,也无法充分利用他们的时间。为了保证一致性,适当的可操作规则与强有力的默认值一样重要,可以确保即使开发者继续进行更改,应用也能继续满足特定标准。

3. 编写时间

请务必在开发生命周期的早期发现和排除性能问题。在提交代码之前编写代码,非常适合用于发现和解决问题。在开发生命周期中发现的问题越晚,解决问题就越困难,成本也就越高。虽然这适用于正确性问题,但性能问题也是如此,因为许多此类问题在提交到代码库后将无法追溯解决。

如今,大多数性能反馈都是通过文档记录或一次性审核实现的,或者在部署到生产环境后通过指标回归出现过晚。我们希望在创作时能够实现这一点。

框架中的一致性

为了保持高水平的用户体验,以便提升加载性能,需要回答以下问题:

  1. 怎样才算最佳加载?哪些常见问题可能会对加载次数产生不利影响?
  2. 哪些解决方案可以包含在不需要开发者输入的情况下?
  3. 我们如何确保开发者使用这些解决方案并以最佳方式利用它们?
  4. 该开发者还可以做出哪些影响加载性能的选择?
  5. 在写作的早期,有哪些代码模式可以让我们了解这些选择(上述第 3 和第 4 条)?
  6. 我们可以制定哪些规则来评估这些代码模式?如何在创作时向开发者呈现,同时又能无缝集成到工作流中?

为了将 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 开始,具备 TypeScript 支持的 Next.js 也在开发和生产环境中支持集成式类型检查。该框架提供的多个组件(图片、脚本、链接)已构建为 HTML 元素(<img><script><a>)的扩展,以便为开发者提供向网页添加内容的高效方法。类型检查确保分配的属性和选项在支持的值和类型的可接受范围内,从而支持这些功能的正确使用。如需查看示例,请参阅所需的图片宽度和高度

使用消息框和叠加层显示错误

如前所述,一致性规则可以出现在多个区域。我们正在探索消息框和叠加层,作为在用户本地开发环境中直接在浏览器中显示错误的方法。

通过消息框显示的错误

开发者依赖的许多错误检查和审核工具(Lighthouse,Chrome 开发者工具的“问题”标签页)都是被动的,需要通过某种形式的用户互动来检索信息。如果开发者直接在其现有工具中发现错误,并且提供了解决问题所应采取的具体措施,开发者更有可能采取行动。

其他框架中的一致性

我们首先在 Next.js 中探索一致性,以扩展到其他框架(Nuxt、Angular 等)。ESLint 和 TypeScript 以许多不同的方式在许多框架中使用,但一个统一的浏览器级运行时系统的概念也在积极探索。

总结

一致性将最佳实践编码成规则集,以简单代码模式的形式提供给开发者。Aurora 团队将重点放在加载性能上,但其他最佳实践(例如无障碍功能和安全)同样适用。

遵循一致性规则应该会产生可预测的结果,实现高标准的用户体验可能会成为在技术栈上构建应用的附带效应。一致性可让团队提高工作效率,并确保应用具有较高的质量标准,即使团队和代码库随时间推移而变化也是如此。