服务端渲染 SSR 概述

Huy大约 6 分钟框架ssr

服务端渲染 SSR 概述

服务端渲染这块,Vue 官网总结的非常好。《实现一个基础的服务端渲染》open in new window 官网的案例中,实现了一个基础的应用,这里再总结一下,Vue 原生的服务端渲染实现过程。

  1. 创建 Vue 应用:使用 Vue CLI 或手动创建一个 Vue 应用,并添加支持服务端渲染的插件,例如 @vue/server-renderer
  2. 编写服务端渲染入口文件:根据需要,编写服务端渲染入口文件,通常命名为 server-entry.js。该文件需要导出一个函数或 Promise,用于生成服务端渲染的 HTML 字符串。
  3. 编写服务端路由和控制器:根据需要,编写服务端路由和控制器,处理客户端请求并生成相应的服务端渲染 HTML。
  4. 构建和打包:使用 Vue CLI 或其他构建工具,将客户端代码和服务端代码分别打包成两个独立的 bundle 文件。
  5. 启动服务端:在服务器上启动 Node.js 环境,并运行服务端代码,监听客户端请求并返回服务端渲染 HTML。
  6. 客户端激活:在客户端代码中,通过 createSSRApp 函数创建 Vue 应用实例,并使用 hydrate 函数将服务端渲染的 HTML 字符串与客户端应用进行关联,从而完成客户端激活。

如果对上述流程不是很熟悉,强烈建议跟着 Vue 官网走一遍流程。当然,官网中的案例需要知道一点点 Node.js 的知识,所创建的服务端渲染是利用了 express 框架。

官网的几个细节:

  • createApp:创建应用,直接挂载到页面上;

  • createSSRApp:服务端渲染的方式,创建应用,是在激活的模式下挂载应用;

    激活模式是指:为了使客户端的应用可交互,Vue 需要执行一个激活步骤。在激活过程中,Vue 会创建一个与服务端完全相同的应用实例,然后将每个组件与它应该控制的 DOM 节点相匹配,并添加 DOM 事件监听器。

  • renderToString:服务端是使用的渲染 API,利用此来渲染。

服务端渲染页面同客户端激活页面,在这个过程中有一个页面交互过程,这个过程就是大名鼎鼎的 Hydration 水合。具体定义:指将服务端渲染生成的 HTML 字符串转换成客户端应用的状态和视图的过程。具体来说,当客户端应用加载并执行时,它会检查服务端生成的 HTML 中是否包含与客户端应用相同的 DOM 结构,如果存在,则使用该 DOM 结构,在此基础上进行事件绑定、路由切换等操作,从而保持与服务端渲染应用相同的状态和视图。

简单的讲,就是在最终打包的时候,会为客户端生成一个 client_bundle.js,用于激活应用,使页面有交互作用;再为服务端生成一个 server_bundle.js,用来服务端动态生成页面的 HTML。

在 Vue.js 中,实现 SSR 水合的过程主要包括以下几个步骤:

  1. 创建一个支持服务端渲染的 Vue 应用实例:使用 createSSRApp 函数创建一个新的 Vue 应用实例,并在该实例中注册组件、路由、数据等相应内容,以便在服务端和客户端之间共享。
  2. 在服务端渲染时生成 HTML:通过调用 renderToString 函数,将上一步创建的 Vue 应用实例渲染为 HTML 字符串。此时,Vue 会自动将应用实例中的数据和状态转换为 HTML 标记,并在其中添加特殊的占位符(例如 data-server-rendered="true")。
  3. 在客户端应用中进行水合:将服务端渲染生成的 HTML 字符串作为客户端应用的入口参数,再次调用 createSSRApp 函数创建一个新的 Vue 应用实例,并使用 hydrate 函数将服务端渲染的 HTML 和客户端应用进行关联。此时,Vue 会根据服务端渲染生成的 HTML 标记和占位符,恢复应用实例的状态和数据,从而保持与服务端渲染应用相同的状态和视图。
  4. 启动客户端应用:客户端应用启动后,会检查页面中是否包含服务端渲染生成的 DOM 结构。如果存在,则使用该 DOM 结构,否则重新生成整个页面。

需要注意的是,在进行 SSR 水合时,需要保证服务端渲染和客户端应用的代码和逻辑尽可能一致,以避免因代码差异导致的状态不一致或错误。此外,由于服务端渲染和客户端应用的生命周期和行为有所不同(例如,服务端没有 DOM 环境,无法执行一些客户端特定的操作),因此还需要针对不同的环境和需求进行相应的处理和优化。

实际上,项目开发大概率不会用到上述的原生 API,因为生成一个 SSR 应用还需要考虑很多细节:

  • 服务器请求过程中, 应确保返回 HTML 包含正确的客户端资源链接和最有的资源加载提示;
  • 还需要一种通用的方式管理路由(Vue Router)、数据获取和状态存储(Pinia)。

目录说明

  1. nuxt.config.js:这个文件是整个 Nuxt.js 项目的配置文件,其中包含全局的设置和选项,如路由配置、模块、插件、中间件等。
  2. pages/ 目录:这个目录包含了所有的页面组件,可以根据自己的需要在该目录下创建子目录和对应的页面组件。
  3. layouts/ 目录:这个目录包含了应用程序的布局和结构组件,可以通过修改这些组件来改变应用程序的外观和行为。
  4. components/ 目录:这个目录包含了应用程序的可复用 UI 组件,如果某个 UI 组件在多个页面中都会使用,则应将其放在该目录下。
  5. store/ 目录:这个目录包含了 Vuex 状态管理模式的相关文件。应当注意,在 Nuxt.js 中,Vuex 不是必须的,因此可以按照自己的需要编写或删除一些文件。
  6. static/ 目录:这个目录包含了静态文件,例如图片、图标、favicon.ico 等。这些文件会被直接复制到最终生成的 Web 应用程序的根目录下。
  7. assets/ 目录:这个目录包含了公共的样式表、JavaScript 脚本和图片等资产。与 static 目录不同,这些文件需要通过 Webpack 打包处理,并且最终会被插入到 HTML 页面中。
  8. plugins/ 目录:这个目录包含了一些插件文件,可以用来扩展 Vue.js 的功能或者以其他方式影响应用程序的行为。
  9. middleware/ 目录:这个目录包含了一些中间件文件,可以用来处理全局请求拦截、页面级别的路由鉴权等任务。
  10. serverMiddleware/ 目录:这个目录包含了一些服务端中间件文件,可以用来处理 API 请求、鉴权、日志记录等操作。
Loading...