前言
当面试官问你谈谈你对spa的理解时,各位彦祖可千万别说:"面试官我认识xx会所的xx技师,待会一起去吗?"现在我们聊聊spa(single page web application)单页应用.
什么是spa
spa是指的是单页应用,认识vue的兄弟们可能对此并不陌生,没错vue就是单页应用,单页应用有以下两个特点:
- 整个项目只有一个页面
- 页面中的内容是动态的,以组件的形式展示,靠路由的映射关系匹配组件
在vue中只有一个html文件,我们写的vue后缀的文件就是一个代码片段,我们可以将代码片段在需要展示时挂载出来,根据这个特点有个很明显的优点就是组件化开发,当出现问题时重要检查对应的组件代码即可,易于代码的维护
在多页应用中,我们需要写很多的html文件,当url发生改变时,就要重新请求相应的资源;但是单页应用不需要,单页应用会在初次读取时会将所有文件加载好,当需要对应的文件时直接展示,这就是它的第二个优点:页面切换快,体验好
但是有有优点就一定有缺点,这种模式会带来两个严重的问题:
1.因为初次读取时会将所有文件加载好,所以会导致首页加载慢
2.当我们查看源代码,就会看到这样的情况,看不到js代码,没有有效的内容,这样虽然可以防止被爬虫爬到,但是不利于搜索引擎搜索到,不利于seo(搜索引擎)
ssr
ok,我们讲完了spa的优缺点,那我们该怎么解决?现在我来介绍一下mvp,SSR(server side render)服务端渲染
服务器端渲染(Server-Side Rendering,SSR)是一种将页面的 HTML 内容在服务器端生成并发送给客户端的技术。
1. 服务器端渲染的基本流程
-
客户端发起请求:
- 用户在浏览器中输入 URL 或点击链接,浏览器向服务器发送请求。
-
服务器处理请求:
- 服务器接收到请求后,根据路由和参数生成页面的 HTML 内容。
- 服务器会执行 JavaScript 代码(如 React、Vue.js 的组件渲染逻辑),生成完整的 HTML 字符串。
-
返回 HTML 给客户端:
- 服务器将生成的 HTML 内容发送给客户端浏览器。
-
客户端渲染:
- 浏览器接收到 HTML 后,立即显示页面内容。
- 同时,浏览器会下载并执行 JavaScript 文件,接管页面的交互逻辑(即“注水”,Hydration)。
代码实现:
const express = require('express');
const app = express();
const Vue = require('vue');
const vue3Compiler = require('@vue/compiler-ssr');//编译器
const renderer = require('@vue/server-renderer')//渲染器
const vueapp = {//模拟前端传来要展示的首页
template: `
<div>
<h1 @click='add'>Hello, SSR!</h1>
<ul>
<li v-for="item in items" :key="item">{{ item }}</li>
</ul>
</div>
`,
data() {
return {
items: ['Item 1', 'Item 2', 'Item 3']
}
},
methods: {
add() {
this.items.push(`Item ${this.items.length + 1}`);
}
}
}
// 读取vue文件,编译成js代码
vueapp.ssrRender = new Function('require', vue3Compiler.compile(vueapp.template).code)(require);
app.get('/', async (req, res) => {
let vapp = Vue.createSSRApp(vueapp);
let html = await renderer.renderToString(vapp); // 渲染成html
const title = 'SSR Demo';
let ret = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>
</head>
<body>
${html}
</body>
</html>`;
res.send(ret);
})
app.listen(3000, () => {
console.log('SSR server is running on port 3000');
});
实现原理:
-
创建 node 服务
-
读取 vue 组件
-
借助 vue 自带编译器函数编译 vue 组件 得到 AST
-
借助 vue 自带渲染器函数渲染 AST 得到 html
-
拼接 html 模板
-
发送响应
这时就会有人说:主播主播.你的操作确实很强有没有更加简单强势的操作呢?
有的,兄弟,有的,
直接使用createssrapp就行了,人家尤雨溪早就想到了,cn.vuejs.org/guide/scali…