资讯专栏INFORMATION COLUMN

Vue.js SSR 内容总结

曹金海 / 1698人阅读

摘要:本文只是对官方文档和对官方的个人学习总结,说得不够完整的请见谅本文主要对以下几方面内容对的内容进行分析总结出现的原因的总体原理当中的数据预取在编写代码时候的限制的构建原理出现的原因单页应用有一个很大的缺点就是问题,搜索引擎目前只能对同步的进

本文只是对Vue.js官方SSR文档和对官方hackernews demo的个人学习总结,说得不够完整的请见谅

本文主要对以下几方面内容对Vue.js SSR的内容进行分析总结

SSR出现的原因

Vue.js SSR的总体原理

SSR当中的数据预取

SSR在编写代码时候的限制

SSR的webpack构建原理

SSR出现的原因

单页应用有一个很大的缺点就是SEO问题,搜索引擎目前只能对同步的javascript进行索引,但对于需要异步获取数据的单页应用来说,搜索引擎并不会抓取到它们的内容

更快的首屏内容展示速度,单页应用需要等待JS文件加载完成,然后再进行页面渲染,而SSR是将渲染完毕的html传输给客户端

Vue.js SSR的总体原理

如果用一句话概括Vue.js SSR的运作过程,那就是在服务端将Vue.js实例转换成html字符串传输到客户端,然后进行客户端激活,使网页内容能在Vue实例的控制之下

这一句话包含两步内容

Vue.js实例转换成html字符串

客户端激活

先来看第一步

Vue.js应用转换成html字符串

一个最简单的Vue.js单页应用是这样的:

new Vue({
    render: h => h("div", "123")
}).$mount("#app")

这里也包含两步

新建Vue实例

挂在到DOM上面

在服务端当中我们不进行上面第二步操作,取而代之的是将这个实例直接渲染成字符串,做这个工作的就是我们的vue-server-renderer

const renderer = require("vue-server-renderer").createRenderer()
const Vue = require("vue")

renderer.renderToString(new Vue({
  render: h => h("div", 123)
})).then(html => {
  console.log(html)
}).catch(err => {
  console.error(err)
})
// 输出
123

到现在一个最简单的vue ssr应用在服务端的工作已经完成了,下面我们转向下一步客户端激活

客户端激活

客户端激活跟我们单页应用所做的工作相比,最大的不同点就是它并不会构建DOM元素,只会对现有的DOM元素进行激活,使它们能被Vue实例进行控制,而判断激活的关键就是上面的data-server-rendered属性

至此,最简单的一个SSR应用已经构建完成了,下面是对这个应用的功能进行进一步的补充

SSR当中的数据预取

数据预取包含着两个方面,客户端的数据预取和服务端的数据预取

服务端的数据预取

我们渲染一个内容完整页面的时候往往需要向服务器请求数据,所以现在服务端的逻辑变成等待数据获取完毕,然后将页面转换成html字符串

其中数据获取有以下几个问题:

获取哪些数据?

如何得到获取数据的方法?

应在何时预取数据?

预取的数据应保存在哪里?

预取的数据应该怎么样跟客户端进行同步?

问题1:
我们的数据用来渲染页面,那么我们就需要组成当前页面的所有组件各自所需要的数据

问题2:
每个需要进行服务端数据预取的组件定义一个asyncData方法,此方法用于数据预取

问题3:
我们需要先得到当前页面所有需要渲染的组件,然后再进行数据预取

问题4:
由于还需要进行数据同步,所以很难将数据保存在组件的私有data上面,放在vuex上面是个普遍的选择

问题5:
服务端在返回html字符串的时候,store数据将被序列化以后以window.__INITIAL_STATE__=/* store state */的形式插入到脚本当中被客户端获取,客户端的store使用store.replaceState方法同步state

简单复述一下上面的流程就是:
在渲染当前页面的所有组件加载完毕以后,执行这些组件的asyncData方法,这些方法将获取到的数据将由vuex托管,获取数据完毕以后即可将应用渲染成html字符串,vuex store的state将会被序列化以后一并传输到客户端,被客户端进行同步

下面是实现的一些细节:

判断组件加载完毕的方法是vue-router的onReady方法

获取当前页面的所有组件为vue-router的getMatchedComponents方法

由于源码太长所以没贴出来,具体可以到官网浏览

服务端数据预取的关键点算是总结的差不多了,下面简单说一下客户端的数据预取

客户端数据预取

客户端的数据预取方法可分为两种:

等待数据获取完毕后再进行视图切换

先进行视图切换然后在进行数据获取

两种方法区别在于让用户在什么时候产生等待的感觉,第一种是在页面切换时,而第二种是在页面切换完毕等待内容的出现时

第一种方法的实现使用了vue-router实例的beforeResolve方法,这个方法执行在异步组件加载完毕后,导航被确认之前,当完成数据预取以后router才会进行DOM更新等步骤

第二种方法的实现跟我们一般进行数据获取一致,在beforeMount钩子当中执行

SSR在编写代码时候的限制

由于浏览器特定的API将会在服务端报错,如"document"、"window"等,尽量避免使用此类API或者在非服务端运行的声明周期函数中调用如"mounted"等等

指令由于能直接操作DOM会受到很大的限制

SSR的webpack构建原理

以官方的hackernews demo为例,webpack有两个入口entry-cliententry-server分别负责构建客户端和服务端的文件

服务端方面webpack会输出一个名叫vue-ssr-server-bundle的json文件,此文件由官方提供的VueSSRServerPlugin插件所构建而成,是服务端的构建清单,传入createBundleRenderer生成服务端渲染所需要的renderer

客户端方面webpack输出的是由代码分割而成的chunk和公用bundle,与一般单页应用的构建相似,不同的是会生成一个vue-ssr-client-manifest,此文件是客户端方面的构建清单,包含所有chunk的信息,将其传入上面的renderer当中能自动将chunk嵌入到html当中,当然用户也能够取消,自行选择手动嵌入的内容

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105207.html

相关文章

  • vue服务端渲染demo将vue-cli生成的项目转为ssr

    摘要:无需使用服务器实时动态编译,而是使用预渲染方式,在构建时简单地生成针对特定路由的静态文件。与可以部署在任何静态文件服务器上的完全静态单页面应用程序不同,服务器渲染应用程序,需要处于运行环境。更多的服务器端负载。 目录结构 -no-ssr-demo 未做ssr之前的项目代码用于对比 -vuecli2ssr 将vuecli生成的项目转为ssr -prerender-demo 使用prer...

    whinc 评论0 收藏0
  • 使用 PHP 来做 Vue.jsSSR 服务端渲染

    摘要:对于客户端应用来说,服务端渲染是一个热门话题。在服务器预渲染初始应用状态。重构这段脚本,使其可以在服务端运行。如果这些原因和你的情况吻合,那么使用进行服务端渲染将会是个不错方案。我已经发布两个库来支持的服务端渲染和专为应用打造的。 showImg(https://segmentfault.com/img/remote/1460000014155032);对于客户端应用来说,服务端渲染是...

    李增田 评论0 收藏0
  • Vue 服务端渲染实践 ——Web应用首屏耗时最优化方案

    摘要:好在后是支持服务端渲染的,零零散散花费了两三周事件,通过改造现有项目,基本完成了在现有项目中实践了服务端渲染。在服务端生成对应的字符串,客户端接收到对应的字符串,能立即渲染,最高效的首屏耗时。服务端渲染的原理是虚拟。实现前后端同构应用。 随着各大前端框架的诞生和演变,SPA开始流行,单页面应用的优势在于可以不重新加载整个页面的情况下,通过ajax和服务器通信,实现整个Web应用拒不更新...

    terasum 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<