专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

Vue进阶篇-服务器端渲染SSR vue前端渲染

ins518 2024-10-06 10:29:36 技术文章 9 ℃ 0 评论

前一段时间看网友讨论的 为什么现在又流行服务端渲染html? ,关于现在的ssr的态度也是各有褒贬。但是不容置疑的是,SSR作为新的出现,是因为在SPA(Single-Page Application – 单页应用程序)流行之后,主要是解决前端开发语言来解决SPA出现问题的进一步解决方案。

吐槽:这几年刚刚开始流行的SPA还没开始学呢,现在已经变成了传统的了,真心是学不动啊!

传统SPA应用的优点是前后端分离,后端只负责提供数据,前端加载完之后体验良好,内容改变不需要加载全部页面,缓存数据,减少服务器压力,提高性能。这么牛,怎么会又缺点!!!

SPA工作的流程是第一次将所有需要的前端搭建的构建脚本资源文件全部下载下来,然后运行脚本异步加载数据,渲染页面,也正是这种特性造成的结果:

  • 首屏慢:第一次加载所有资源,然后才开始执行,那执行到这里优化不好的话,已经是几秒十几秒以后了。
  • SEO优化差:搜索引擎爬虫爬到这里是空的!空的!搜索引擎抓取的时候是不执行js脚本就跟谈不上什么异步请求了,当然Google最新技术在支持,但是什么时候用上呢?
  • 不能刷新:使用vue之后你会发现,好多页面刷新就意味着页面数据全部消失,前进后对都是消失,就需要自行编写前进后端的逻辑了。
  • 页面复杂度成倍提高,前端开发的要求提高。

这里提醒有些使用VUE开发管理平台的同学,面对业务提出要打开独立页面的需求的话,一定要用多tab的框架,不然用openwin的解决方案的话,每次打开新窗口都是首屏,都要加载会很慢的。

这时候就开始返回来去服务端渲染页面的技术来了。也是之前jsp php .net 之类的一直干的事儿,一样是模板引擎。只不过后端语言变成js,并且也使用模板引擎,vue的ssr也算是一种吧。ssr的出现就是为了解决上面提到的spa应用中的seo问题和首屏加载问题。

有舍必有得,SPA为追求极致性能产生,SSR为解决SPA的问题产生,也就损失了追求极致的问题。SSR需要占用服务器资源处理模板引擎来产生数据,势必造成服务器压力变大。服务器版本也不是单纯的只要能下载静态资源就行了,现在需要使用nodejs server环境了。是否真有必要上这个东西就要自行取舍了。

在之前的讨论帖中,有童鞋说应该搜索引擎来提高技术,这个呢Google虽然已经在做了,但是这个对搜索爬虫要求提升的可不是一个量级,Google也只是在小范围内在测试使用。至于百度,呵呵,他什么时候关注过为客户打好广告之外的事情呢?

基本使用与安装

先建立文件夹,新建server.js文件,内容是 根目录新建server.js文件,写入代码

const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer()
server.get('*', (req, res) => {
 const app = new Vue({
 data: {
 url: req.url
 },
 template: `<div>The website you visit is: {{ url }}</div>`
 })
 renderer.renderToString(app, (err, html) => {
 if (err) {
 res.status(500).end('Internal Server Error')
 return
 }
 res.end(`
 <!DOCTYPE html>
 <html lang="zh">
 <head><title>Hello</title></head>
 <body>${html}</body>
 </html>
 `)
 })
})
server.listen(8080,() => {
 console.log('服务器已启动!')
})

然后开始项目初始化及包安装

npm init //初始化项目
npm install vue //安装vue基础包
npm install express //安装服务器环境包
npm install vue-server-renderer //安装服务器渲染包
node server //安装包结束之后运行服务器

node server运行显示服务器已启动,就可以访问http://localhost:8080/ ,就可以显示内容了。而且呢,地址后面不管你输入啥,都是访问这个页面。

这时候打开谷歌浏览器的开发者工具查看 并且打开谷歌浏览器的开发者工具,查看Network => Doc => localhost => Response, 发现接收到的其实似乎已经是编译好的结果。

看上面的server.js代码,ssr的核心其实vue-server-renderer组件中renderToString,他将APP组件里面的内容编译后写入到输出模块里面。

页面模板和模板插值

上面只是简单的将组件最后插入,再来一个提前写好模板,然后在createRenderer()的时候就将模板写好。先写一个模板文件 index.tpl.html

<!DOCTYPE html>
<html lang="en">
 <meta charset="utf-8">
 <title>{{ title }}</title>
 {{{ meta }}}
 <body>
 <!--vue-ssr-outlet-->
 </body>
</html>

在这个模板中 双括号{{}} 是进行 HTML 转义插值,三括号{{{}}}是不进行HTML转义的插值,< !–vue-ssr-outlet– > 标签是对应组件输出的位置。

根目录的server.js文件内容对应的变更为

const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer({
 template: require('fs').readFileSync('./index.tpl.html', 'utf-8')
})
server.get('*', (req, res) => {
 const app = new Vue({
 data: {
 url: req.url
 },
 template: `<div>The website you visit is: {{ url }}</div>`
 })
 const context = {
 title: 'hello',
 meta: `
 <meta ...>
 <meta ...>
 `
 }
 renderer.renderToString(app, context,(err, html) => {
 console.log(html) 
 })
})
server.listen(8080,() => {
 console.log('服务器已启动!')
})

然后重新运行下npm run server/node server。重新访问链接对应的内容就发生了变化。

当然,其中模板填入的参数值不仅仅可以通过renderToString的第二个参数传进入,也可以与 Vue 应用程序实例共享 context 对象,允许模板插值中的组件动态地注册数据。

服务端代码的局限性

由于ssr是在用户访问阶段服务端直接渲染初始代码到客户端,为了降低最服务器的占用,响应式的数据特性就被禁用掉了。这样就产生了服务端vue组件代码和其他代码开发中的差别:

  • 生命周期钩子仅beforeCreate 和created 生效,其他只在客户端运行。注意避免原来created周期新建,destroyed 周期销毁之类的副作用代码的产生。
  • 操作windows和document的代码会在服务端报错抛出。
  • 注意使用相关第三方库(library)涉及以上API的问题
  • 自定义指令大多数都是直接操作dom,也会出错
  • 避免单例模式造成的请求交叉污染

遇到相关问题,可以自行查阅处理方案。

文末

当然,本文只起到理解概念入门的地步。真的需要又兴趣或者业务需要,建议直接去官网通读官网的教程,一定更有收获。当然也可以灵活运用,根据自己的业务需要引入redis,serverfetch之类的技术,让首屏速度及seo能提升到10ms以内,也不是不可能的。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表