VUE项目是SPA的项目,既可以做SSR服务器渲染也可以CSR客户端渲染
SPA (Single Page Application)
SPA是一种单页面应用的Web应用的设计模式。
在这种模式下,用户在浏览网站时,页面不会重新加载或只会部分重载
-
用户体验:
- SPA提供了一种接近原生应用的体验,页面切换快速且流畅。
- 用户交互更加直接,减少了等待新页面加载的时间。
-
页面加载方式:
- 初始加载时,会一次性加载大量的HTML、CSS和JavaScript代码。
- 随后的用户交互通过AJAX等技术从服务器获取数据,并动态更新DOM(文档对象模型),而不需要重新请求整个页面。
-
URL处理:
- 使用浏览器的历史API或者hashbang(#!)来改变URL路径,使得用户可以在不同的“页面”状态之间导航,并且可以使用后退按钮。
- URL的变化不会导致页面刷新。
-
前后端分离:
- 前端负责展示逻辑和用户界面,而后端则主要处理数据处理和业务逻辑。
- 这种分离有助于开发团队并行工作,并且可以更容易地扩展应用。
-
SEO(搜索引擎优化)挑战:
- 初始的页面内容是通过JavaScript动态生成的,这可能会影响搜索引擎对页面内容的理解,进而影响SEO排名。
- 不过,现代搜索引擎如Google已经能够执行JavaScript来索引SPA中的内容,但这依然可能不如传统的静态页面那样高效。
-
性能:
- SPA可能会在首次加载时下载较多的数据,这可能会导致较长的加载时间。
- 但是,由于后续的页面转换不需要重新加载整个页面,所以可以提高响应速度。
-
开发和维护:
- SPA通常依赖于现代前端框架如React、Vue.js或Angular,这些框架提供了丰富的工具和库来帮助构建复杂的用户界面。
- 单页应用的复杂性可能会增加维护成本,特别是在没有良好架构设计的情况下。
-
资源消耗:
- SPA通常比多页面应用消耗更多的客户端资源,因为它需要在客户端解析和渲染所有内容。
CSR客户端渲染
在我们平常写VUE项目的时候大部分时候使用的都是CSR客户端渲染的方式
其中页面的主要内容和动态数据都是在用户的浏览器中通过JavaScript生成的。
这就导致了SEO的排名会靠后,搜索引擎爬虫可能无法有效地执行JavaScript代码,它们可能无法完全理解和索引通过JavaScript动态生成的内容。
我们直接创建一个vite项目,运行后可以看到
在浏览器中只有一个app的挂载点,并且其他的页面都是通过JavaScript去生成的,也就意味着,像响应式之类的操作,以及页面的交互都是在浏览器端完成的,但是如果是搜索引擎爬虫的话就没办法高效的读取,就意味着对其不太友好,搜索引擎爬虫希望的是访问得到的就是有完整结构的html
这时候就需要通过服务端将页面处理好发给前端
SSR服务端渲染
服务端渲染(Server-Side Rendering, SSR)是一种Web开发技术,它允许在服务器端生成完整的HTML页面,并将其发送到客户端浏览器。这种方式与传统的客户端渲染(CSR)不同,在CSR中,HTML页面的初始加载仅包含基本结构,而动态内容则通过JavaScript在客户端加载后动态生成。
接下来我们写一个例子
我们先添加对应的依赖
npm install express vue @vue/server-renderer @vue/compiler-sfc @vue/compiler-ssr
分别是以下依赖
"express": "^4.17.2",
"vue":"^3.2.26",
"@vue/server-renderer":"^3.2.26"
const express = require("express"); // 类koa 简单backend框架 commonjs
const app = express();
const Vue = require("vue"); // vue走向后端
const readerer3 = require("@vue/server-renderer"); // ssr
const vue3Compile = require("@vue/compiler-ssr"); // 编译模板
我们创建一个vue的页面
const vueapp = {
template: `
<div>
<h1 @click="add">{{num}}</h1>
<ul>
<li v-for="(todo, n) in todos">{{n+1}}-- {{todo}}</li>
</ul>
</div>
`,
data() {
return {
num: 1,
todos: ["吃饭", "睡觉", "打豆豆"],
};
},
methods: {
add() {
this.num++;
console.log("11");
},
},
};
template: 定义了组件的 HTML 结构,包含一个可点击的标题和一个列表。data: 返回组件的状态,包括num和todos。methods: 包含一个add方法,每次点击标题时增加num的值并打印 "11" 到控制台。:key: 在v-for中使用:key来确保列表渲染时性能更佳。-template: 定义了组件的 HTML 结构,包含一个可点击的标题和一个列表。data: 返回组件的状态,包括num和todos。methods: 包含一个add方法,每次点击标题时增加num的值并打印 "11" 到控制台。:key: 在v-for中使用:key来确保列表渲染时性能更佳。
接下来我们为vueapp添加ssrRender属性
vueapp.ssrRender = new Function(
"require",
vue3Compile.compile(vueapp.template).code
)(require);
添加一个get请求
// http 协议基于请求响应的简单协议
app.get("/", async (req, res) => {
// 爬虫 拿到 组件的html 在vue之前
// res.end('hello world');
// 创建服务器端的渲染app
let vapp = Vue.createSSRApp(vueapp);
// 渲染
let html = await readerer3.renderToString(vapp);
const title = "vue3 ssr";
let ret = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>
</head>
<body>
<div id="app">${html}</div>
</body>
</html>
`;
res.end(ret);
});
创建 Vue 应用
// 创建服务器端的渲染app
let vapp = Vue.createSSRApp(vueapp);
let vapp = Vue.createSSRApp(vueapp);: 创建一个 Vue 3 服务器端渲染的应用实例vapp,其中vueapp是之前定义的 Vue 组件。这个实例将用于生成 HTML。
渲染组件
// 渲染
let html = await readerer3.renderToString(vapp);
let html = await readerer3.renderToString(vapp);: 使用@vue/server-renderer提供的renderToString方法,将 Vue 应用vapp渲染成 HTML 字符串。这个过程是异步的,所以使用await关键字。### 渲染组件
// 渲染
let html = await readerer3.renderToString(vapp);
let html = await readerer3.renderToString(vapp);: 使用@vue/server-renderer提供的renderToString方法,将 Vue 应用vapp渲染成 HTML 字符串。这个过程是异步的,所以使用await关键字。
生成完整的 HTML 响应
const title = "vue3 ssr";
let ret = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>
</head>
<body>
<div id="app">${html}</div>
</body>
</html>
`;
const title = "vue3 ssr";: 定义 HTML 页面的标题。let ret =...`` : 使用模板字符串生成完整的 HTML 文档。${html}会被替换为渲染后的 Vue 组件的 HTML 内容。### 生成完整的 HTML 响应
const title = "vue3 ssr";
let ret = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>
</head>
<body>
<div id="app">${html}</div>
</body>
</html>
`;
const title = "vue3 ssr";: 定义 HTML 页面的标题。let ret =...`` : 使用模板字符串生成完整的 HTML 文档。${html}会被替换为渲染后的 Vue 组件的 HTML 内容。
启动项目
app.listen(9093, () => {
console.log("server is running at port 9093");
});
最后执行后端并访问前端即可看到页面显示
并且该页面是由后端处理好,前端直接显示的,这也就是SSR服务器渲染