天天看点

VUE2--从零实现服务端渲染(SSR)

VUE2--从零实现服务端渲染(SSR)

Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。在服务端渲染模板字符串的这一过程即为SSR。

概要

何时使用服务器端渲染 (SSR) (来自vue官方文档)

与传统 SPA (单页应用程序 (Single-Page Application)) 相比,服务器端渲染 (SSR) 的优势主要在于:

更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。

请注意,截至目前,Google 和 Bing 可以很好对同步 JavaScript 应用程序进行索引。在这里,同步是关键。如果你的应用程序初始展示 loading 菊花图,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再行抓取页面内容。也就是说,如果 SEO 对你的站点至关重要,而你的页面又是异步获取内容,则你可能需要服务器端渲染(SSR)解决此问题。

更快的内容到达时间 (time-to-content),特别是对于缓慢的网络情况或运行缓慢的设备。无需等待所有的 JavaScript 都完成下载并执行,才显示服务器渲染的标记,所以你的用户将会更快速地看到完整渲染的页面。通常可以产生更好的用户体验,并且对于那些「内容到达时间(time-to-content) 与转化率直接相关」的应用程序而言,服务器端渲染 (SSR) 至关重要。

使用服务器端渲染 (SSR) 时还需要有一些权衡之处:

开发条件所限。浏览器特定的代码,只能在某些生命周期钩子函数 (lifecycle hook) 中使用;一些外部扩展库 (external library) 可能需要特殊处理,才能在服务器渲染应用程序中运行。

涉及构建设置和部署的更多要求。与可以部署在任何静态文件服务器上的完全静态单页面应用程序 (SPA) 不同,服务器渲染应用程序,需要处于 Node.js server 运行环境。

更多的服务器端负载。在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用 CPU 资源 (CPU-intensive - CPU 密集),因此如果你预料在高流量环境 (high traffic) 下使用,请准备相应的服务器负载,并明智地采用缓存策略。

在对你的应用程序使用服务器端渲染 (SSR) 之前,你应该问的第一个问题是,是否真的需要它。这主要取决于内容到达时间 (time-to-content) 对应用程序的重要程度。例如,如果你正在构建一个内部仪表盘,初始加载时的额外几百毫秒并不重要,这种情况下去使用服务器端渲染 (SSR) 将是一个小题大作之举。然而,内容到达时间 (time-to-content) 要求是绝对关键的指标,在这种情况下,服务器端渲染 (SSR) 可以帮助你实现最佳的初始加载性能。

SSR的原理

通过如下的原理图我们可以分析出SSR的基本原理:

VUE2--从零实现服务端渲染(SSR)

左侧Source部分就是我们编写的源代码,所有代码有一个公共入口,即app.js,与app.js右侧相邻的就是服务端的入口

(entry-server.js)和客户端的入口(entry-client.js)。当完成所有源代码的编写之后,我们通过webpack打包出两个bundle,分别是server bundle和client bundle,当用户进行页面访问的时候,先是经过服务端的入口,将vue组件组装为html字符串,并混入客户端所访问的html模板中,最终就完成了整个SSR渲染的过程。

创建SSR demo

创建一个项目目录为vue-ssr-demo, 进入目录,输入如下命令:

安装完成后,可以看到我们的package.json文件如下:

在根目录下(vue-ssr-demo)新建一个server.js文件,用户创建node服务

在package.json文件中添加启动node服务的命令

在vscode终端输入 npm run server 可以看到服务已启动的提示语,在浏览器地址栏输入localhost:5000,可以看到页面显示​<code>​Hell SSR​</code>​。

上面我们成功渲染出一段文字,下面我们去渲染一个html模板。

修改server.js文件如下:

保存代码,重启服务npm run server,然后重新刷新页面, 可以看到渲染的文字为​<code>​这是模板消息:Hello SSR​</code>​。

浏览器按F12查看页面源代码,我们发现在源代码中,已经存在一个标签h1,同时,h1标签上面有一个属性:data-server-rendered="true",这其实是一个标记,表明这个页面是由vue-ssr渲染而来的。

虽然h1标签对被成功渲染,但是我们发现这个html页面并不完整, 缺少文档声明,html标签,body标签,title标签等。

当你在渲染 Vue 应用程序时,renderer 只从应用程序生成 HTML 标记 (markup)。我们必须用一个额外的 HTML 页面包裹容器,来包裹生成的 HTML 标记。

为了简化这些,你可以直接在创建 renderer 时提供一个页面模板。多数时候,我们会将页面模板放在特有的文件中,例如 index.template.html:

注意 ​<code>​&lt;!--vue-ssr-outlet--&gt; ​</code>​注释 -- 这里将是应用程序 HTML 标记注入的地方。

然后,我们可以读取和传输文件到 Vue renderer 中,修改server.js

重新启动node服务,刷新页面,按下F12,这时我们可以看到完整的html结构

VUE2--从零实现服务端渲染(SSR)