热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

VueSSR即时编译技术的实现

这篇文章主要介绍了VueSSR即时编译技术的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

当我们在服务端渲染 Vue 应用时,无论服务器执行多少次渲染,大部分 VNode 渲染出的字符串是不变的,它们有一些来自于模板的静态 html,另一些则来自模板动态渲染的节点(虽然在客户端动态节点有可能会变化,但是在服务端它们是不变的)。将这两种类型的节点提取出来,仅在服务端渲染真正动态的节点(serverPrefetch 预取数据相关联的节点),可以显著的提升服务端的渲染性能。

提取模板中静态的 html 只需在编译期对模板结构做解析,而判断动态节点在服务端渲染阶段是否为静态,需在运行时对 VNode 做 Diff,将动态节点转化成静态 html 需要修改渲染函数的源代码,我们将这种在运行时优化服务端渲染函数的技术称作 SSR 即时编译技术(JIT)。

GitHub:vue-ssr-jit

JIT Diff 算法

首要面对的问题是如何 Diff,完成这项工作需要两个 VNode,其中一个通过 serverPrefetch / asyncData 载入动态数据,我们称之为 Dynamic VNode,另一个未载入任何数据,我们称之为 Static VNode。我们做了一个大胆的假设,对任何用户来说,Static VNode 渲染出的 html 是一致的,并且 Static VNode 是 Dynamic VNode 的子集,不同用户的差异点在 Static VNode 相对 Dynamic VNode 的补集当中。

以上假设对绝大部分的 Web 应用都是成立的,某些意料之外的情况将在文末做讨论

Diff 的核心在于从 Staitc VNode 中标记 Dynamic VNode,下一次仅渲染被标记的 Dynamic VNode,Diff 算法的技术示意图如下所示

优化前的 Dynamic VNode 渲染流程图如下

优化后的 Dynamic VNode 渲染流程图如下

如何修改渲染函数的源代码

修改渲染函数的难点在于如何建立 VNode 与源代码的对应关系,否则我们无从得知需要优化的节点是哪段代码生成的,这看起来非常困难。幸运的是 Vue 的模板语法提供了很不错的约束,内置的编译引擎也确保了渲染函数代码结构可预测。

如下模板代码编译生成的渲染函数结构是有章可循的

_c("div", [
 _c("static-view"),
 _c("dynamic-view")
], 1)

执行 _c(xxx) 会生成一个 VNode 节点,解析 _c(xxx) 会生成一个固定结构的 AST,将 AST 与 VNode 做绑定,如果当前 VNode 为静态节点,则修改对应的 AST,VNode 树遍历结束后再将 AST 转化成可执行的代码,代码里便有了我们对 VNode 做的优化。详细的技术实现可参考项目中的 patch.js 和 patch-context.js 文件。

如下流程图演示了修改渲染函数源代码的过程

一个简单的例子如下



官方编译器生成的代码:

_c("div", [
 _c("router-link", {attrs: { to: "/" }}, [
  _vm._v(_vm._s(_vm.name))
 ]),
 _c("router-view")
], 1)

使用 SSR 即时编译生成的代码:

_c("div", [
 _vm._ssrNode(
  "vue-ssr-jit"
 ),
 _c("router-view")
], 1);

用法

npm install --save vue-ssr-jit
const { createBundleRenderer } = require('vue-ssr-jit')

createBundleRenderer 与官方同名函数接口一致,参考 vue ssr 指南

推荐使用 serverPrefetch 预取数据,也支持使用 asyncData 预取数据,参考 demo

哪些场景会导致优化失败

COOKIE

不要在服务端渲染周期内使用 COOKIE,除非你确定此数据与用户无关。可以在 serverPrefetch / asyncData 方法内使用 COOKIE,服务端渲染周期结束后也可以被使用,例如:mountedupdated 等等。

不推荐用法

data() {
 let COOKIE = COOKIE;
 try {
  COOKIE = document.COOKIE;
 } catch(e) {
  COOKIE = global.xxx.COOKIE;
 }
 return {
  COOKIE
 };
},

推荐用法

mounted() {
 this.COOKIE = document.COOKIE;
},

v-for

v-for 指令建议用 dom 元素单独包裹,不建议和其他组件并排使用,由于 for 循环会扰乱抽象语法树与 VNode 节点的对应关系,除非 v-for 指令所在的整个节点层级全为静态,否则将不会对包含 v-for 指令的层级及子级做优化。

不推荐用法

推荐用法

闭包

某些场景下,渲染函数引用了闭包变量,同时这个闭包变量又影响着一个动态的节点,通过 ast 逆向生成的渲染函数暂时无法追踪到之前的闭包引用,执行时会因找不到变量而报错,碰到这种情况,解析引擎将放弃当前组件的 ast 优化,转而使用优化前的渲染函数。

不推荐用法:

推荐用法:

到此这篇关于Vue SSR 即时编译技术的实现的文章就介绍到这了,更多相关Vue SSR 即时编译 内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 本周信息安全小组主要进行了CTF竞赛相关技能的学习,包括HTML和CSS的基础知识、逆向工程的初步探索以及整数溢出漏洞的学习。此外,还掌握了Linux命令行操作及互联网工作原理的基本概念。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • 探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ... [详细]
  • 网络攻防实战:从HTTP到HTTPS的演变
    本文通过一系列日记记录了从发现漏洞到逐步加强安全措施的过程,探讨了如何应对网络攻击并最终实现全面的安全防护。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 360SRC安全应急响应:从漏洞提交到修复的全过程
    本文详细介绍了360SRC平台处理一起关键安全事件的过程,涵盖从漏洞提交、验证、排查到最终修复的各个环节。通过这一案例,展示了360在安全应急响应方面的专业能力和严谨态度。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 本文探讨了在不使用服务器控件的情况下,如何通过多种方法获取并修改页面中的HTML元素值。除了常见的AJAX方式,还介绍了其他可行的技术方案。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
author-avatar
情之秋梦痕
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有