这篇文章主要介绍“vue原理Compile之optimize标记静态节点源码分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue原理Compile之optimize标记静态节点源码分析”文章能帮助大家解决问题。optimize这一步的内容好像不太多,但是非常重要,于是是一个更新性能优化, 非常重要先来看看 optimize 在什么位置,就在 parse 处理完之后,generate 之前Vue官方注释优化器的目标遍历生成的模板AST树,检测纯静态的子树,即永远不需要更改的DOM。一旦我们检测到这些子树,我们可以:1、把它们变成常数,这样我们就不需要了在每次重新渲染时为它们创建新的节点2、在修补过程中完全跳过它们。那是怎么做的呢?给静态ast节点设置属性 static,当节点时静态是下面就来看下源码里面主要调用了两个函数,这两个函数会分别分析但是在此之前,我们先来看一个函数,这个函数就是 判断静态节点的 主力函数直接传入 ast 节点,各种组合判断,然后给 ast 节点添加上 static 属性如果要判断为静态节点,就要经过下面7个条件的审判(把上面的代码列了出来)如果添加了指令 v-pre,那么 node.pre 为 true,表明所有节点都不用解析了当节点有绑定 Vue属性的时候,比如指令,事件等,node.hasBindings 会为 true同样,当 节点有 v-if 或者 v-for 的时候,node.if 或者 node.for 为true因为这两者是要动态编译的,不属于静态范畴所以只要是 slot 或者 component 都不可能是静态节点isPlatformReservedTag 是用于判断该标签是否是正常的HTML 标签,有什么标签呢?标签必须是正常HTML标签,如下html,body,base,head,link,meta,style,titleaddress,article,aside,footer,header,h2,h3,h4,h5,h6,h7,hgroup,nav,sectiondiv,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ula,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,rubys,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,videoembed,object,param,source,canvas,script,noscript,del,inscaption,col,colgroup,table,thead,tbody,td,th,trbutton,datalist,section,form,input,label,legend,meter,optgroup,optionoutput,progress,select,textareadetails,dialog,menu,menuitem,summarycontent,elem免费云主机域名ent,shadow,template,blockquote,iframe,tfootsvg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-faceforeignObject,g,glyph,image,line,marker,mask,missing-glyph,path,patternpolygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view是不是挺多的,哈哈,尤大真厉害,估计收集了很多,我觉得应该有用,就全放上来了看下这个函数的源码表明了节点父辈以上所有节点不能是 template 或者 带有 v-forisStaticKey是一个函数,用于判断传入的属性是否在下面的范围内type,tag,attrsList,attrsMap,plain,parent,children,attrs比如这样的 ast上面的 ast 的所有属性通过 isStaticKey 判断之后,都在上面列出的属性范围中,都是静态属性,所以这就是一个静态节点而当你存在之外的其他属性的时候,这个节点就不是静态ast然后下面就来看 optimize 中出现的两个函数把markStatic$1 和 markStaticRoot怎么标记一个节点是否是静态节点呢,就在 markStatic$1 中进行处理这个方法做了下面三种事情进行初步静态节点判断给节点本身判断完是否静态节点之后,需要做额外的处理,就是需要检查所有的子孙节点于是便会逐层递归子节点,如果某子节点不是静态节点,那么父节点就不能是静态节点,但是并不是所有节点都会进行特殊处理,是有条件的类型 1 是 标签元素类型 2 是 文字表达式类型 3 是 纯文本1、必须是正常标签,也就是说自定义标签不需要再次处理2、slot 会额外处理3、有 inline-template 属性也会额外处理只有有一个满足,就会进行额外处理你可以看到源码中的最后一步判断 node.ifCondition,并且如果 ifCondition 中保存的节点不是静态的话,那么这个 node 也不是静态节点这个判断就很让我匪夷所思了明明如果存在 v-if 的话,该节点在 一开始的 isStatic 中,就会被设置 node.static 为 false 了为什么还要在末尾 再判断一遍呢?这里我觉得好像有点多余?反正我没有想通 尤大 的想法啊啊啊啊啊,为了确保正确?经过这一步,所有的节点,都会被添加上 static 属性,节点是否静态,一看便知这个方法只会不断的寻找 静态的根节点,应该说是区域根节点吧,反正一个节点下面有马仔节点,这个节点就算是根节点递归他的所有子孙,看看谁是静态根节点,如果是静态ast,就会被添加上 staticRoot 这个属性markStaticRoots 也是递归调用的,但是并不是会处理到所有节点因为找到一个根节点是静态根节点后,就不会递归处理他的子节点了然后我们需要了解两个问题1、markStaticRoot 和 markStatic$1 的区别2、判断静态根节点的依据是什么找出静态根节点才是性能优化的最终作用者markStatic$1 这个函数只是为 markStaticRoots 服务的,是为了先把每个节点都处理之后,更加方便快捷静态根节点,可以说是把功能分开,这样处理的逻辑就更清晰了先给所有的节点都划分身份,之后处理静态节点时,只用找 那部分的根节点(区域负责人就好了)当然,上面都是我个人的理解,那么我的依据是什么呢?markStatic$1 添加的 static 属性,我全局搜索,并没有在处理DOM和 生成 render上使用过而 markStaticRoots 添加的 staticRoot ,在生成 render 上使用了而且再 根据 markStaticRoots 写的功能逻辑 并 使用了 static 属性进行判断所以我认为 markStatic$1 是为 markStaticRoots 服务的一个函数1该节点的所有子孙节点都是静态节点而 node.static = true 则表明了其所有子孙都是静态的,否则上一步就被设置为 false 了2必须存在子节点3子节点不能只有一个 纯文本节点这一点我不太明白,为什么只有一个纯文本子节点时,这个点不能是静态根节点?注意:只有纯文本子节点时,他是静态节点,但是不是静态根节点。静态根节点是optimize 优化的条件,没有静态根节点,说明这部分不会被优化而 Vue 官方说明是,如果子节点只有一个纯文本节点,如果优化的话,带来的成本就比好处多了,所以就不优化那么我就疑惑了下面是我的个人探索的想法首先,我们明确,优化的好处是,减少DOM比对,加速更新而带来的成本是什么呢?1、维护静态模板存储对象2、多层函数调用现在我们来简单解释下上面两种成本一开始的时候,所有的静态根节点 都会被解析生成 VNode,并且被存在一个缓存对象中,就在 Vue.proto._staticTree 中比如下面这个静态模板解析后被存了进去随着静态根节点的增加,这个存储对象也会越来越大,那么占用的内存就会越来越多势必要减少一些不必要的存储,所有只有纯文本的静态根节点就被排除了这个问题涉及到 render 和 静态 render 的合作举个例子一个动态跟静态混合的模板生成的 render 函数是这样的看到 _m(0) 了吗,这个函数就是去获取静态模板的这样,静态模板的处理就多了一个 _m 函数的调用,加上初期涉及到了很多函数的处理,其中包括上一步的存储再者,既然纯文本节点不做优化那么就是说更新时需要比对这部分喽?但是纯文本的比对,就是直接 比较字符串 是否相等而已啊消耗简直不要太小,那么这样,我还有必要去维护多一个静态模板缓存吗?综上所述只有纯文本子节点最好不要当做静态模板处理以上只是个人的意淫想法,如有不同意见可以提出番外疑惑我不禁疑惑到,难道只有一个普通标签子节点的时候,好处难道会大一些吗?可以看到模板放在了 staticRenderFns 上,做了静态模板处理结果论出发的话,可能消耗的确大一些吧哈哈哈更新的时候,会比较 div 和 span 和 span 内的纯文本关于“vue原理Compile之optimize标记静态节点源码分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注百云主机行业资讯频道,小编每天都会为大家更新不同的知识点。
相关推荐: tsconfig的useDefineForClassFields属性怎么使用
这篇“tsconfig的useDefineForClassFields属性怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“tsconfig…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。