宝哥软件园

高性能JavaScript模板引擎实现原理详解

编辑:宝哥软件园 来源:互联网 时间:2021-10-13

随着web的发展,前端应用变得越来越复杂,基于后端的javascript(Node.js)也开始出现。这个时候,对javascript的期待就更多了,同时,javascript MVC的思想也越来越流行。javascript模板引擎作为数据与界面分离的最重要部分,越来越受到开发者的重视。近年来在开源社区开花结果,在推特、淘宝、新浪微博、腾讯QQ空间、腾讯微博等大型网站都能看到。

本文将用最简单的示例代码来描述现有javascript模板引擎的原理,包括新一代javascript模板引擎artTemplate的特性实现原理。欢迎大家一起讨论。

艺术模板简介

ArtTemplate是新一代的javascript模板引擎,采用预编译的方法在性能上做出质的飞跃,充分利用了javascript引擎的特性,使其在前端和后端的性能都极其突出。chrome下的渲染效率分别是著名引擎小胡子和micro tmpl的25倍和32倍。

除了性能优势,调试功能也值得一提。模板调试器可以准确定位导致渲染错误的模板语句,解决了编译模板过程中调试的痛苦,使得开发更加高效,避免了单个模板中的错误导致整个应用崩溃。

ArtTemplate,都是用1.7kb(gzip)实现的!

javascript模板引擎的基本原理。

虽然每个引擎从模板语法、语法解析、变量赋值和字符串拼接都有不同的实现,但关键的渲染原则仍然是动态执行javascript字符串。

关于javascript字符串的动态执行,本文以一个模板代码为例:

这是一个非常简单的模板编写,其中“”是一个闭包标记(逻辑语句闭包标记),如果openTag后面跟“=”,就会输出变量的内容。

HTML语句和变量输出语句直接输出,解析后的字符串类似:

解析后,通常会返回呈现方法:

渲染测试:

在上面的渲染方法中,with语句用于模板变量的赋值,数组的push方法用于字符串拼接,以提高IE6和IE7下的性能。jQuery的作者john开发的微模板引擎tmpl就是这种方法的典型代表。看http://ejohn.org/blog/javascript-micro-templating/.

从原理实现可以看出,传统的javascript模板引擎有两个问题需要解决:

1.性能:模板引擎在渲染时依赖于Function构造函数。与eval、setTimeout和setInterval一样,Function提供了一种使用文本访问javascript解析引擎的方法,但javascript执行的性能很低。

2.调试:由于它是一个动态执行字符串,如果遇到错误,调试器就无法捕获错误源,导致模板bug的调试极其痛苦。在没有容错的引擎中,如果局部模板甚至可能因为数据异常导致整个应用崩溃,那么维护成本会随着模板数量的增加而急剧增加。

艺术模板效率的秘密。

1.预编译。

在上述模板引擎的实现原理中,由于模板变量是赋值的,所以每次渲染都需要动态编译javascript字符串来完成变量赋值。但是artTemplate的编译赋值过程是在渲染之前完成的,这叫做“预编译”。artTemplate模板编译器将根据一些简单的规则提取所有模板变量,并在渲染函数的头部声明它们,类似于:

这个自动生成的函数就像一个手写的javascript函数。在相同的执行次数下,CPU和内存的使用明显减少,性能几乎有限。

值得一提的是,artTemplate的很多特性都是基于预编译实现的,比如沙盒规范和自定义语法。

2.更快的字符串添加方式。

很多人误以为数组推送法比=能更快的拼接字符串,这只是在IE6-8的浏览器下。说明现代浏览器使用=比数组推送方法快,而在v8引擎中,使用=比数组拼接快4.7倍。因此,根据javascript引擎的特点,artTemplate采用了两种不同的字符串拼接方式。

ArtTemplate调试模式原理。

与后端模板引擎不同,前端模板引擎是动态解析的,因此调试器无法定位错误的行号,而artTemplate使模板调试器能够以巧妙的方式准确定位导致呈现错误的模板语句,例如:

艺术模板支持两种类型的错误捕获,一种是渲染错误和编译错误。

1.呈现错误。

渲染错误通常由模板数据错误或变量错误引起。渲染时只遇到错误,在调试模式下会重新编译模板,不会影响正常的模板执行效率。模板编译器根据模板换行符记录行号,编译后的函数类似:

当执行过程中遇到错误时,立即抛出异常模板对应的行号,然后模板调试器根据行号反向检查模板对应的语句并打印到控制台。

2.编译错误。

编译错误一般是模板语法错误,比如嵌套不规范,语法未知。由于artTemplate没有进行完整的词法分析,无法确定错误源的位置,所以只能输出原始的错误信息和源代码供开发者判断。

更多资讯
游戏推荐
更多+