模板语法允许在HTML中之插入Js变量以及表达式,当在Js中控制render的时候能够自动在页面上将变量或者是表达式进行计算并显示,比较常见的模板语法有mustcache风格的{{}}以及DSL风格的dsl-html等。
AST抽象语法树,全称为Abstract Syntax Tree是源代码的抽象语法结构的树状表现形式,每种源码都可以被抽象成为AST,在这里把模板解析成为AST,就是将模板的HTML结构进行解析,变成一棵附带结构、关系、属性的抽象树。这样做方便后续对模板进行处理,减少了多次解析字符串带来的性能消耗,同时将HTML变成一棵树的数据结构之后更加方便于遍历,下面是对于例子中的HTML的简单的AST。
对mustcache风格的{{}}进行简单的实现,仅对于其数据的展示方面有实现,对于其指令例如循环等并未实现。通过处理字符串,将其转换为一个函数并传参执行,即可实现数据的展示。
通过对于字符串的处理并使用Function实现模板语法,如果使用正则表达式进行较为完整的过滤,是完全可以生成较为完善的模板语法的处理的,包括Js的表达式以及自带指令等,如mustcache.js、layui.js的laytpl模块。基于AST的模板语法需要解析HTML成为AST,然后将AST转化为字符串,将字符串作为函数执行,这个过程依旧需要用到Function,下边的例子只是借助了Js取得DOM结构生成的AST,没有自行解析HTML。
虽然看起来最后都需要使用Function去处理字符串,而AST还需要解析HTML然后再拼接字符串,增加了计算的时间。但是如果仅仅是完全基于处理字符串的方式实现的模板语法,在数据进行变更时都需要进行render,每次render的时候都需要重新渲染整个DOM。
虽然在上边的简单实现中AST也是重新渲染了整个模板,但是现在主流的Js框架例如Vue就是基于AST的方式,首先解析template为AST,然后对于AST进行静态节点标记,用以标记静态的节点进行重用跳过比对,从而进行渲染优化,然后生成虚拟DOM。当数据进行变更时虚拟DOM会进行diff算法的比对,找到数据有变更的节点,然后进行最小化渲染,这样就不需要在数据变更时将整个模板进行渲染,从而增加了渲染的效率。