Open xinglie opened 4 years ago
当模板是这样时
<div class="a b" name="div">
{{=name}}
</div>
编译出的js代码如下
let $quick___0_static_attr={'class': 'a b','name': 'div',};
Magix.View.extend({
tmpl: ($$, $_create,$_viewId,$n)=> {
let $_temp,$vnode_0=[],
{
name,}=$$,
$vnode_1,
$text;
$vnode_1=[$_create(0,0,$n(name))];$vnode_0.push($_create('div',$quick___0_static_attr,$vnode_1));
return $_create($_viewId,0,$vnode_0); } ,
我们可以看到html中的属性被编译成对象并以变量提取到最外边,生成重复使用的变量
同时当有相同的静态html属性时,生成的这个对象也只有一份,不会生成值重复的变量
<div a="b">
<div>
<div>bb</div>
</div>
</div>
{{=f}}
<div a="b1">
<div>
<div>bb</div>
</div>
</div>
编译出的js代码如下
if ($quick___0_static_node) {
$vnode_0.push($quick___0_static_node);
}
else {
$vnode_3 = [$_create(0, 0, 'bb')];
$vnode_2 = [$_create('div', 0, $vnode_3)];
$vnode_1 = [$_create('div', 0, $vnode_2)];
$vnode_0.push($quick___0_static_node = $_create('div', { '_': '_', 'a': 'b', }, $vnode_1));
}
$vnode_0.push($_create(0, 0, ($__line = 6, $__art = '{{=f}}', $__ctrl = '<%=f%>', $n(f))));
if ($quick___1_static_node) {
$vnode_0.push($quick___1_static_node);
}
else {
$vnode_3 = [$_create(0, 0, 'bb')];
$vnode_2 = [$_create('div', 0, $vnode_3)];
$vnode_1 = [$_create('div', 0, $vnode_2)];
$vnode_0.push($quick___1_static_node = $_create('div', { '_': 'a', 'a': 'b1', }, $vnode_1));
}
我们会发现不同静态节点下的
<div>
<div>bb</div>
</div>
是一样的,但是编译出的js代码中,却要反复创建相同的节点。
针对这样的情况,我们可以对这样的节点进行变量重复利用,达到提升性能的目的 上述情况优化后生成的js代码如下
if ($quick___0_static_node) {
$vnode_0.push($quick___0_static_node);
}
else {
if ($inline$___) {
$vnode_1 = [$inline$___];
}
else {
if ($inline$__a) {
$vnode_2 = [$inline$__a];
}
else {
$vnode_3 = [$_create(0, 0, 'bb')];
$vnode_2 = [$inline$__a = $_create('div', 0, $vnode_3)];
}
$vnode_1 = [$inline$___ = $_create('div', 0, $vnode_2)];
}
$vnode_0.push($quick___0_static_node = $_create('div', { '_': '_', 'a': 'b', }, $vnode_1));
}
$vnode_0.push($_create(0, 0, ($__line = 6, $__art = '{{=f}}', $__ctrl = '<%=f%>', $n(f))));
if ($quick___1_static_node) {
$vnode_0.push($quick___1_static_node);
}
else {
if ($inline$___) {
$vnode_1 = [$inline$___];
}
else {
if ($inline$__a) {
$vnode_2 = [$inline$__a];
}
else {
$vnode_3 = [$_create(0, 0, 'bb')];
$vnode_2 = [$inline$__a = $_create('div', 0, $vnode_3)];
}
$vnode_1 = [$inline$___ = $_create('div', 0, $vnode_2)];
}
$vnode_0.push($quick___1_static_node = $_create('div', { '_': 'a', 'a': 'b1', }, $vnode_1));
}
背景
小程序、快应用和我负责研发的Magix,在开发阶段,HTML,CSS和Javascript是分离的文件,通过编译的功能把html和css编译到js文件中,最终和react一样,仅输出js文件
今天就聊聊模板,也就是html被编译到js中时,一些优化方法
模板编译优化
在Magix中,js使用如下的语法占位符表示最终html出现在哪个位置
当我们的index.html是静态内容时
编译出的js文件内容如下
在这份编译结果中,有2个优化点
静态化不变的节点
通过原始模板,我们可以知道这个html在接下来的并不会变化,我们会通过类似$quick___0_static_node在js代码中,反复使用同一个对象来进行运行时的速度提升
给静态节点打上标记
我们可以看到静态div节点被打上
{'_': '_',}
,这样的标记,这样的标记告诉运行时的diff模块,这个节点下的内容不会变化,会加快运行时的diff当模板是这样时
编译出的js结果如下
编译器会自动识别重复的同样的html片断,最终它们将会使用同一个变量,同一个静态标记,来减少运行时的内容和加速diff