那么,人们可以做些什么来改善他们的网站呢?为了回答这个问题,让我们回到过去...
时间是 1998 年,网络正在兴起。为了试图对 WWW 的架构进行高层次的概述,蒂姆·伯纳斯·李——没错,就是 *那个* 蒂姆·伯纳斯·李——发表了一篇名为 “从 50,000 英尺看 Web 架构” 的论文。该报告涵盖了许多内容:内容协商、语义网、HTML、CSS 和酷炫的 URI (不会改变),等等。
在文章中,伯纳斯·李还 记录了一些非常早期的设计原则。其中一个原则是 “最小能力原则”。
最小能力原则如下
在设计计算机系统时,人们经常面临在使用功能更强大或功能更弱的语言来发布信息、表达约束或解决某些问题之间的选择。[...] “最小能力原则”建议选择最适合特定目的的最小功能语言。
我们在网络前端有三种主要语言可用
HTML
语义地描述内容
CSS
控制演示和布局
JavaScript
添加交互性和行为
最小能力原则建议尝试尽可能多地使用 HTML,然后再求助于 CSS。一旦 CSS 不再足够,就使用 JavaScript——但只有在真正需要的时候。
正如 Derek Featherstone 很好地 所说
在 Web 前端栈中——HTML、CSS、JS 和 ARIA——如果您可以在栈中使用更简单的解决方案来解决问题,您应该这样做。它更不易碎、更可靠,而且只需运行即可。
💡 **等等:** 这并不意味着您应该通过标记设置字体大小和颜色——这是我们在网络的“旧时代”所做的事情。例如:伯纳斯·李在他的文章中提到的一个规则是 形式和内容的分离。
破碎的网络
伯纳斯·李发表那篇文章已经快 25 年了。然而,不知何故,他发送的信息没有传达出去,许多开发人员——但不是全部——对此一无所知。看看 Drew Devault 不久前遇到的情况
我的浏览器在过去 28 年中一直能够完美地提交 HTML 表单,但出于某些愚蠢的原因,一些开发人员决定用 JavaScript 重新实现表单,现在我无法在不打开开发工具的情况下支付电费。
可悲的是,这不是孤立的事件,而是一种熟悉的现象。我经常看到试图变得聪明或试图重新发明轮子的网站和库——主要是通过向其添加一堆 JavaScript。在他们试图这样做的过程中,他们实现了与他们的目标完全相反的结果:这些网站变得功能更少、可访问性更差,或者——更糟糕的是——在某些条件下根本无法工作。
虽然表单可能是一个熟悉的例子,但还有更多情况表明,应用最小能力原则会带来更好的结果
- 平滑滚动?
👉 无需 JavaScript,因为 CSS 可以做到。 - 需要从您的基于 JSON 的 API 中传递错误信息?
👉 不要使用响应主体中的{error: true}
的 HTTP 200,而使用 HTTP 状态代码 来传递错误信息。 - 通过 JavaScript 关闭
<dialog>
?
👉 带有[method="dialog"]
的<form>
元素 就足够了。 - 想要延迟加载图像?
👉 这将很快 得到所有现代浏览器的支持,直接在 HTML 标记中使用属性。 - 可自定义的
<select>
?
👉 正如我们所说,正在开发中。 - 想要将动画链接到滚动偏移量?
👉 无需外部 JavaScript 库,因为 现在是浏览器原生 API,并且很快也会 可以使用纯 CSS 完成。 - 需要阻止表单输入中的某些字符?
👉 不要禁用粘贴,而是选择合适的输入类型和/或使用pattern
属性。 - 需要折叠部分?
👉<details>
和<summary>
是您的朋友。 - 等等...
在所有这些示例中,我们可以将一些功能从上层移动到下层。伯纳斯·李会为我们感到自豪。
弹性
通过选择 Web 栈中更低级别的技术,更接近 Web 平台的核心,我们还获得了针对故障的内置弹性的优势。
JavaScript 在故障方面非常糟糕。一个无法加载或在过程中被破坏的脚本,或一个传递给函数的错误参数,都可能导致您的整个应用程序无法工作。如果您对“无法读取 x
的 undefined
属性”之类的错误信息感到熟悉,您就知道我在说什么。
另一方面,CSS 在故障方面表现非常出色。即使您的其中一个样式表中存在语法错误,您的其他 CSS 仍然会正常工作。HTML 也是如此。这些语言具有容错性。
如果您怀疑为什么应该使用最小能力原则,Jeremy Keith 在他的文章 “评估技术” 中为我们提供了答案
我们倾向于问“它运行得如何?”,但您真正应该问的是“它故障得如何?”
Jeremy Keith
我们可以做得更好
一个可以从最小能力原则中获益的知名网站是耐克网站。当您禁用 JavaScript 访问他们的网站时,您看不到任何图像,也无法订购任何鞋子。

这种对 JavaScript 的过度依赖是不必要的,因为所有这些失效的功能都可以用前端栈中更低级别的技术来构建
- 为什么不立即包含
<img>
元素来显示鞋子的照片,而不是通过 JavaScript 动态注入它们? - 为什么不使用带有
<select>
(选择您的尺码)和提交<button>
(订购鞋子)的<form>
,而不是通过 JavaScript 管理整个状态和提交?
☝️如果您想知道为什么有人会禁用 JavaScript 浏览网页:这通常不是他们的选择,而是干扰的外部因素。请参阅 “每个人都有 JavaScript,对吗?” 以获取有关该主题的详细解释。
这个类别中更糟糕的违规者是 Instagram 和 Twitter 等知名网站。没有 JavaScript,这些网站根本无法正常工作。它们要么会显示警告,要么就只是空白。从什么时候开始,JavaScript 成为在网络上显示文本和图像的必要条件?
渐进增强
它不必像耐克的这个孤立示例那样糟糕。有时是某些更小的组件在 JavaScript 出现故障时无法正常工作。以选项卡界面为例。即使您可以找到许多提供此功能的 JavaScript 库,但关键是您不需要 JavaScript,因为 HTML、CSS 和 ARIA 本身 已经可以帮助您取得很大进展。
一旦您有了这些基础层,就可以使用 JavaScript 来进一步改善体验。**将 JavaScript 视为增强功能,而不是必备条件。**
对于某些可能可用或不可用的 CSS 功能也是如此。提供基本样式,当功能可用时——可以使用 @supports
检测——增强您已有的结果。
这种方法被称为**渐进增强**:您随着更多功能的可用而添加功能,使结果在体验方面得到改善,但不会过度依赖这些额外装饰,以至于功能无法在没有这些装饰的情况下正常工作。
对于尚未支持特定新功能的浏览器,您可以尝试找到一个 polyfill,将该功能提供给这些浏览器。
网络追赶
从网络早期开始,我们看到网络平台随着时间的推移获得了许多新功能。定义了新的 HTML 元素,JavaScript(语言)已经成熟,CSS 已经获得了许多用于构建布局、动画元素等功能的强大新功能。
几年前不可能的事情,只能通过依赖外部技术(如 Flash)来完成,现在已经内置到浏览器本身了。
一个典型的例子是 jQuery 引入的功能。十年前,jQuery 是第一个进入项目的工具。如今,情况已不再如此,因为网络平台已经赶上,现在内置了 document.querySelectorAll()
、Element.classList
等——所有这些功能都是受到 jQuery 为我们提供的功能的启发。可以说 jQuery 是一个 polyfill,甚至在 polyfill 称为 polyfill 之前就已经存在了。
虽然 jQuery 可能是一个熟悉的例子,但还有许多其他情况证明网络已经追赶上了。
- 在 JavaScript 中难以使用非常糟糕的
Date()
API 吗?
👉 Temporal API 更加方便使用。 - 使用第三方 JavaScript 库来为屏幕上的元素制作动画?
👉 为什么不试一试内置的 Web Animations API?它非常强大。 - 需要彩色单选按钮和复选框?
👉 新的 CSSaccent-color
属性 为您完成了这项工作。 - 依赖预处理器才能使用 CSS 变量?
👉 CSS 自定义属性是 过去 20 年来对 CSS 最大的补充。 - 等等...
这里的主要主题是这些功能不再依赖于 polyfill 或外部库,而是更靠近 Web 堆栈的核心。网络追赶上了。
虽然这些新 API 中的一些可能相当抽象,但有一些库可以插入您的代码中。例如,Redaxios 在幕后使用 fetch
,同时还公开了一个对开发人员友好的、与 Axios 兼容的 API。如果这些便利方法最终渗透到 Web 平台中,我不会感到惊讶。
最后
伯纳斯-李近 25 年前写下的内容经受住了时间的考验。我们开发人员有责任维护这条信息。通过拥抱 Web 平台提供的功能——而不是试图与之抗衡——我们可以构建更好的网站。
保持简单。应用最小权原则。以渐进增强的理念进行构建。
HTML、CSS 和 JavaScript——按此顺序。
总的来说我同意,但你提到的有些东西——滚动关联动画、Temporal API——太新了,以至于在撰写本文时,实际上没有任何浏览器支持它们。
不支持某些新 API 的浏览器可以使用 polyfill 来补充。对于你提到的那两个 API,可以使用这些:
旁注:在 TC39 流程中,开发新的 ECMAScript 语言特性时,其中一项预期是存在 polyfill。
很棒的文章。谢谢。
我一直都在考虑提交类似内容的想法,但你抢先了一步,而且表达得更加优雅!
平台的许多创新都受到那些创建“高性能”JavaScript 库的人的影响和塑造。
平台可能不会完全赶上。新的 UX 设计将导致新的 JavaScript 库。
对于开发人员来说,重要的是要知道何时拥抱平台,何时使用 JavaScript。此外,需要考虑选择快速更新的 JavaScript 库与相对稳定的 polyfill 时的维护成本。
我非常同意你的观点。我真的希望更多的人能够学习平台。
我想补充一点,对于因为布局或设计选择而改变 HTML 结构的做法也是如此。你懂的,那些分隔符
div
或者内部/外部div
组合…作为一名拥有 2 年以上经验的初级开发人员,采用这种原则会如何影响我对 React 等前端框架的使用?我应该优先使用原生的 HTML、CSS 和 JS 吗?毫无疑问,这会让我成为一名更好的开发人员,但对于刚入行的行业新人来说,这是一种可行的做法吗?
不要默认情况下就使用 React 是这里的关键教训。
而且,如果你确实需要 React——这可能是一个完全合理的選擇——不要忽视你所知道的其他一切。
HTML/CSS 可以做的事情清单中,“即将推出”的部分数量很奇怪。很快我们就可以更多地依靠 HTML 和 CSS……但现在还不行。
确实,有时这会让人沮丧。
对于上面提到的大多数事情,polyfill 都存在(延迟加载、Temporal 等)。
不幸的是,并非所有功能都已实现 polyfill。对于那些你确实需要的功能,你需要使用其他选择。滚动关联动画就是一个很好的例子。
然后是浏览器的不兼容性/不一致性……感谢 #webcompat2021 等努力,这些问题得到了很大的改善。
所以,是的,它肯定还有一些需要改进的粗糙边缘。
很棒的文章 Bramus。喜欢这些现成解决方案的链接!
我正在构建一个在 React、Vue 3、Svelte 和 Angular 中都能使用的 UI 组件库(它在平台 JS 中也能正常工作,因为它主要关心的是 HTML 和 CSS),我可以告诉你——我希望我们能够全面采用基于平台的方法。我认为雇主、团队以及某些实际情况,尤其是无法丢弃的旧代码库,让这成为一项挑战。但是,对于新项目来说,这绝对值得一试。
实际上,我可以吹嘘说我的开源库没有使用 Sass 或 PostCSS;只有纯 CSS。这是一种非常冗长的编写方式,但我感觉很好,因为它正在“走向标准”,而且我最终的特殊性也很低。
总之,我同意你至少应该尝试先使用基于标准的工具,然后再使用“机枪框架”:)
说得太好了:)
我不确定我是否理解关于耐克网站的这段话——是否有办法(客户端)从后端获取鞋子数据并处理响应,而无需使用 Js?
我已经开发网站 27 年了,我完全同意。我从未见过这么多由于 JS 失败而陷入困境的网站,没有回退。HTML 和 CSS 已经成为非常强大的语言,为可以用纯 HTML/CSS 实现的功能分配功能是毫无意义的,而且往往很危险。有趣的事实:我记得曾经 JS 被认为是邪恶的,趋势引领者认为只有无知的菜鸟才会使用它。