简单搭建自己vue-ssr-demo

原创 DarkNight 随笔 vue 70阅读 4 天前 举报

搭建自己简单的ssr-demo

demo地址 https://github.com/darkNightMan/vue-ssr

Build Setup

项目结构


前言

最近在琢磨ssr的渲染原理,通过这几天的学习和了解也看了很多文章和一些demo,对于一个新手来说学习成本相对会比较高,无论是对webpack的打包机制
和对vue生命周期的理解,以及对服务端node服务端掌握都是需要一定的积累的, 每个人的写法和讲解都有不同再刚开始接触的也是有很多疑问
只能通过慢慢去理解别人消化的东西然后慢慢转换成自己理解范畴,所以自己也在不断试错和采坑中,所有打算重零开始自己搭建一个ssr-demo
方便于更好理解和学习服务端ssr渲染的原理并分享学习过程中遇到的问题需注意的地方同时希望能够对学习SSR的朋友起到一点帮助。

服务端渲染的优点

1.更好的SEO,搜索引擎爬虫可以抓取渲染好的页面
2.更快的内容到达时间(首屏加载更快),因为服务端只需要返回渲染好的HTML,这部分代码量很小的,所以用户体验更好

服务端渲染的缺点

1.首先就是开发成本比较高,比如声明周期钩子函数(beforeCreate、created)能同时运行在服务端和客户端.
2.由于服务端渲染要用Nodejs做中间层,所以部署项目时,需要处于Node.js server运行环境。在高流量环境下,还要做好服务器负载和缓存策略

SSR的实现原理


先来一张图官方的图解

aratar

大概意思就是在服务端生成html片段,实际上当然是会复杂点,比如服务端返回html片段,客户端直接接受显示,不做任何操作的话
浏览器端无法触发点击事件这路由跳转这些的所以客户端便只需要激活这些静态页面,让他们变成动态的。
通过vue提供 vue-server-renderer 转换成静态html片段,返回给客户端。会在根节点上附带一个 data-server-rendered="true" 的特殊属性。
让客户端 Vue 知道这部分 HTML 是由 Vue 在服务端渲染的,并且应该以激活模式进行挂载

需注意的地方

vue-server-renderer 的版本 要与 vue版本一致
服务端渲染只会执行 vue 的两个钩子函数 beforeCreate 和 created
服务端渲染无法访问 window 和 document等只有浏览器才有的全局对象。
假如你项目里面有全局引入的插件和JS文件或着在beforeCreate和created用到了的这些对象的话,是会报错的,因为服务端不存在这些对象。

根据图解一步一步来拆分代码

从图可以看出app.js里面包含了vue 组件 vuex状态管理器 router路由...所以接下来将对我们所熟悉的 这几个文件对这些代码分隔进行一些改造
为了防止后端渲染中很容易导致交叉请求状态污染,导致数据流被污染了。所以避免状态单例,我们不应该直接创建一个应用程序实例,而是应该
暴露一个可以重复执行的工厂函数,为每个请求创建新的应用程序实例,同样router和store入口文件也需要重新创建一个实例这几个文件都已
createXXX这种方式声明函数名

store.js 改造 暴露一个createStore 工厂函数


router.js 同样改造 暴露一个createRouter 工厂函数方便每次访问创建一个新的实例


app.js 创建一个新的实例:

接下来webpack打包入口的js代码 一个需要运行在客户端 一个运行在服务端

客户端打包入口 entry-client.js

服务端打包入口 entry-server.js
==*router.getMatchedComponents() 在测试中发现当调用这个方法时只能获取到当前路由第一个根组件里面asyncData 里面的方法==
==如果当前路由有多个子组件的话 并不能全部获取到如果在子组件预渲染数据的话此时可能还需要对改方法进行一些改造将当前路由==
==下所有的组件循环出来并调用每个组件里面的asyncData的方法==

当我们把服务端代码运行起来后异步调用组件里面asyncData

test.vue

webpack.server 打包配置

webpack.client.js 客户端打包配置

webpack.base.js

需要注意的一个地方vue-style-loader 和 style-loader 默认的Webpack样式加载程序不是同构的
所以当打包出来是没问题可是运行在服务端就会报错了后来在github也有人遇到同样的问题看到尤大大的回答
image
所以在这里使用vue-style-loader

当启动ssr渲染的时候 使用 index.pro.html模板

开发模式下使用 index.dev.html 模板

最后start.js node服务端代码


vue vue-server-renderer提供了 2个api方法 一个是 createRenderer() 和 createBundleRenderer()

createRenderer需要传一个vue的实列
createBundleRenderer无需传入app 实列对象通过webpack打包出来的bundle文件在使用 clientManifest 时,自动注入资源链接(asset links)和资源预加载提示(resource hints)
最后通过renderToString()方法,将Vue实例转换为字符串插入到html文件

项目梳理

最后启动node服务测试ssr 服务端渲染查看页面源代码可以看到这一番景象服务端渲染成功了!

image

首屏加载渲染速度对比通过谷歌浏览器开发者工具-performace面板来比较服务端渲染和客户端渲染

通过几张图来对比看看

客户端渲染
image

服务端渲染
image

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复