您现在的位置是:首页 >其他 >【三十天精通Vue 3】第十七天 Vue 3的服务器渲染详解网站首页其他

【三十天精通Vue 3】第十七天 Vue 3的服务器渲染详解

陈书予 2023-06-12 00:00:03
简介【三十天精通Vue 3】第十七天 Vue 3的服务器渲染详解

请添加图片描述

✅创作者:陈书予
🎉个人主页:陈书予的个人主页
🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区
🌟专栏地址: 三十天精通 Vue 3

引言

Vue 3 是一款非常流行的前端框架,它提供了一系列强大的功能来构建现代化的Web应用程序。其中,服务器端渲染(Server Side Rendering,SSR)是Vue 3 的一个非常重要的特性,它可以显著提高应用程序的性能和SEO优化效果。本篇文章将对Vue 3 服务器端渲染进行详细的介绍和分析,包括基础概念、基础配置、实践和最佳实践等内容。

一、Vue 3 服务器端渲染概述

1.1 服务器端渲染的概念

服务器端渲染(Server Side Rendering,SSR)是一种将Web页面在服务器端预先渲染成HTML字符串,然后将其直接发送给客户端浏览器的技术。与传统的客户端渲染(Client Side Rendering,CSR)相比,服务器端渲染可以提高页面加载速度、SEO效果和用户体验。

1.2 Vue 3 中的服务器端渲染

Vue 3 提供了一个官方的服务器端渲染方案,可以将Vue应用程序渲染成HTML字符串,并在服务器端生成静态HTML文件。Vue 3 的服务器端渲染采用了一些新的特性,如Composition API和Teleport等,可以更好地支持服务器端渲染的需求。

1.3 Vue 3 服务器端渲染的优势和劣势

Vue 3 服务器端渲染的优势包括:

  • 提高页面加载速度:由于服务器端已经将页面渲染成HTML字符串,客户端只需要下载和解析HTML即可展示页面,而无需等待JavaScript代码下载和执行。
  • 改善SEO效果:搜索引擎爬虫可以直接抓取服务器端渲染后的HTML页面,提高了网站在搜索引擎中的排名。
  • 提高用户体验:页面渲染速度更快,用户能够更快地看到内容,减少了等待时间。

Vue 3 服务器端渲染的劣势包括:

  • 服务器端渲染的实现较为复杂,需要对服务器端的运行环境、路由配置、数据获取和CSS处理等方面进行特别的考虑和处理。
  • 服务器端渲染的性能消耗较大,需要消耗更多的服务器资源。

二、Vue 3 服务器端渲染的基础

2.1 服务器端渲染的基础配置

在进行 Vue 3 服务器端渲染之前,需要进行一些基础配置,包括安装相关的依赖和设置一些基本的配置项。下面是一些常用的服务器端渲染配置:

  1. 安装依赖

在进行服务器端渲染之前,需要安装相关的依赖。可以使用以下命令来安装依赖:

npm install vue vue-server-renderer express

其中,vue 是 Vue 3 的核心库,vue-server-renderer 是服务器端渲染相关的库,express 是一个常用的 Node.js Web 框架。

  1. 配置服务器端入口文件

创建服务器端入口文件 server.js,该文件中包含服务器的基本配置和路由处理。以下是一个基本的服务器端入口文件示例:

const express = require('express')
const { createSSRApp } = require('vue')
const { renderToString } = require('@vue/server-renderer')

const app = express()

// 服务器端路由处理
app.get('*', async (req, res) => {
  // 创建应用实例
  const app = createSSRApp({
    // 应用程序选项
  })

  try {
    // 渲染应用程序
    const html = await renderToString(app)
    res.send(html)
  } catch (err) {
    res.status(500).send('Internal Server Error')
  }
})

// 启动服务器
app.listen(3000, () => {
  console.log('Server running at http://localhost:3000')
})

在该示例中,我们使用 Express 框架来创建了一个基本的服务器,并对所有的请求进行了路由处理。当收到请求时,服务器会创建一个应用实例,然后使用 renderToString 方法将应用渲染成 HTML 字符串,并将其发送回客户端。

  1. 配置客户端入口文件

创建客户端入口文件 client.js,该文件包含了客户端的基本配置和路由处理。以下是一个基本的客户端入口文件示例:

import { createApp } from 'vue'
import App from './App.vue'

// 创建应用实例
const app = createApp(App)

// 启动应用
app.mount('#app')

在该示例中,我们使用 Vue 3 的 createApp 方法来创建一个应用实例,并使用 mount 方法将其挂载到 HTML 页面中。

2.2 使用 Vite 进行服务器端渲染

Vite 是一个基于浏览器原生 ES imports 开发的前端构建工具,它能够实现快速的冷启动和热更新,同时支持服务器端渲染。

在使用 Vite 进行服务器端渲染时,我们需要按照以下步骤进行配置:

  1. 安装相关依赖
bashCopy code
npm install vite vue-server-renderer express

其中,vite 是 Vite 的核心依赖,vue-server-renderer 是 Vue 3 服务器端渲染的核心依赖,express 则是用于搭建服务器的依赖。

  1. 创建 Vite 配置文件

在项目根目录下创建一个名为 vite.config.js 的文件,用于配置 Vite 的相关参数。具体配置可以参考 Vite 官方文档进行设置。

const { createServer: createViteServer } = require('vite')
const { createRenderer } = require('vue-server-renderer')
const express = require('express')

const app = express()

const isProd = process.env.NODE_ENV === 'production'

async function createServer() {
  const viteServer = await createViteServer({
    server: {
      middlewareMode: true,
    },
  })

  app.use(viteServer.middlewares)

  const renderer = createRenderer({
    template: `<!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>{{ title }}</title>
    </head>
    <body>
      <!--vue-ssr-outlet-->
      <script src="/@vite/client"></script>
      <script src="/src/entry-server.js"></script>
    </body>
    </html>
    `,
  })

  app.get('*', async (req, res) => {
    const context = {
      url: req.url,
      title: 'Vue 3 SSR',
    }

    try {
      const html = await renderer.renderToString(context)
      res.send(html)
    } catch (err) {
      console.error(err)
      res.status(500).send('Internal Server Error')
    }
  })

  app.listen(3000, () => {
    console.log('Server running at http://localhost:3000')
  })
}

createServer()

上述代码中,我们首先引入了相关依赖,然后创建了一个 Express 应用程序实例。在应用程序中,我们使用 Vite 的 middlewares 中间件来处理静态资源文件的请求。接着,我们创建了一个 Vue 3 服务器端渲染的渲染器实例,并在 Express 应用程序中创建了一个处理所有路由的处理程序。当请求到来时,我们将请求的 URL 以及页面标题传递给渲染器实例进行页面渲染,最终将渲染结果发送给客户端。

  1. 创建入口文件

创建入口文件的步骤如下:

  1. 在项目根目录下创建一个名为 entry-server.js 的文件,该文件将用于服务器端渲染的入口。
  2. entry-server.js 中导入 createApp 函数和根组件。
  3. 创建一个函数 renderToString,该函数将用于渲染页面。
  4. 创建一个函数 createServerRenderer,该函数将返回一个对象,其中包含一个函数 renderToString,这个函数将在服务器端使用。
  5. 导出 createServerRenderer 函数。

下面是示例代码:

// entry-server.js

import { createApp } from './app'
import { renderToString } from '@vue/server-renderer'

const { app, router } = createApp()

function renderToStringWithRouter(url) {
  router.push(url)
  return renderToString(app)
}

export default function createServerRenderer() {
  return {
    renderToString: renderToStringWithRouter
  }
}

在该示例中,我们使用 @vue/server-renderer 中的 renderToString 函数进行渲染。我们还定义了一个名为 createServerRenderer 的函数,并将其导出。该函数返回一个对象,其中包含一个名为 renderToString 的函数。在这个示例中,我们创建了一个名为 renderToStringWithRouter 的函数,该函数在渲染之前调用路由器来设置正确的路由状态。

值得注意的是,在实际项目中,createApp 函数可能会包含其他的插件和组件,具体的内容根据项目的需求而定。

三、Vue 3 服务器端渲染实践

3.1 服务器端渲染的基本步骤

在 Vue 3 中进行服务器端渲染的基本步骤如下:

  1. 创建一个 Vue 实例,并将其挂载到一个空的 HTML 模板中。
  2. 根据路由地址获取需要渲染的组件。
  3. 调用组件的 asyncData 方法获取组件需要的数据。
  4. 将获取到的数据通过 props 传递给组件。
  5. 在服务器端使用 renderToString 方法将 Vue 实例渲染为字符串。
  6. 将渲染后的 HTML 字符串发送给客户端。

3.2 服务器端渲染中的路由处理

在服务器端渲染中,路由处理需要特殊注意,因为服务器端的路由与客户端的路由是不一样的。在服务器端渲染中,需要根据请求的路由地址获取对应的组件并进行渲染。

为了实现服务器端的路由处理,可以使用 Vue Router 提供的 createRouter 方法和 createMemoryHistory 方法来创建路由实例和路由历史实例。创建完路由实例和路由历史实例后,可以使用 router.push 方法来根据请求的路由地址进行路由跳转,并获取需要渲染的组件。

import { createMemoryHistory, createRouter } from 'vue-router'

const routes = [
  // 定义路由规则
  // ...
]

// 创建路由实例和路由历史实例
const router = createRouter({
  history: createMemoryHistory(),
  routes
})

// 在服务器端通过路由跳转获取需要渲染的组件
router.push(context.url)

3.3 服务器端渲染中的数据获取

在客户端渲染中,通常使用异步请求来获取组件需要的数据。但在服务器端渲染中,由于没有浏览器环境,无法使用异步请求,需要使用另外的方式来获取数据。

为了解决这个问题,可以在组件中定义一个 asyncData 方法,该方法返回一个 Promise 对象,在服务器端渲染时调用该方法来获取组件需要的数据。在调用 asyncData 方法时,需要传递路由参数和 store 实例,以便在方法中使用。

import { createStore } from 'vuex'

const store = createStore({
  // ...
})

export default {
  // ...
  async asyncData({ params, store }) {
    await store.dispatch('fetchData', params.id)
  }
}

3.4 服务器端渲染中的 CSS 处理

在服务器端渲染中,需要注意 CSS 的处理,因为在客户端渲染中,浏览器会自动加载和解析 CSS,但在服务器端渲染中,没有浏览器环境,需要手动处理 CSS。

为了解决这个问题,可以使用一些工具来处理 CSS,如使用 vue-server-renderer 提供的 renderStyles 方法来生成 CSS 字符串,并在 HTML 模板中添加 <style> 标签来引入 CSS。

import { createSSRApp, renderToString } from 'vue'
import { renderStyles } from '@vue/server-renderer'

const app = createSSRApp(App)

// 渲染 Vue 实例为字符串
const html = await renderToString(app)

// 生成 CSS 字符串
const css = await renderStyles()

// 在 HTML 模板中添加 CSS
const finalHtml = `
  <html>
    <head>
      <style>${css}</style>
    </head>
    <body>${html}</body>
  </html>
`

除此之外,还可以使用一些 CSS 预处理器或者 CSS-in-JS 的方式来处理 CSS。例如,可以使用 sass-loader 来编译 SASS 文件,并将生成的 CSS 字符串添加到 HTML 模板中。另外,还可以使用 CSS-in-JS 的库如 styled-components 来在组件内定义样式,并在服务器端渲染时生成对应的 CSS 字符串。

3.5 服务器端渲染中的性能优化

以下是在Vue 3服务器端渲染中进行性能优化的几个步骤:

  1. 使用异步组件:在Vue 3中,可以使用 defineAsyncComponent 方法来定义异步组件。当组件被渲染时,该方法会返回一个Promise对象,组件将在该Promise对象解析后渲染。这可以减少初始加载的文件大小和组件的数量。
  2. 缓存组件:在服务器端渲染中,组件的重复渲染是常见的情况。为了避免重复渲染,可以使用缓存技术来缓存已经渲染的组件,以便在后续请求中重复使用。
  3. 优化数据获取:在服务器端渲染中,由于没有浏览器环境,无法使用异步请求来获取数据。因此,在获取数据时,需要尽可能地减少数据请求的次数,可以通过将多个数据请求合并为一个请求,或使用缓存来减少数据请求的次数。
  4. 优化CSS:在服务器端渲染中,需要特别注意CSS的处理,因为在服务器端渲染中,CSS是同步加载的。为了避免CSS阻塞渲染,可以将CSS提取为独立的文件,或使用内联CSS。
  5. 使用CDN:使用CDN可以提高静态文件的加载速度,并减少服务器负载。可以将静态文件存储在CDN上,并在服务器端渲染中使用CDN链接来加载静态文件。

四、Vue 3 服务器端渲染最佳实践

4.1 服务器端渲染的最佳实践

以下是服务器端渲染的最佳实践:

  1. 使用异步组件和动态导入来减小打包文件的大小,提高服务器端渲染的性能。
  2. 服务器端渲染需要特别注意内存泄漏问题,要及时释放不再使用的组件、实例和资源。
  3. 避免使用浏览器 API 和 DOM 操作,因为在服务器端没有浏览器环境。
  4. 避免在服务器端渲染中使用全局变量,因为不同请求之间共享同一个全局变量可能会导致意外的问题。
  5. 避免在服务器端渲染中使用单例模式,因为单例模式会导致不同请求之间共享同一个实例,可能会导致意外的问题。

4.2 在 Vue 3 中的服务器端渲染最佳实践

以下是在 Vue 3 中的服务器端渲染的最佳实践:

  1. 使用 @vue/server-renderer 包提供的 createRenderer 方法来创建服务器端渲染实例。
  2. 使用 createMemoryHistory 方法来创建路由历史实例,使用 createRouter 方法来创建路由实例。
  3. 在服务器端渲染中使用 asyncData 方法来获取组件需要的数据。
  4. 在服务器端渲染中使用 onBeforeRender 方法来进行一些操作,例如初始化一些全局变量。
  5. 使用 @vue/server-renderer 包提供的 renderToStringrenderToStream 方法来将 Vue 实例渲染为字符串或流。

五、Vue 3 服务器端渲染常见问题及解决方案

5.1 如何处理异步数据

在服务器端渲染中,由于没有浏览器环境,无法使用异步请求。为了解决这个问题,可以在组件中定义一个 asyncData 方法,该方法返回一个 Promise 对象,在服务器端渲染时调用该方法来获取组件需要的数据。在调用 asyncData 方法时,需要传递路由参数和 store 实例,以便在方法中使用。在客户端渲染时,可以在组件的 mounted 钩子函数中获取数据。

5.2 如何处理动态路由

在服务器端渲染中,动态路由需要特殊处理。需要在服务器端通过路由跳转获取需要渲染的组件,并将路由参数传递给组件。可以使用 Vue Router 提供的 createRouter 方法和 createMemoryHistory 方法来创建路由实例和路由历史实例,在服务器端通过路由跳转获取需要渲染的组件。

5.3 如何处理样式

在服务器端渲染中,需要将组件的样式打包成一个 CSS 文件,并在 HTML 模板中引入。可以使用 Vue CLI 提供的插件 @vue/cli-plugin-ssr 来自动化配置服务器端渲染的样式处理。该插件会将组件的样式提取出来,打包成一个 CSS 文件,并在 HTML 模板中引入该文件。

5.4 如何处理状态管理

在服务器端渲染中,由于每个请求都是一个新的实例,所以需要将状态管理实例在每个请求中重新创建。可以在服务器端创建一个新的状态管理实例,并将其传递给组件。在客户端渲染时,可以将服务器端传递的状态合并到客户端状态中。

5.5 如何处理 SEO

在服务器端渲染中,由于 HTML 是由服务器端生成的,所以可以在服务器端设置 HTML 的一些 SEO 相关的标签,例如 titlemeta 等。可以在 Vue 3 中使用 createHead 方法来创建一个头部管理实例,在组件中使用该实例来设置 HTML 的头部标签。在服务器端渲染时,可以将头部标签的内容添加到 HTML 模板中。
在这里插入图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。