你的博客用不着什么 JavaScript 框架

今年年初,我终于决定将自己的网站从基于 php 的 CMS 移植到基于 JAVAScript 的静态网站生成器(SSG)了 。原因如下:

  1. 虽然一开始我是“全栈”开发人员,但现在我只负责前端工作:如果我需要编写自定义功能,那么能用 JavaScript 编写的代码我就不想用 PHP 来写 。
  2. 我不需要抽象层或 CMS 的复杂性——我最喜欢用 markdown 文件编写内容,并且希望永远不要再碰 MySQL 数据库或所见即所得编辑器 。
  3. 我想提高网站的性能:静态 html 文件在 99% 的时候都比动态页面更快 。
  4. 最后还有成本优势:LAMP stack 服务器得按月付费;Netlify 的免费套餐(每月构建 300 分钟)应该可以轻松覆盖零成本个人博客的需求 。
当我决定使用静态站点生成器和 JavaScript(排除了 Jekyll 和 Hugo)后,就只剩下两个差别颇大的选项了 。
“我听说 Gatsby 很好用”根据官方网站的说法,“Gatsby 是一个基于 React 的免费开源框架,可帮助开发人员构建速度飞快的网站和应用” 。它有一个由 GraphQL 支持的数据层,并将所有内容输出到静态文件,使你可以在几乎任何地方托管它 。
当我第一次听说我可以编写 React 并使用这个很酷的 GraphQL 新玩意儿,同时还能输出不需要 JavaScript 的静态页面时,我很想尝试它一下 。我是这么想的:“这听起来像是渐进增强,但用不着什么投入” 。不幸的是,就像大多数听起来过于美好的事情一样,经过一些调查我发现它就是个坑 。用户首次访问 Gatsby 网站时会发生这些事情:
  1. 用户请求一个页面 。
  2. 服务器将静态生成的 HTML 文档发送到用户的浏览器,然后浏览器开始渲染页面 。
  3. HTML 文档到达后,JavaScript 包(包括 React 库和渲染页面所需的其他 JavaScript)开始在后台下载、解析和编译 。
  4. JavaScript 已准备就绪,可以运行——整个 DOM 通过 React 组件“被水化”(hydrated) 。
这里就有些不对劲——Gatsby 需要你以 React 组件的形式再加载一次页面;在完成多出来的这一步之前,所有需要 JavaScript 的元素(例如按钮、菜单、自定义输入)实际上都不能交互 。
哪怕你的网站没有任何互动元素(链接除外,即使没有 Gatsby,它们也无需 JavaScript 即可工作),你的用户也必须下载这部分 JavaScript,仅仅是为了将你的网站变成单页应用程序(SPA);SPA 是有自己的缺点的,我们稍后再提 。
这种多出来的操作看来是违背我转向 SSG 的初衷(提高页面速度)的 。华丽的 Gatsby 网站在 2,000 美元的 macBook 上可能很快,但对于使用 3G 连接和廉价智能手机的用户来说,它显示是能显示出来,但是没有响应;用户等待加载 JavaScript 的过程要持续 15 秒 。电池和数据流量也得跟着往下掉了 。
如果浏览器需要解析 296kb 的 JavaScript 代码才能显示出博客文章的列表,这就不是什么"渐进增强”,而是用错了工具 。从网站 /Web 应用的大致区别来看,React 是用于构建 Web 应用的,这种应用需要有响应用户输入或实时获取数据的交互式 UI;而博客只是一个网站而已 。
单页应用程序中的可访问性单页应用程序这种网站放弃了传统的 Web 导航方法,即通过加载新的 HTML 文档来加载新内容;相反,它使用 AJAX 和 History API 之类的 JavaScript 特性来切换到新内容上,而不会触发页面加载 。它的目标是提高感知的性能,并使网站看起来更像“原生”应用(从应用商店下载的那种) 。不再需要整页重新加载的问题在于,浏览器和辅助技术将页面加载用作触发某些有用行为的信号,包括宣布新页面的标题或将键盘焦点重置到文档的开头 。
如果你在开发关注可访问性的单页应用程序,那么你可能会试着使用 JavaScript 来模拟浏览器的行为 。Gatsby 试图通过包含一个 RouteAnnouncer 组件来为你解决这个问题 。它使用一个 ARIA live region 来宣布页面的 title 或 h1,以对使用屏幕阅读器软件的用户提示页面跳转行为 。但这种方法也存在问题:它在配置和本地化方面仍然存在很多未解决的 issue 。
我们已经看到,单页应用程序在导航方面存在固有的可访问性问题,但要注意的是,使用前端框架也会在其他方面带来可访问性问题 。在 2020 年 2 月对 100 万个首页的调查中,WebAIM 发现使用 React 的网页的可访问性错误比平均水平高 5.7%;而使用 Vue 的网页则高出 25% 。这并不一定意味着框架一定会导致这些错误,但是更多的 JavaScript 与更差的可访问性之间存在很强的相关性 。


推荐阅读