深入探讨 Web 开发中的预渲染和 Hydration
像Next.js、Gatsby.js和Remix这样的框架大家或多或少使用过,但是它们具体是如何工作的呢
这些框架运用了预渲染(Pre-rendering)和 Hydration 等技术来构建高性能应用程序。在本文中,我们将讨论预渲染和 Hydration,以及为什么在构建单页面应用程序时它们是很重要的特性。为了理解这些概念,我们需要探究它们为什么被创建以及它们试图解决的问题
过去的 Web 开发:传统的 SSR
在传统 SSR 的时代,渲染和交互性是分开的。我们使用像Node.js、PHP、Java和Ruby on Rails这样的服务器端语言。 在我们的服务器中,我们使用像JSP和EJS这样的模板语言创建了视图。视图就是 HTML 页面,我们可以在其中注入 JavaScript 或 Java 来添加功能、从数据库查询中获取动态数据以及使用像JQuery这样的语言创建交互部分。
传统 SSR 的缺点
- 性能问题
- 每次用户请求一个页面时,都需要向服务器发出请求
- 这意味着会有一个整页重载。
- 复杂的查询可能会导致速度变慢。
- 可扩展性
- 全球覆盖:需要一个动态 CDN来缓存我们的动态文件。CDN 更适合静态内容
- 升级服务器:如果更多的用户开始使用该应用程序,服务器的需求就会增加。可能需要在资源上投入更多,例如通过添加更多服务器来进行扩展。
- 重复逻辑
- 我们可能会有重复的代码。例如,如果我们试图验证表单字段,我们就必须在 EJS 文件和您的 API 端点中都进行验证。
让我们看一下下面的代码片段,以了解这种重复逻辑的一个示例:
EJS 中的代码:
代码语言:javascript代码运行次数:0运行复制<form action="/submit-form" method="POST" id="myForm">
<label for="email">电子邮件:</label>
<input type="email" id="email" name="email" />
<button type="submit">提交</button>
</form>
<script>
document
.getElementById("myForm")
.addEventListener("submit", function (event) {
const email = document.getElementById("email").value;
if (!email.includes("@")) {
alert("请输入有效的电子邮件。");
event.preventDefault();
}
});
</script>
Express.js 中的代码:
代码语言:javascript代码运行次数:0运行复制import express from "express";
const app = express();
const path = require("path");
const port = 3000;
// 用于接收表单数据
app.use(
express.urlencoded({
extended: true,
})
);
// 视图引擎设置。需要一个名为 views 的文件夹
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.get("/", (req, res) => {
// 用于渲染视图
res.render("index", { errors: null });
});
app.post("/submit-form", (req, res) => {
const email = req.body.email;
if (!email.includes("@")) {
res.status(400).send("无效的电子邮件。");
return;
}
// 继续进行表单处理
});
app.listen(port, () => {
console.log(`沙盒正在端口 ${port} 上监听`);
});
传统的 SSR 存在显著的缺点,但单页面应用程序的出现标志着 Web 开发的新时代。
传统 SSR 与单页面应用程序
什么是单页面应用程序(SPA)?
单页面应用程序(SPA)是一种网络应用程序的实现方式,它只加载一个单一的网络文档,然后当需要显示不同的内容时,通过诸如 Fetch 等 JavaScript API 来更新该单一文档的主体内容。它允许用户在无需从服务器加载全新页面的情况下使用网站。
实现 SPA 的一种流行方式是使用 React。React 使我们能够创建快速的应用程序,并且比 DOM 操作方法更易于简化用户界面的更新。
它具有以下几个优点:
- 提升用户体验
- SPA 加载一个单一的 HTML 文件,并在用户与之交互时动态更新内容。所有这些操作都无需完全重新加载页面。
- SPA 可以轻松更新用户界面的状态,并根据应用程序上采取的操作向用户提供即时反馈。
- 减轻服务器负载
- 大部分工作由浏览器完成。这减轻了服务器的负载!
- 更好的可扩展性
- 现在大部分工作由浏览器完成。我们现在可以部署专门的服务器,专注于通过 API 提供数据服务。我们可以轻松地进行水平扩展。我们可以选择使用服务器或 Serverless 功能
- SPA 可以托管在静态 CDN 上,如Netlify。
随着像Vite和Create React App这样的工具链的加入,用于自动化现代 JavaScript 应用程序的设置,开发者们不再需要担心手动配置 Webpack。
实现 SPA 也存在一些缺点。其中一个主要问题是它依赖浏览器为我们加载所有的 JavaScript 和 HTML。这意味着在移动设备上以及对于网络速度较慢的用户,他们可能会在看到页面时遇到延迟。让我们来检查一下流程以解释这一点:
单页面应用程序流程
用户最终看到 HTML 页面需要几个步骤。
首先,浏览器会获取 HTML。这个初始的 HTML 会是空白且不正确的。为什么呢?因为内容是来自 JavaScript 的。这意味着浏览器需要花费时间来获取 JavaScript、加载它并执行它。由于初始的 HTML 是错误的,网络爬虫和搜索引擎将无法在网站上找到相关内容并跳过它。
看一下下面的 GIF 图。在这里,在 Chrome 开发者工具中禁用了 JavaScript。没有 JavaScript,网站就无法加载。如果启用了 JavaScript 但网络连接缓慢,用户可能会在较长时间内看到一个空白页面。
这是一个大问题。这导致了 Web 开发进入了预渲染时代。
进入具有预渲染和 Hydration 的新世界
为什么预渲染很重要?
我们意识到可以提前生成 HTML。它可以从我们的服务器或在构建时生成,具体取决于所使用的方法。
预渲染可以通过两种方式完成
SSR(SSR) 或 静态站点生成(SSG)
什么是 SSR?
在服务器上渲染 React 组件,然后将生成的 HTML 发送到浏览器。这可以提高 SEO 和初始加载时间。渲染过程在每个页面请求时发生。
什么是静态站点生成(SSG)?
在构建时生成静态 HTML 页面。这些页面可以快速提供服务,而不需要服务器实时渲染它们。
这两种方法都是有用的!现在用户收到的 HTML 将是正确的。他们将看到一个有内容的页面,而不是像使用 Vite 或 Create React App 时看到的空白页面。
但有一个问题:用户收到的 HTML 不是交互式的。他们不能点击它或提交表单。我们如何为我们的应用程序添加交互性呢?通过正确的 Hydration
发布评论