首页 > 技术沙龙 > 高性能JavaScript模板引擎原理解析

高性能JavaScript模板引擎原理解析

糖饼 / 技术沙龙 / 2012.06.15 / 相关标签

9

随着 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 倍。所以 artTemplate 根据 javascript 引擎特性采用了两种不同的字符串拼接方式。

artTemplate 调试模式原理

前端模板引擎不像后端模板引擎,它是动态解析,所以调试器无法定位到错误行号,而 artTemplate 通过巧妙的方式让模板调试器可以精确定位到引发渲染错误的模板语句,例如:

debug

artTemplate 支持两种类型的错误捕获,一是渲染错误(Render Error)与编译错误(Syntax Error)。

1、渲染错误

渲染错误一般是因为模板数据错误或者变量错误产生的,渲染的时候只有遇到错误才会进入调试模式重新编译模板,而不会影响正常的模板执行效率。模板编译器根据模板换行符记录行号,编译后的函数类似:

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

2、编译错误

编译错误一般是模板语法错误,如不合格的套嵌、未知语法等。由于 artTemplate 没有进行完整的词法分析,故无法确定错误源所在的位置,只能对错误信息与源码进行原文输出,供开发者判断。

开源节流

artTemplate 基于开源协议发布,无论是商业公司还是个人都可以免费在项目中使用,欢迎共同完善。

下载地址:

https://github.com/aui/artTemplate

在线预览:

http://aui.github.com/artTemplate/

反馈:

腾讯微博 | 新浪微博

欢迎大家参与微博讨论和作者互动:腾讯微博 & 新浪微博

文章评论 共有9条评论

  • 01李白 2015/05/08

    arttemplate如何绑定事件啊?我用jquery绑定事件,渲染后的dom都绑不上事件呢??

    赞成[2]反对[4]回复

  • 02熊猫 2015/06/09

    你好,能给个解析器的案例吗?我网上找了很久也没找到。我仅仅想实现是一个存值得插件,类似于JSP中的set标签。

    赞成[1]反对[4]回复

  • 03res 2015/06/26

    这些个JavaScript模板怎么看都像JSP,差别只在于程序脚本是用JavaScript实现,还是Java实现的。 HMTL文件自身就是最好的模板,反正看着都很难受。顺便说句,性能优先,但不是全部。

    赞成[3]反对[3]回复

  • 04逼格牛 2015/07/30

    用了,简洁语法太简洁了,var关键字都被过滤了,搞得不能在模板中声明变量

    赞成[3]反对[5]回复

  • 05真的很丑 2015/09/21

    不错的模板...

    赞成[4]反对[4]回复

  • 06莫等闲 2015/09/22

    ArtTemplate支持koa吗?现在有现成的DEMO么?

    赞成[3]反对[4]回复

  • 07alonso 2015/09/28

    jq的代码不乱啊,我先前是写原生js的,但接触了jq后,代码精湛了不少,可读性也很高。虽然对css的支持有些不足,但兼容做得不错,瑕不掩瑜吧

    赞成[2]反对[2]回复

  • 08陈钢 2015/10/31

    Mustache也有compile方法, to_html 调用 render , render 调用 compile 然后你这个循环 都是每次compile一下, 至少cache功能打开。不然这个对比测试不合理

    赞成[1]反对[4]回复

  • 09设计窝 2015/10/31

    请问JS如何操作artTemplate编译过的元素呢?

    赞成[3]反对[1]回复

  • 10李云滨 2012/06/20

    他是CDC人,微博是t.qq.com/tangbin||@dantezhu: 貌似是artdialog的作者写的?看起来不错,但是为啥会被CDC推荐,是公司的人吗?

  • 11相恒 2012/06/20

    瞎看看 || @mersis: 你也關注cdc了 || @colorfulsand: 牛人总归有牛的道理!

  • 12辰小俊的Time 2012/06/18

    转起来明天看

  • 13王程旭 2012/06/16

    /強

  • 14邵海金 2012/06/16

    关注很久了 || @shengyihao: @hjcq1314 @keketu @roamxj @RAV4_177

  • 15生意专家--郭锐 2012/06/15

    @hjcq1314 @keketu @roamxj @RAV4_177

  • 16梅斯先生 2012/06/15

    你也關注cdc了 || @colorfulsand: 牛人总归有牛的道理!

  • 17兵兵 2012/06/15

    || @citystorm: #jund mark# || @leoangel: mark || @Jerrylu: CDCblog第一天纯技术分享,顶~

  • 18Jerome 2012/06/15

    #jund mark# || @leoangel: mark || @Jerrylu: CDCblog第一天纯技术分享,顶~

  • 19相恒 2012/06/15

    牛人总归有牛的道理!

  • 20贾峰 2012/06/15

    #QY时尚#分享@*5900831

  • 21许庆光 2012/06/15

    mark

  • 22朱念洋 2012/06/15

    貌似是artdialog的作者写的?看起来不错,但是为啥会被CDC推荐,是公司的人吗?||@leoangel: mark || @Jerrylu: CDCblog第一天纯技术分享,顶~

  • 23leeon 2012/06/15

    mark || @Jerrylu: CDCblog第一天纯技术分享,顶~

  • 24路飞-设计师 2012/06/15

    CDCblog第一天纯技术分享,顶~

  • 25腾讯CDC体验设计 2012/06/15

    谢谢支持~ /微笑 || @heroicYang: 干货啊,马克一下再细心阅读。

  • 26腾讯CDC体验设计 2012/06/15

    /鼓掌 || @ufo2y1: 这东西上KM的当天我们项目就用上了。||@xiaokzhang

  • 27腾讯CDC体验设计 2012/06/15

    /呲牙 || @zhangyiyao: CDC的博客一直干货多。

  • 28谢福才 2012/06/15

    不错,收藏

  • 29张乂爻 2012/06/15

    CDC的博客一直干货多。

  • 30YY-资深吐槽分析师 2012/06/15

    这东西上KM的当天我们项目就用上了。||@xiaokzhang

  • 31王永山 2012/06/15

    糖饼兄的这文章终于在CDC上排到头了 /鼓掌,等的黄花菜都凉了. CDC的文章排队也忒慢了吧

  • 32杨雄 2012/06/15

    干货啊,马克一下再细心阅读。

  • 33林永鹏 2012/06/15

    0.0

欢迎大家参与微博讨论和作者互动:腾讯微博 & 新浪微博

欢迎大家参与微博讨论和作者互动:腾讯微博 & 新浪微博