您的博客不需要JavaScript框架

2020-07-18 16:38:29

今年年初,我终于决定将我的网站从基于a的[1]移植到基于JavaScript的static site Generator()。这有几个原因:

在开始成为“全栈”开发人员后,我现在只在前端工作:如果我需要编写自定义功能,我不想在可以用JavaScript编写的时候编写它。

我不需要a-markdown文件的抽象层或复杂性,这是我编写内容最舒服的地方,我将很高兴再也不会接触我的数据库或编辑器。

我想提高我网站的性能:100个静态文件中有99个会比动态构建的页面更快。

最后,还有成本效益:一台堆栈[2]服务器每个月都要花钱;Netlify的免费级别(300分钟/月)应该可以轻松地零成本覆盖个人博客。

一旦我决定我想要一个静态站点生成器,并且它需要使用JavaScript(这排除了Jekyll和Hugo),我就把列表缩小到两个截然不同的竞争者:

根据官方网站的说法,“Gatsby是一个基于Reaction的免费开源框架,可以帮助开发人员构建速度极快的网站和应用程序”。它有一个由GraphQL提供支持的数据层,它将所有内容输出到静态文件,让您几乎可以在任何地方托管它。

当我第一次听说我可以编写、反应和使用这个很酷的新GraphQL东西,同时仍然可以输出没有JavaScript的静态页面时,我非常想试一试。我想,这听起来像是渐进式增强,但并不费力。不幸的是,就像大多数听起来好得令人难以置信的事情一样,经过一些调查,结果发现其中有一个陷阱。以下是用户首次访问盖茨比网站时会发生的情况:

服务器将静态生成的文档发送到用户的浏览器,浏览器开始呈现页面。

现在文档已经到达,JavaScript包(包括Reaction库和呈现页面所需的任何其他JavaScript)开始在后台下载、解析和编译。

JavaScript已经准备好运行了--整个系统都被Reaction组件“补充了水分”[3。

这里有一些不太对劲的地方-Gatsby强制您再次加载相同的页面,但作为Reaction组件;在额外的步骤完成之前,所有需要JavaScript的元素(例如按钮、菜单、自定义输入)实际上都不是交互式的。

如果您的站点没有任何交互元素(不包括链接,它们在没有JavaScript的情况下也可以工作,即使在Gatsby中也是如此),您的用户仍然必须下载此JavaScript,其唯一目的是将您的站点转换为单页面应用程序(),这也有其自身的缺点,我们很快就会发现这一点。

这种额外的膨胀似乎与转到a的一个主要原因背道而驰:让页面变得更快。你的盖茨比(Gatsby)网站在2000美元的MacBook上可能速度很快,但对于那些使用3G连接的经济型智能手机的人来说,在用户等待JavaScript加载的15秒内,它是可见的,但没有响应。这也不必要地耗尽了他们的电池和数据津贴。

如果浏览器需要解析296kb的JavaScript[4]来显示博客帖子列表,这不是渐进式增强,它使用的工具是错误的。使用相当模糊的网站/web应用程序区别-reaction是为了构建web应用程序:需要响应用户输入或实时获取数据的交互式UI-您的博客只是一个网站,这很好。

单页应用程序是一种网站,它放弃了Web上的传统导航方法,即通过加载新文档来加载新内容;取而代之的是,它使用诸如和历史记录之类的JavaScript功能在不触发页面加载的情况下交换新内容。这样做的目的是提高用户的感知性能,让网站感觉更像是一款原生应用程序(你可以从应用程序商店下载)。取消整页重载的问题是,浏览器和辅助技术使用页面加载作为触发某些有用行为的信号,包括宣布新页面的标题或将键盘焦点重置到文档的开头。

如果您是构建单页面应用程序的易访问性开发人员,则可以尝试使用JavaScript模拟浏览器的行为。Gatsby试图通过包含RouteAnnouner组件来为您处理此问题。这使用活动区域来宣布页面的标题或H1,提醒屏幕阅读器软件的用户导航更改。然而,这种方法并不是没有问题:围绕配置和本地化仍然存在一些悬而未决的问题。

我们已经看到,单页面应用程序在导航方面存在固有的可访问性问题,但值得记住的是,使用前端框架也会使可访问性的其他方面变得更加困难。在2020年2月对一百万个主页的调查中,WebAIM发现那些使用React的人比平均水平多5.7%的可访问性错误,而那些使用Vue的人多25%[5]。这并不一定意味着框架导致了这些错误,但是JavaScript越多,可访问性越差。

很有可能,你创建的第一个网页的表现远远好于你后来创建的一些网页--它由一个文件和一些文件组成;也许它有一些未经优化的图片,但它们并没有阻止页面的加载。如果你和我一样,当你开始添加JavaScript的那一刻,你的网页性能就会一落千丈。并不是所有的字节都是相等的:与同等大小的JavaScript文件解析、编译和执行相比,图像解码并呈现到屏幕上所需的时间要少得多[6]。

JavaScript是一种功能强大的语言,可以做一些令人难以置信的事情,但在开发早期跳到使用它是非常容易的,因为您可以使用它,而不是使用它。考虑最低功耗规则:在用尽功能较弱的语言()的功能之前,不要使用功能较强的语言(JavaScript)。在我看来,将博客转换为JavaScript单页面应用程序会带来不必要的复杂性。

我不希望这篇文章给人的印象是对盖茨比的具体攻击。它背后有一些聪明人,他们已经承认了本文中提到的许多问题,并正在努力解决这些问题。静态呈现和加水的页面仍然远远好于完全在客户端呈现的Reaction应用程序(就像那些由Create-Reaction-app生成的应用程序),后者在没有JavaScript的情况下毫无用处。我确实对Gatsby大量使用JavaScript的单页应用程序的广告方式有问题,包括在Gatsby自己的营销中,如果适用于任何类型的网站。客户端JavaScript是有成本的,开发人员应该意识到这一点。

这让我陷入了两难境地:使用Gatsby开发站点是一种全方位的很棒的体验;但是开发人员体验(DX)应该始终排在用户体验(UX)之后--如何在没有Gatsby的JavaScript Heavy方法固有问题的情况下构建Gatsby站点?当然,是通过尽可能多地去除它。幸运的是,Gatsby社区正在进行一些奇妙的工作,以构建更快、更轻量级的站点:

首先,通过使用Gatsby-plugin-preact将Reaction替换为Preact,可以节省几千字节。我在组件库上使用它,它可以无缝工作,立即减少大约30KB的JavaScript有效负载。

如果你想采取更激进的方法,有一个插件可以从你的Gatsby站点中删除所有的Gatsby JavaScript。现在我们有进展了!您可以继续编写Reaction组件和GraphQL,甚至可以使用CSS-in-JS库(只要它输出CSS或内联样式),而无需向浏览器发送任何JavaScript。Gatsby的大多数问题可以通过丢弃其所有客户端JavaScript来解决。Gatsby starter low Tech博客使用非javascript插件,以及其他一些技术,包括将所有图像转换为灰度,帮助您创建一个极其轻便且节能的博客。

在这一点上,我觉得有些地方不对劲--使用了一个大力推动客户端JavaScript的框架,但是删除所有的JavaScript似乎是构建网站的一种相当复杂的方式。我想看看我是否可以用零客户端JavaScript构建一个功能齐全的博客,而不是使用插件来删除它,而不是从一开始就不打算添加它。这就是我的另一位竞争者的用武之地:

十一鼓励你以你想要的方式建立你的网站。你使用你最习惯的技术,它坚持生成你的页面。Elevty提供了混合和匹配10种不同的模板语言的选项,包括Markdown、双节棍和Liquid;这意味着我可以从Craft复制并粘贴我的旧小枝模板,更改文件扩展名,然后通过一些小的调整使它们在Eleviti中运行。我可以直接放入现有的webpack文件和src文件夹,而不是将我的前端构建过程调整到新的捆绑包中。使用并发包,我可以在运行构建脚本的同时运行Eleviti的服务进程。

和Gatsby一样,Elevty也有一个插件生态系统(虽然很小,但增长很快)。我挑选了几个我用过的,它们使我无需添加客户端JavaScript即可添加功能:

在POST中显示代码片段时,通常会包含特定于语言的语法突出显示。有几个JavaScript库可以做到这一点,其中最流行的似乎是Prism-通常您会在客户端运行它,但是因为我们使用的是JavaScript SSG,所以我们可以在构建时运行它,并将语法突出显示所需的元素和类直接烘焙到文档中-这消除了在浏览器中下载该库的需要。

11-plugin-embed-tweet是这种在构建时而不是在客户端运行JavaScript的另一个示例。Twitter的默认嵌入代码迫使用户下载大量JavaScript来呈现一条tweet。通过在构建时获取并呈现tweet,用户可以获得呈现tweet所需的最少内容,而且根本不需要额外的JavaScript。

与任何新技术一样,Elevty缺少其他更成熟的工具的一些功能。例如,在Eleviti中没有生成响应图像的优雅方法;与之相比,Gatsby出色的Gatsby-image插件可以生成延迟加载的响应图片元素,并在加载全分辨率文件后从低分辨率或低版本的图像平滑过渡。还有几件事让我感到困惑:有一段时间我很难理解分页功能,以为它只用于将帖子分成指定大小的组,然后才意识到它可以动态生成全新的页面;我还发现自己在同一文件中混合了模板语言:没有什么能阻止您在标记文件中包含双节棍标记,或者将基于YAML的头条换成JavaScript,但这可能会破坏语法突出显示、链接和自动格式化。

如果您确实决定使用Gatsby,我不会责怪您--有时使用一个固执己见的框架很好,如果您想要快速启动和运行某些东西,这是一个可靠的解决方案。只需注意与所有JavaScript相关性能成本和对可访问性的潜在影响。

我已经选择了使用“十一”来建立我的网站,但我明白不是每个人都可以从一张空白的画布开始--拥有完全按照你想要的方式构建东西的自由可能是令人望而生畏的。但你不必像我一样去做--与盖茨比类似,Elevty有很多入门项目,你可以把它作为基础。“。其中一些工具(如Andy Bell的Hylia初学者工具包)可以在几分钟内启动并运行;它甚至预配置了Netlify,这样您就可以在不接触任何代码的情况下编辑站点内容。

那么我学到了什么呢?Elevty使得在没有JavaScript的情况下构建博客变得很容易,但是总会有一些功能需要客户端JavaScript:

我不得不将Google Analytics从我的网站上删除,但分析从一开始就对用户没有真正的好处,所以我对它的消失并不感到难过-幸运的是,有一些服务器端的替代方案,我将在另一篇文章中讨论。

我为延迟加载图像使用了loading=#34;lazy";属性,但是浏览器支持是不完整的,除非本机浏览器实现得到改进,否则无法在加载图像时逐渐淡入。

暗模式切换-虽然我可能只使用CSS就可以实现这一点,但如果不访问cookie或本地存储,我将无法在页面之间持久化该值。

我会在短期内将JavaScript添加到我的站点中吗?可能不是:我在上面列出的功能只不过是一些不错的功能。我并不是认真地建议每个阅读这篇文章的人打开他们的网站,删除每一个JavaScript文件,但从现在开始,当我建立网站时,我会试着把JavaScript看作是可选的额外内容,而不是体验的基本部分。我鼓励你也这样做。

Reaction尝试将现有HTML标记中的元素与其自己的组件和状态进行匹配的过程,有效地重新运行在构建时(但在客户端↩︎中)呈现静态HTML文件的逻辑。

盖茨比入门博客主页加载的javascript量(99kbgzip),测量2020-04-11↩︎