随着web发展,前端应用变得越来越复杂,基于后端的JavaScript(Node.js)也开始崭露头角,此时JavaScript被寄予了更大的期望,与此同时JavaScript MVC思想也开始流行起来。JavaScript模板引擎作为数据与界面分离工作中最重要一环,越来越受开发者关注,近一年来在开源社区中更是百花齐放,在Twitter、淘宝网、新浪微博、腾讯QQ空间、腾讯微博等大型网站中均能看到它们的身影。
本文将用最简单的示例代码描述现有的JavaScript模板引擎的原理,包括新一代JavaScript模板引擎artTemplate的特性实现原理,欢迎共同探讨。
artTemplate介绍
artTemplate是新一代JavaScript模板引擎,它采用预编译方式让性能有了质的飞跃,并且充分利用JavaScript引擎特性,使得其性能无论在前端还是后端都有极其出色的表现。在Chrome下渲染效率测试中分别是知名引擎Mustache与micro tmpl的25、32倍。
除了性能优势外,调试功能也值得一提。模板调试器可以精确定位到引发渲染错误的模板语句,解决了编写模板过程中无法调试的痛苦,让开发变得高效,也避免了因为单个模板出错导致整个应用崩溃的情况发生。
artTemplate这一切都在1.7kb(gzip)中实现!
JavaScript模板引擎基本原理
虽然每个引擎从模板语法、语法解析、变量赋值、字符串拼接的实现方式各有所不同,但关键的渲染原理仍然是动态执行JavaScript字符串。
关于动态执行JavaScript字符串,本文以一段模板代码举例:
这是一段非常朴素的模板写法,其中,""为closeTag(逻辑语句闭合标签),若openTag后面紧跟“=”则会输出变量的内容。
HTML语句与变量输出语句被直接输出,解析后的字符串类似:
语法分析完毕一般还会返回渲染方法:
渲染测试:
在上面render方法中,模板变量赋值采用了with语句,字符串拼接采用数组的push方法以提升在IE6、7下的性能,jQuery作者john开发的微型模板引擎tmpl是这种方式的典型代表,参见:http://ejohn.org/blog/javascript-micro-templating/由原理实现可见,传统JavaScript模板引擎中留下两个待解决的问题:
1、性能:模板引擎渲染的时候依赖Function构造器实现,Function与eval、setTimeout、setInterval一样,提供了使用文本访问JavaScript解析引擎的方法,但这样执行JavaScript的性能非常低下。
2、调试:由于是动态执行字符串,若遇到错误调试器无法捕获错误源,导致模板BUG调试变得异常痛苦。在没有进行容错的引擎中,局部模板若因为数据异常甚至可以导致整个应用崩溃,随着模板的数目增加,维护成本将剧增。
artTemplate高效的秘密
1、预编译
在上述模板引擎实现原理中,因为要对模板变量进行赋值,所以每次渲染都需要动态编译JavaScript字符串完成变量赋值。而artTemplate的编译赋值过程却是在渲染之前完成的,这种方式称之为“预编译”。artTemplate模板编译器会根据一些简单的规则提取好所有模板变量,声明在渲染函数头部,这个函数类似:
这个自动生成的函数就如同一个手工编写的JavaScript函数一样,同等的执行次数下无论CPU还是内存占用都有显著减少,性能近乎极限。
值得一提的是:artTemplate很多特性都基于预编译实现,如沙箱规范与自定义语法等。
2、更快的字符串相加方式
很多人误以为数组push方法拼接字符串会比+=快,要知道这仅仅是IE6-8的浏览器下。实测表明现代浏览器使用+=会比数组push方法快,而在v8引擎中,使用+=方式比数组拼接快4.7倍。所以rtTemplate根据JavaScript引擎特性采用了两种不同的字符串拼接方式。
artTemplate调试模式原理
前端模板引擎不像后端模板引擎,它是动态解析,所以调试器无法定位到错误行号,而artTemplate通过巧妙的方式让模板调试器可以精确定位到引发渲染错误的模板语句,例如:
artTemplate支持两种类型的错误捕获,一是渲染错误(Render Error)与编译错误(Syntax Error)。
1、渲染错误
渲染错误一般是因为模板数据错误或者变量错误产生的,渲染的时候只有遇到错误才会进入调试模式重新编译模板,而不会影响正常的模板执行效率。模板编译器根据模板换行符记录行号,编译后的函数类似:
当执行过程遇到错误,立马抛出异常模板对应的行号,模板调试器再根据行号反查模板对应的语句并打印到控制台。
2、编译错误
编译错误一般是模板语法错误,如不合格的套嵌、未知语法等。由于artTemplate没有进行完整的词法分析,故无法确定错误源所在的位置,只能对错误信息与源码进行原文输出,供开发者判断。
开源节流
artTemplate基于开源协议发布,无论是商业公司还是个人都可以免费在项目中使用,欢迎共同完善。