静态 vs. 动态 vs. Jamstack:界限在哪里?

Avatar of Mike Neumegen
Mike Neumegen

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

您经常会听到开发人员谈论“静态”与“动态”网站,或者您可能听说过有人使用术语Jamstack。这些术语是什么意思?“静态”网站何时会变成 Jamstack 或动态网站?这些问题听起来很简单,但实际上比看起来要复杂得多。让我们探索这些术语,以更深入地了解 Jamstack。

寻找界限

椅子和凳子有什么区别?大多数人会回答说椅子有四个腿和靠背,而凳子有三个腿没有靠背。

Two brown backed leather chairs with a black frame and legs around a white table with a decorative green succulent plant in a white vase.
图片来源:Rumman Amin
Two tall brown barstools with three legs and a brass frame under a natural wood countertop with a decorative green houseplant.
图片来源:Rumman Amin

好的,这是一个很好的起点,但这些呢?

A tall black leather chair with a back and four brown legs against a light blue background.
图片来源:Valerii Zorin
A brown leather black chair with a seamless back facing directly at the camera, with three curved black legs.
图片来源:Krisztian Tabori

椅子越像凳子,就越少人会断言它是椅子。最终,我们会到达一个大多数人认为它是凳子而不是椅子的点。这听起来可能像一个愚蠢的练习,但如果我们想深入了解成为椅子的意义,这是一个有价值的练习。我们找出对于大多数人来说椅子的极限在哪里。我们还建立了对超出范围的灰色区域的理解。最终,我们到达了一个点,即使是最顽固的椅子粉丝也会让步并承认他们面前的是一个凳子。

虽然椅子很有趣,但这篇文章是关于网站交付技术的。让我们对静态、动态和 Jamstack 网站执行相同的练习。

高级概述

当您在浏览器中访问网站时,幕后会发生很多事情。

  1. 您的浏览器执行 DNS 查询以将域名转换为 IP 地址。
  2. 它从该 IP 地址请求一个 HTML 文件。
  3. Web 服务器发送回请求的文件。
  4. 当浏览器渲染网页时,它可能会遇到对资源的引用,例如 CSS、JavaScript 或图像文件。然后浏览器对该资源执行请求。
  5. 此循环持续进行,直到浏览器拥有网页的所有文件。一个网页执行 50 多个请求并不少见。

对于每个请求,来自 Web 服务器的响应 **始终** 是一个静态文件,即使在动态网站上也是如此。您可以将这些文件保存到 USB 驱动器,像您计算机上的任何其他文件一样通过电子邮件发送给朋友。

在比较静态和动态时,我们谈论的是 **Web 服务器在做什么**。在静态网站上,浏览器请求的文件已经存在于 Web 服务器上。Web 服务器按原样发送它们。在动态网站上,响应由软件生成。此软件可能会连接到数据库以检索数据,从模板文件构建布局,并在页脚中添加今天的日期。它为每个请求执行所有这些操作。

这就是静态和动态网站之间的根本区别。

Jamstack 在哪里发挥作用?

静态网站受到限制。它们非常适合信息类网站;但是,根据定义,您不能拥有任何动态内容或行为。Jamstack 模糊了静态和动态之间的界限。其理念是利用静态网站的所有优势,同时在必要时启用动态功能。

Jamstack 中的“stack”是一个误称。事实上,Jamstack根本不是一个堆栈。它是一种理念,与 AWS 架构良好框架的五大支柱 惊人地相似。该术语的模糊性导致社区对成为 Jamstack 的含义进行了广泛的讨论。

什么是 Jamstack?

Jamstack 是静态的超集。但要真正理解 Jamstack,让我们从导致该术语产生的种子开始。

2002 年,已故的 Aaron Swartz 发布了一篇题为 “烘焙,不要油炸。” 的博文。虽然 Aaron 没有创造“烘焙,不要油炸”这个词,但这是我第一次发现有人认识到静态网站的好处,同时打破了这个词的既定限制。

我不希望维护脾气暴躁的 AOLserver、Postgres 和 Oracle 安装。我希望能够使用 scp 备份数据。我不希望在将我的网站迁移到新服务器时进行任何安装或配置。我希望独立于平台和服务器。

如果我们仔细研究历史,我们可以发现类似的挫折导致了 Jamstack 种子。

  • BenMena Trott 创建了 MovableType,因为他们 [对]现有博客 CMS 感到不满——性能、稳定性。
  • Tom Preston-Werner 创建了 Jekyll 以摆脱复杂性。
    我已经知道很多我不想要的东西。我厌倦了像 WordPress 和 Mephisto 这样复杂的博客引擎。我想写出精彩的文章,而不是设计无数的模板页面,整天审核评论,并不断落后于最新的软件版本。
  • Steve Francia 创建了 Hugo 以提高性能。
    过去几年,此博客由 wordpress [sic] 提供支持,在此之前是 drupal。两者都是优秀的软件,但随着时间的推移,我越来越失望于它们都针对内容编写进行了优化,即使大多数常见用法是阅读内容。由于需要在每次请求时加载 PHP 解释器,因此它永远无法被认为很快,并且在我的 VPS 上消耗了大量内存。

当您查看许多早期 Jamstack 工具的起源时,会出现相同的主题。

  • 降低复杂性
  • 提高性能
  • 减少供应商锁定
  • 为开发人员提供更好的工作流程

在过去的 20 年里,JavaScript 已从一种用于向网站添加少量交互的语言发展成为一种在浏览器中构建丰富 Web 应用程序的平台。与此同时,我们看到了将大型应用程序拆分为更小的微服务的趋势。这两种发展催生了一种新的构建网站的方式,您可以在其中拥有与动态后端分离的静态前端。

2015 年,Mathias Biilmann 想要讨论这种构建网站的现代方法,但一直难以摆脱静态的限制性定义。

我们处于现代静态网站的领域。这对我们正在做的事情来说是一个非常糟糕的描述,对吧?而且我们一直遇到这样的问题,在与人们讨论静态网站时,他们会认为它非常静态。他们会想到宣传册或一些没有活动部件的东西。一个小型的单页或类似的东西。

为了打破这些限制,他创造了“Jamstack”一词来谈论这种新方法,并且它像野火一样流行起来。90 年代的旧静态技术再次焕发生机,并被推向了新的高度。许多开发人员意识到了 Jamstack 方法的优势,这帮助 Jamstack 发展成为当今 蓬勃发展的生态系统

Aaron Swartz 在 Jamstack 诞生 13 年前就很好地表达了这一点:在输入(需要动态代码进行处理)和输出(通常可以烘焙)之间保持严格的分离。 换句话说,将前端与后端分离。尽可能预渲染内容。在必要时分层添加动态功能。这就是 Jamstack 的核心。

您可能希望构建 Jamstack 网站而不是动态网站的原因归结为 Jamstack 的六大支柱。

安全

Jamstack 网站的活动部件更少,外部来源恶意利用的攻击面也更小。

扩展性

Jamstack 网站在可能的情况下使用静态内容。静态网站可以完全存在于 CDN 中,这使得它们更容易且更便宜地进行扩展。

性能

从 CDN 提供网页服务,而不是根据需要从集中的服务器生成网页,可以提高网页加载速度。

可维护性


静态网站很简单。您只需要一个能够提供文件服务的 Web 服务器。对于动态网站,您可能需要一个完整的团队来保持网站的在线和快速运行。

可移植性


同样,静态网站由文件组成。只要您找到能够提供网站文件的 Web 服务器,就可以将您的网站迁移到任何地方。

开发者体验

Git 工作流是当今软件开发的核心部分。许多遗留 CMS 难以实现 Git 开发工作流。使用 Jamstack 网站,所有内容都是文件,因此可以无缝地使用 Git。

Chris 在 Jamstack 与 WordPress 的深入比较 中提到了其中的一些要点。他还比较了在 “静态还是非静态?” 中选择 Jamstack 架构与服务器端架构的原因。

让我们利用这些支柱来评估 Jamstack 的用例。

静态与 Jamstack 的边界在哪里?

现在我们已经了解了静态网站和 Jamstack 的基础知识,让我们深入了解一下每个定义的边界。每个边缘案例都可能属于以下四个类别。

  • 静态 – 严格遵循静态的定义。
  • 基本上是静态的 – 虽然不完全是静态的,但大多数人会称其为静态网站。
  • Jamstack – 与动态后端分离的静态前端。
  • 动态 – 根据需要呈现网页。

许多这些用例可以归入多个类别。在本练习中,我们将它们放在它们适合的最严格的类别中。

JavaScript 交互 静态

让我们从一个简单的例子开始。我有一个使用 JavaScript 创建图像幻灯片的静态网站。

HTML 页面、JavaScript 和图像都是静态文件。幻灯片功能所需的全部 HTML 操作都在浏览器中发生,没有任何外部影响。

Cookie 静态

我有一个静态网站,如果存在 Cookie,则使用 JavaScript 将横幅添加到页面顶部。Cookie 只是一个头部。其余文件是静态的。

外部资源 基本上是静态的

在网页上,我们可以从外部源加载图像或 JavaScript。此外部源可能会根据请求动态生成这些资源。这是否意味着我们有一个动态网站?

包括我在内的大多数人都会认为这是一个静态网站,因为它基本上就是。但是,如果我们严格按照定义,它就不符合要求。页面的任何部分动态生成都会破坏静态的神圣和谐。

iFrames 基本上是静态的

内联框架允许您将 HTML 页面嵌入到另一个 HTML 页面中。iFrames 通常用于在网页上嵌入 Google 地图、Facebook 点赞按钮和 YouTube 视频。

同样,大多数人仍然会认为这是一个静态网站。但是,这些嵌入几乎总是来自动态生成的源。

表单 基本上是静态的

静态网站无疑可以在其中包含表单。难题出现在您提交表单时。如果您想对数据执行某些操作,则几乎肯定需要一个动态后端。您可以使用许多表单提交服务作为表单的操作。

我可以看到两种争论方式

  1. 您正在将表单提交到外部网站,并且碰巧随后会重定向回来。这种分离意味着静态的定义保持不变。
  2. 此外部服务是您网站上的核心工作流程,静态的定义不再适用。

实际上,大多数人仍然会认为这是一个静态网站。

Ajax 请求 Jamstack

Ajax 请求允许开发人员请求来自外部源的数据,而无需重新加载页面。我们与上述依赖第三方的情况处于同一境地。Ajax 调用的端点可能是静态 JSON 文件,但也更有可能是动态生成的。

Ajax 数据在网站上的典型使用方式使其超越了静态网站,进入了 Jamstack 领域。它非常适合 Jamstack,因为您可以拥有一个网站,在该网站上您可以预渲染所有可以预渲染的内容,然后使用 Ajax 在网站上添加任何动态功能或内容。

嵌入式电子商务 Jamstack

有一些 服务允许您添加电子商务,即使是在静态网站上。在幕后,它们基本上是在发出 Ajax 请求以管理购物车中的商品并收集付款详细信息。

单页应用程序 (SPA) Jamstack

仅标题就将其排除在静态网站的范围之外。SPA 使用 Ajax 调用来请求数据。表示层完全位于前端,使其变得非常棒 (Jamtastic)。

对无服务器函数的 Ajax 调用 Jamstack

无论 Ajax 调用的端点是使用诸如 AWS Lambda 之类的无服务器功能,还是您的 Kubernetes 集群的 Node.js 后端,或者是一个简单的 PHP 后端,都没有关系。Jamstack 的关键在于前端独立于后端。

Web 服务器前面的反向代理 静态

在 Web 服务器前面添加反向代理以用于静态站点必须使其成为动态的,对吧?好吧,没那么快。虽然代理是在网络中添加动态元素的软件,但只要服务器上的文件与浏览器接收的文件完全相同,它仍然是静态的。

Web 服务器、调制解调器以及介于两者之间的所有网络基础设施部件都在运行软件。如果添加代理会使静态站点变为动态,那么就没有什么是静态的。

CDN 静态

CDN 是一个全球分布式反向代理,因此它与反向代理属于同一类别。CDN 通常会添加自己的标头。但这仍然不会影响其享有盛誉的静态状态,因为标头不是服务器硬盘驱动器上文件的一部分。

带有 200 年缓存过期时间的动态站点前面的 CDN 动态

好吧,200 年是一个很长的过期时间,我承认这一点。有两个原因导致这既不是静态站点也不是 Jamstack 站点

  1. 第一个请求未被缓存,因此它按需生成。
  2. CDN 并非设计用于持久存储。如果在一周后,您的网站仅有五次访问,则 CDN 可能会从缓存中清除您的网页。它始终可以从源服务器检索网页,该服务器将动态呈现响应。

带有静态输出的 WordPress 静态

使用 WP2Static 等 WordPress 插件,您可以在 WordPress 中创建和管理您的网站,并在任何内容发生更改时输出一个静态网站。

当您执行此操作时,浏览器请求的文件已存在于 Web 服务器上,这使其成为一个静态网站——与在动态站点前面放置 CDN 相比,这是一个细微但重要的区别。

边缘计算 动态

许多公司现在都提供了在 CDN 边缘运行动态代码的功能。这是一个强大的概念,因为您可以拥有动态功能而不会增加用户的延迟。您甚至可以使用边缘计算在将 HTML 发送到客户端之前对其进行操作。

这取决于您如何使用边缘函数。您可以使用边缘函数向特定请求添加标头。我认为这仍然是一个静态站点。如果超出此范围,您正在操作 HTML,那么您就越过了动态边界。

很难说它是一个 Jamstack 站点,因为它不符合一些基本优势:可扩展性、可维护性和可移植性。现在,您有一部分核心基础设施在每个请求上都更改 HTML,并且它只会在该特定托管基础设施上运行。这与静态站点的轻松简洁性相去甚远。

Jamstack 的一个巧妙之处在于前端和后端是解耦的。后端由输出数据的 API 组成。它们不知道也不关心数据是如何使用的。前端是表示层。它知道从哪里获取动态数据以及如何呈现它。当您打破这种关注点分离时,您就进入了动态世界。

分布式持久渲染 (DPR) 动态

DPR 是一种减少大型静态站点生成器 (SSG) 站点构建时间的策略。其想法是 SSG 构建最受欢迎页面的子集。对于其余页面,SSG 在第一次请求时按需构建它们并将它们保存到持久存储中。在初始请求之后,该页面表现得与其余已构建的静态页面完全一样。

较长的构建时间限制了大型用例选择 Jamstack。如果所有 SSG 工具都是基于 GoLang 的,我们可能不需要 DPR。但是,这并非大多数 Jamstack 工具采用的方向,并且大型网站的构建性能可能非常慢。

DPR 是一种手段,也是 Jamstack 发展壮大的必要条件。虽然它允许您在大型网站上使用 Jamstack 工作流程,但具有讽刺意味的是,我认为您不能将使用 DPR 的站点称为 Jamstack 站点。按需运行软件以生成网页当然听起来像是动态的。在第一次请求之后,使用 DPR 提供的服务页面是静态页面,这使得 DPR 比在动态站点前面放置 CDN 更“静态”。但是,它仍然是一个动态站点,因为前端和后端之间没有分离,并且它不可移植,这是 Jamstack 站点的一大支柱。

增量静态再生 (ISR) 动态

ISR 是一种类似但略有不同的 DPR 策略,用于减少大型 SSG 站点的构建时间。不同之处在于,您可以定期重新验证各个页面以模仿动态站点,而无需进行整个站点的构建。

对没有缓存版本的页面的请求将回退到该页面的陈旧版本或通用加载页面。

同样,这是一项激动人心的技术,它扩展了您使用 Jamstack 工作流程可以做的事情,但按需动态生成页面听起来像是动态站点会做的事情。

平面文件 CMS 动态

平面文件 CMS 使用文本文件而不是数据库来存储内容。虽然平面文件 CMS 从堆栈中删除了动态元素,但它仍然会动态呈现响应。

界限已划定

探索和讨论这些边缘案例可以让我们更好地理解所有这些术语的限制。此练习的重点不是教条式地创建静态或 Jamstack 网站。而是为了让我们能够用通用的语言来讨论在从一个概念跨越到另一个概念的边界时所做出的权衡。

权衡本身绝对没有错。并非所有内容都可以是纯粹的静态网站。在许多情况下,权衡是有意义的。例如,假设前端需要知道访问者的国家/地区。有两种方法可以做到这一点

  1. 在页面加载时,执行 Ajax 调用以从 API 查询国家/地区。(Jamstack)
  2. 使用边缘函数在响应中的 HTML 中动态插入国家/地区代码。(动态)

如果拥有国家/地区代码是一项锦上添花的功能,并且网页不需要立即使用它,那么第一种方法是一个不错的选择。页面可以是静态的,如果 API 调用不起作用,则可以优雅地失败。但是,如果页面需要国家/地区代码,则使用边缘函数动态添加它可能更有意义。它会更快,因为您不需要执行第二个请求/响应周期。

关键是要了解您要解决的问题,并考虑使用不同方法进行权衡。您最终可能会使大部分站点成为 Jamstack 站点,而一部分是动态的。这完全没问题,并且可能是您的用例所必需的。通常,您越接近静态,您的站点速度就越快、安全性就越高、可扩展性就越好。

这仅仅是讨论的开始,我很想听听您的想法。您会在哪里划定界限?静态和 Jamstack 对您意味着什么?您现在是坐在椅子上还是凳子上?