个人网站如何做移动端,免费采购信息平台,线下销售怎么做推广,珠海网站建设小程序Proxy响应式
PatchFlag
编译模板时#xff0c;动态节点做标记标记#xff0c;分为不同的类型#xff0c;如TEXT PROPSdiff算法时#xff0c;可以区分静态节点#xff0c;以及不同类型的动态节点
divHello World/div
span{{ msg }}/span动态节点做标记标记分为不同的类型如TEXT PROPSdiff算法时可以区分静态节点以及不同类型的动态节点
divHello World/div
span{{ msg }}/span
span classmsg闻人放歌/span
span idname{{ msg }}/span
span classmsg-class :msgmessage{{ msg }}/span编译结果
import { createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from vueexport function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createElementBlock(_Fragment, null, [_createElementVNode(div, null, Hello World),_createElementVNode(span, null, _toDisplayString(_ctx.msg), 1 /* TEXT */),_createElementVNode(span, { class: msg }, 闻人放歌),_createElementVNode(span, { id: name }, _toDisplayString(_ctx.msg), 1 /* TEXT */),_createElementVNode(span, {class: msg-class,msg: _ctx.message}, _toDisplayString(_ctx.msg), 9 /* TEXT, PROPS */, [msg])], 64 /* STABLE_FRAGMENT */))
}// Check the console for the AST静态字段将不再比较这样diff算法将少比较很多节点。
hoistStatic
将静态节点的定义提升到父作用域缓存起来多个相邻的静态节点会被合并起来典型的拿空间换时间的优化策略
// 模板
divHello World/div
divHello World/div
divHello World/div编译结果
import { createElementVNode as _createElementVNode, createCommentVNode as _createCommentVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from vueconst _hoisted_1 /*#__PURE__*/_createElementVNode(div, null, Hello World, -1 /* HOISTED */)
const _hoisted_2 /*#__PURE__*/_createElementVNode(div, null, Hello World, -1 /* HOISTED */)
const _hoisted_3 /*#__PURE__*/_createElementVNode(div, null, Hello World, -1 /* HOISTED */)export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createElementBlock(_Fragment, null, [_hoisted_1,_hoisted_2,_hoisted_3,_createCommentVNode( span{{ msg }}/span\nspan class\msg\闻人放歌/span\nspan id\name\{{ msg }}/span\nspan class\msg-class\ :msg\message\{{ msg }}/span )], 64 /* STABLE_FRAGMENT */))
}// Check the console for the AST还有一个点如果静态节点数量多编译会自动合并如
divHello World/div
divHello World/div
divHello World/div
divHello World/div
divHello World/div
divHello World/div
divHello World/div
divHello World/div
divHello World/div
divHello World/divimport { createElementVNode as _createElementVNode, createCommentVNode as _createCommentVNode, createStaticVNode as _createStaticVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from vueconst _hoisted_1 /*#__PURE__*/_createStaticVNode(divHello World/divdivHello World/divdivHello World/divdivHello World/divdivHello World/divdivHello World/divdivHello World/divdivHello World/divdivHello World/divdivHello World/div, 10)export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createElementBlock(_Fragment, null, [_hoisted_1,_createCommentVNode( span{{ msg }}/span\nspan class\msg\闻人放歌/span\nspan id\name\{{ msg }}/span\nspan class\msg-class\ :msg\message\{{ msg }}/span )], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */))
}// Check the console for the ASTcacheHandler
上代码
div clickclickHandlerHello World/div编译结果
import { openBlock as _openBlock, createElementBlock as _createElementBlock } from vueexport function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createElementBlock(div, {onClick: _cache[0] || (_cache[0] (...args) (_ctx.clickHandler _ctx.clickHandler(...args)))}, Hello World))
}// Check the console for the AST从编译结果代码可以看出如果该事件方法已被定义则直接去缓存中的方法没有则定义。其意义就是缓存事件
SSR优化
编译前
divHello World/div
divHello World/div
divHello World/div
divHello World/div
divHello World/div
divHello World/div
div{{ msg }}/div
div clickclickHandlerHello World/div
div classmsg-class{{ msg }}/div
div classmsg-class :msgmsg闻人放歌/div编译结果
import { mergeProps as _mergeProps } from vue
import { ssrRenderAttrs as _ssrRenderAttrs, ssrInterpolate as _ssrInterpolate } from vue/server-rendererexport function ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) {const _cssVars { style: { color: _ctx.color }}_push(!--[--div${_ssrRenderAttrs(_cssVars)}Hello World/divdiv${_ssrRenderAttrs(_cssVars)}Hello World/divdiv${_ssrRenderAttrs(_cssVars)}Hello World/divdiv${_ssrRenderAttrs(_cssVars)}Hello World/divdiv${_ssrRenderAttrs(_cssVars)}Hello World/divdiv${_ssrRenderAttrs(_cssVars)}Hello World/divdiv${_ssrRenderAttrs(_cssVars)}${_ssrInterpolate(_ctx.msg)}/divdiv${_ssrRenderAttrs(_cssVars)}Hello World/divdiv${_ssrRenderAttrs(_mergeProps({ class: msg-class }, _cssVars))}${_ssrInterpolate(_ctx.msg)}/divdiv${_ssrRenderAttrs(_mergeProps({class: msg-class,msg: _ctx.msg}, _cssVars))}闻人放歌/div!--]--)
}// Check the console for the AST静态节点直接输出绕过了vdom动态节点还是需要动态渲染
tree-shaking
观察两者编译结果区别
div v-ifmsgHello World/div
input v-modelmsg
// 编译结果
import { openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode, vModelText as _vModelText, createElementVNode as _createElementVNode, withDirectives as _withDirectives, Fragment as _Fragment } from vueexport function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createElementBlock(_Fragment, null, [(_ctx.msg)? (_openBlock(), _createElementBlock(div, { key: 0 }, Hello World)): _createCommentVNode(v-if, true),_withDirectives(_createElementVNode(input, {onUpdate:modelValue: $event ((_ctx.msg) $event)}, null, 8 /* PROPS */, [onUpdate:modelValue]), [[_vModelText, _ctx.msg]])], 64 /* STABLE_FRAGMENT */))
}// Check the console for the ASTdiv v-ifmsgHello World/div// 编译结果
import { openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode } from vueexport function render(_ctx, _cache, $props, $setup, $data, $options) {return (_ctx.msg)? (_openBlock(), _createElementBlock(div, { key: 0 }, Hello World)): _createCommentVNode(v-if, true)
}// Check the console for the AST编译时根据不同的情况引入不同的API