初始化之前可能会有一个汇编过程。最终产品是渲染函数。我们知道,渲染函数返回的值是虚拟DOM(VNODE)。那么,这个虚拟DOM在我们随后的更新过程中扮演什么角色?让我们今天讨论。
1.概念编译原理:编译器是将源代码转换为机器代码的软件;因此,编译的过程是将源代码转换为计算机代码的过程,即可以由CPU执行的二进制代码。例如,高级语言Java编写的程序需要编译为字节代码我们无法理解,但是计算机可以理解。
如果您知道编译器工作流程的工作流程,则应该知道完整编译器的工作流程将是这样:
2. VUE中还编译了VUE中的汇编。我们经常写的HTML模板不是HTML模板。它实际上是一个渲染函数。在此过程中,编译即,即该字符串的模板最终将成为称为渲染函数的JS函数。因此,在过程中,我们需要介绍编译器的概念。当计算机从一种形式转换为另一种形式时,它需要进行编译。compiler:用于将模板字符串编译为JavaScript渲染函数的代码
那么何时汇编呢?
目前,我们需要进一步了解VUE软件包的不同版本。VUE具有一个不携带编译的编译器和一个软件包(对不同版本的解释)。
3.运行时,当使用编译器(编译器)的VUE数据包时,VUE编译的时间发生在安装座时($安装)。
4.运行时不要编译。如果您将VUE软件包与最不磨练的编译器一起使用,则在运行时不会编译VUE。因此,何时发生?当使用编译器未携带的VUE软件包时,您需要预编译,也就是说,基于构建工具,即我们通常使用Vue-CLI来构建的项目,即使用WebPack调用Vue-Loader进行预编译,所有VUE所有Vuethe File is sfc is sfc都将模板模板转换为内部的模板渲染功能。这样做的优点是,Vue的袋子的体积变小,并且执行时的速度更快,因为没有必要编译。
简单地说:模板模板被转换为AST抽象语法树,然后将AST转换为渲染。
那么什么是AST抽象语法树?
1.桅杆抽象的语法树称为模板模板和渲染函数之间的ast抽象语法树。仅在程序运行期间编译,它与我们最终程序的操作无关。根据整个程序的生命周期,这是AST和虚拟DOM之间的本质区别。
2.为什么要在转换为渲染函数的过程中转换AST的过程中AST需要特殊操作。首次,转换为模板的AST是一个非常粗糙的JS对象,非常粗糙的转换,类似于匹配正则表达式,然后在我们的模板模板中有许多表达式。这些特定的深处理分析(转换)后,您将获得最终的AST,然后此最终AST生成生成生成
3.下面的VUE编译器的迷你版本,我们查看VUE编译器的迷你版。特定代码已被省略。我将其放在GitHub上:Mini-Vue-Compilerr
关于上述操作,其中解析功能发生在将模板转换为AST的过程中,该过程专门通过一些匹配模板中字符串的正则表达式。例如
XXX被转换为AST对象,然后通过正则表达式匹配。如果是
然后设置一个启动标记,然后匹配XXX内容,然后设置一个子元素,最后匹配以设置末端标记,等等。解析后,将获得一个粗糙的AST对象。在解析后获得粗糙的AST对象后解析,使用转换进行深度处理,最后通过生成生成代码。
安装时,首先将模板编译为渲染函数。创建实例后,直接调用组件实例的渲染函数以创建该组件的真实DOM,然后继续恢复。
1. vue2.x中vue2.x和vue3.x的汇编比较是这样的:
在VUE3中,整体编译过程仍然是三个阶段,但是与VUE2.X不同,第二阶段被普通编译器的阶段所取代。
2.源代码汇编入口,让我们从我们的源代码的门户开始,packages/vue/index.ts。
此入口文件的代码相对简单。只有一个编译功能函数,但是功能主体中的内容更为关键,主要通过以下步骤:
3.获取的模板
4.编译TemplateCompile以将模板传输到渲染函数,软件包/runtime core/src/component.ts中
实际持久性是基本编译,包装/编译器核/src/compile.ts
分步:字符串模板的分析是一个抽象的语法树AST
步长转换转换:分析属性,样式,说明等。
步骤3生成:将AST转换为渲染功能
这是随着内存改变时间的非常典型的操作
1.静态节点改进
上面的部分模板是这样的,如果它不打开静态节点以改进它:
如果打开静态节点,将在启用后进行编译:
我们可以看到模板中有大量的P标签,因此,当重新构成此组件时,这些静态标签不应再次创建。因此,VUE3放置了这些静态标签,这些标签不会更改在该外部的vnode。渲染功能范围。当下次再次执行渲染函数时,这些静态标签vnodes已经在内存中,无需重新创建。仔细考虑已提出的单词。我们无法读取静态一词,但是该单词得到了增强并表示其(静态节点)要改进。
2.补丁标记和动态属性记录
这意味着在编译过程中,像人眼一样扫描模板以查看动态的内容,然后预先预先保存这些动态事物,进行标记和记录,并等待下一个更新。SaveDynamic Records。例如,上面的模板标题是动态的。提前做出标记并记录。更新后,仅更新标题部分的内容。
我们可以观察到_createvnode函数的第四参数为9,稍后注: / text,props /,这意味着当前节点中有两件事。它是一个属性,然后在哪个属性中,第五参数的数组,记录[“标题”],标题的属性是动态的。
将来执行补丁更新后,您可以根据当前的记录信息更新更新过程和操作,只能通过标题和文本进行更新。
如果DIV标签中有静态文本,则_CReatEvnode函数的第四参数变为8,背面的注释变为: / props /,背面的第五个参数数据保持不变。
_reatevnode函数的第四参数的编号实际上是一个二进制数字,转换为十进制数字。
8的二进制为1000,9二进制是1001。很容易看到二进制的每个数字代表特殊含义。这些数字是patchflag,那么patchflag是什么?
PatchFlag是AST元素时间上的补丁标记。它为实现目标更新和静态改进的效果的时间提供了一个基础。
PatchFlag定义为数字枚举类型。与每个枚举值相对应的标识符的重要性是:
总体贴片分为两类:
以上是VUE3的非常有效的优化策略,称为补丁标记和动态属性记录。
3.缓存事件处理过程
将来,该框架将 @call =“ onclick”转换为@click =“()=> onclick()”,例如React。最后,这可能是一个箭头函数。这意味着每次onclick函数是一个新函数时,这将导致此回调函数显然不会更改,并且会考虑更改。然后必须进行一系列更新。当您起床时,请不要在更新时再次创建它。
在缓存事件处理过程之前,汇编过程
在缓存事件处理过程之后进行编译
4.封锁是什么意思?根据对Yuxi本人的分析,他说,根据他的统计数据,动态部分仅是三分之一,基本上是静态部分,因此在汇编过程中,您能发现较小的动态零件?将其放在上层模块上,然后您可以调用更高的块模块,这意味着,当将来续订此模块时,它将不会一层重新发布。仅更新动态零件每个模块中的每个人都知道补丁过程是最耗时的过程。既然递归的过程已经省略了大部分过程,则性能得到了极大的改善。
我们观察到上述生成的汇编代码。在渲染函数中,首先打开一个_oopenblock(),这意味着首先打开一个块,然后在_CreateBlock中创建一个块,然后将这些动态零件保存在称为dynamicChildren的属性中,仅在将来更新此模块时,只有DynamicChildren中的更新。其他人不再处理,这是非常有效的。
学习了目标更新的学生应该知道,其实现与Vnode树上的DynamicChildren属性是不可分割的。DynamicChildren用于在整个Vnode树中进行所有动态节点,并且标记动态节点的过程在Compilele中。可以说编译转换阶段是互锁的,因此这也是运行时和编译的巧妙组合,VUE3,我们经常说。
显然,在vue2.x中,它没有构建Vnode DynamicChildren属性的条件。
有针对性更新的本质是形成动态和静态节点中动态和静态节点的节点形成,也就是说,然后在当时实现准确而快速的更新。因此,显然形成了它不需要目标更新。
以上是使用编译器对VUE3的优化。它非常有效且非常强大。我认为这比反应更好。VUE3在这篇文章中非常出色,值得赞美。