也许您已经听说过静态化和服务器渲染这两个术语。您也可能知道它们都可以改善 SEO,为您的网站或应用程序生成 HTML。如果您正在使用 React,那么使用 ReactDOMServer.renderToString() 就可以完成其中之一。
听上去,它们做的基本上是同一件事,对吗?好吧,它们几乎是一样的。下面让我解释一下。
静态渲染热切,服务器渲染懒惰
静态渲染和服务器渲染都可以为站点的每个 URL 生成对应的 HTML。不同之处在于,当用户请求每个文件时,静态化渲染仅在构建时发生一次,而服务器渲染则是在每次请求时都构建一次。
静态化渲染
使用静态化渲染时,您需要在用户访问站点时,提前为访问的每个页面生成一个 HTML 文件。然后,将这些文件放到服务器上,比如 S3 之类的云服务或运行 Nginx 之类的服务器来托管这些页面。
静态化渲染的优点是能够做到无脑的快速处理请求,因为在请求时无需动态生成任何内容。实际上,由于网站的响应都是提前生成的,因此您可以将文件存储在世界各地的 CDN 上。这给您的站点带来了不可思议的响应速度。但这也是有代价的。
使用静态化渲染,您需要提前为每个可能的请求生成响应。对于专注于高质量内容的网站,这是没问题的。像 Navi 这样的静态化渲染器可以在几秒钟内生成数百个页面。但是,如果您要构建无法预测所有可能请求的东西,例如搜索引擎,该怎么办?或者,如果您有很多用户在生成内容,并且响应随每个请求而变化,该怎么办?在这种情况下,您将需要服务端渲染。
服务端渲染
在 React 世界中,服务器渲染是指为每个请求按需生成 HTML 的过程。通常,您将通过安装运行 express 或 Next.js 之类的服务器来实现此目的,该服务器会在每个请求时呈现您的 React App,就像更传统的基于 PHP 或 Rails 的网站一样。
服务端渲染总是比提供静态内容慢。但是,您需要做很多额外的事情让服务端渲染的速度变得更快一些,而这种延迟是否重要,取决于您的业务需求。
当然,虽然服务端渲染存在速度短板,但它拥有了更好的灵活性。它允许您:
- 响应用户提出的任何请求,甚至您可能没有预想到的请求。
- 从数据库中提取最新内容,而不是从服务器中提取较旧的静态文件。
- 有选择地对未经身份验证的用户隐藏内容。
那我应该使用哪个呢?
答案是-取决于情况。
如果可以进行静态化渲染,它将为您提供更快、更低廉、更简单的解决方案。但是,如果您的站点需要提供满足以下任何要求的 HTML,则需要服务端渲染:
- 如果您无法预测所有可能的请求
- 如果响应内容根据请求用户不同而改变
- 如果响应内容很快过时
请记住,这些要求仅在需要为每个页面提供特定 HTML 用于 SEO 目的时,才需要服务器渲染。例如,社交网站或电商网站一般采用服务端渲染。
另一方面,如果您要构建与 SEO 不相关的内容(例如,位于登录屏幕后面的应用程序),则您的应用程序仅需要单个 HTML 文件。过去,这是迄今为止最简单的选择,因为这意味着您可以只使用 stock create-react-app。但是,静态化渲染和服务端渲染工具的改进在很大程度上弥补了简单性方面的不足,降低了开发成本。
渲染工具
几年前,当我第一次开始使用 React 构建网站时,静态化/服务端渲染非常困难。我甚至写了一篇文章告诉你不要这样做。但是现在情况发生了很大变化。
基于 React 的静态化渲染工具越来越多。gatsbyjs是一种流行的选择。对于更简单的方法,您可以尝试 Navi,它可以驱动该网站并与 create-react-app 一起使用。
至于服务端渲染,您有两个选择:Next.js 和 Express。使用 Next.js,您可以立即使用一个完整的框架和一个托管解决方案-但是将您的项目与 Next.js 绑定(后者已声明它们将不提供弹出选项)。如果这对您不起作用,那么您始终可以设置更传统的 Express 应用程序(而 Navi 的路由器使此操作比以往更加轻松!)
一点琐事
最后,让我解释一下您现在正在阅读的网站的工作方式。frontarm 是静态渲染的。每次内容更改时,都会使用 Navi 重新构建站点,然后将其推送到 S3。然后,当您发送请求时,它首先会使用 CloudFront 检查在地理位置上与您接近的缓存版本,然后再从 S3 请求它(如果失败)。
这就是为什么 Frontend Armory 感觉如此活跃的原因-都是由于路由和静态化渲染!