• 热门专题

性能卓越的js模板引擎artTemplate

作者:爱邱  发布日期:2016-06-06 21:51:16
Tag标签:性能  模板  引擎  
  •      以前研究过一段时间的handlebars,但因为其渲染性能略逊于腾讯的artTemplate(在artTemplate的GitHub官网上有推荐的性能测试地址),貌似最近耳边听到得最多的模板引擎也就是artTemplate了,所以就花个时间来研究下吧...

         artTemplate是新一代的javascript模板引擎,若采用拥有V8引擎的chrome浏览器进行测试,其渲染性能甚至能达到知名模板引擎Mustache的20倍以上以及模板引擎tmpl的40倍以上,测试截图如下:

     

        下面进入正题:

        特性


    性能卓越,执行速度通常是 Mustache 与 tmpl 的 20 多倍 支持运行时调试,可精确定位异常模板所在语句 对 NodeJS Express 友好支持 安全,默认对输出进行转义、在沙箱中运行编译后的代码(Node版本可以安全执行用户上传的模板) 支持include语句 可在浏览器端实现按路径加载模板 支持预编译,可将模板转换成为非常精简的 js 文件 模板语句简洁,无需前缀引用数据,有简洁版本与原生语法版本可选 支持所有流行的浏览器

         

          快速上手


          编写模板(采用script标签并带有属性id和type='text/html')

    <script id='test' type='text/html'>
       {{if isAdmin}}
       
       <h3>{{author}}</h3>
       <ul>
        {{each list as value i}}
        <li>{{i+1}}:{{value}}</li>
        {{/each}}
       </ul>
       
       {{/if}}
      </script>

          渲染模板

    1 var data = {
    2     author: '宫崎骏',
    3     isAdmin: true,
    4     list: ['千与千寻', '哈尔的移动城堡', '幽灵公主', '风之谷', '龙猫']
    5 };
    6 var html = template('test', data);
    7 document.getElementById('content').innerHTML = html;

         

          模板语法


           有两个版本的模板语法可以选择。

          1.简洁语法(采用'{{ }}',推荐使用)

    <script id='test' type='text/html'>
    {{if admin}}
      {{include 'admin_content'}}
    
      {{each list}}
         <div>{{$index}}.{{$value.user}}</div>
      {{/each}}
    {{/if}}
    </script>

          2.原生语法(采用'<%= %>')

    <script id='test' type='text/html'>
    <%if {%>
      <%include('admin_content')%>
    
      <%for (var i=0;i<list.length;i++) {%>
        <div><%=i%>.<%=list[i].user%></div>
      <%}%>
    <%}%>
    </script>

         

          下载地址


           

    template.js (简洁语法版, 2.7kb) template-native.js (原生语法版, 2.3kb)

         

          方法


            1. template(id, data)

          根据 id 渲染模板。内部会根据document.getElementById(id)查找模板,如果没有 data 参数,那么将返回一渲染函数。

     1 //修改代码前
     2 var data = {
     3     author: '宫崎骏',
     4     isAdmin: true,
     5     list: ['千与千寻', '哈尔的移动城堡', '幽灵公主', '风之谷', '龙猫']
     6    };
     7 var html = template('test', data);
     8 document.getElementById('content').innerHTML = html;
     9 
    10 //修改代码后
    11 var data = {
    12     author: '宫崎骏',
    13     isAdmin: true,
    14     list: ['千与千寻', '哈尔的移动城堡', '幽灵公主', '风之谷', '龙猫']
    15    };
    16 var html = template('test');
    17 console.log(html);

          控制台输出结果如下图:

             2. template.compile(source, options)

          将返回一个渲染函数。

     1 <h3>用变量存放模板</h3>
     2   <div id='content'></div>
     3   <script>
     4    var source = '<ul>' +
     5                   '{{each list as value i}}' +
     6                     '<li>{{i+1}}.{{value}}</li>' +
     7                   '{{/each}}' +
     8                 '</ul>';
     9    var render = template.compile(source);
    10    var html = render({
    11     list: ['千与千寻', '哈尔的移动城堡', '幽灵公主', '风之谷', '龙猫']
    12    });
    13    document.getElementById('content').innerHTML = html;
    14   </script>

             3. template.render(source, options)

          将返回一个渲染结果。

             4. template.helper(name, callback)

          将返回一个渲染结果。

     1 <script id='test' type='text/html'>
     2    {{time | dateFormat: 'yyyy年 MM月 dd日 hh:mm:ss'}}
     3   </script>
     4   <script>
     5    template.helper('dateFormat', function(date, format) {
     6     var date = new Date(date);
     7     var map = {
     8      M: date.getMonth() + 1, //月份
     9      d: date.getDate(), //日
    10      h: date.getHours(), //小时
    11      m: date.getMinutes(), //分
    12      s: date.getSeconds(), //秒
    13      q: Math.floor((date.getMonth() + 3) / 3), //季度
    14      S: date.getMilliseconds() //毫秒
    15     };
    16     var format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
    17      var v = map[t];
    18      if (v !== undefined) {
    19       if (all.length > 1) {
    20        v = '0' + v;
    21        v = v.substr(v.length - 2);
    22       }
    23       return v;
    24      } else if (t === 'y') {
    25       return (date.getFullYear() + '').substr(4 - all.length);
    26      }
    27      return all;
    28     });
    29     return format;
    30    });
    31    // ---------
    32    var data = {
    33     time: new Date().toString()
    34    };
    35    var html = template('test', data);
    36    document.getElementById('content').innerHTML = html;
    37   </script>

             5. template.config(name, value)

          更改引擎的默认配置。

字段 类型 默认值 说明
openTag String '{{' 逻辑语法开始标签
closeTag String '}}' 逻辑语法结束标签
escape Boolean true 是否编码输出 HTML 字符
cache Boolean true 是否开启缓存(依赖 options 的 filename 字段)
compress Boolean false 是否压缩 HTML 多余空白字符

     

      使用预编译


       可突破浏览器限制,让前端模板拥有后端模板一样的同步“文件”加载能力:

      一、按文件与目录组织模板

template('tpl/home/main', data)

    二、模板支持引入子模板

{{include '../public/header'}}

     

      基于预编译


       

可将模板转换成为非常精简的 js 文件(不依赖引擎) 使用同步模板加载接口 支持多种 js 模块输出:AMD、CMD、CommonJS 支持作为 GruntJS 插件构建 前端模板可共享给 NodeJS 执行 自动压缩打包模板

   预编译工具:TmodJS

     

      NodeJS


       安装

npm install art-template

    使用

var template = require('art-template');
var data = {list: ['aui', 'test']};

var html = template(__dirname + '/index/main', data);

    配置

     NodeJS 版本新增了如下默认配置:

字段 类型 默认值 说明
base String '' 指定模板目录
extname String '.html' 指定模板后缀名
encoding String 'utf-8' 指定模板编码

    

     配置base指定模板目录可以缩短模板的路径,并且能够避免include语句越级访问任意路径引发安全隐患,例如:

template.config('base', __dirname);
var html = template('index/main', data)

    NodeJS + Express

var template = require('art-template');
template.config('base', '');
template.config('extname', '.html');
app.engine('.html', template.__express);
app.set('view engine', 'html');
//app.set('views', __dirname + '/views');

    运行 demo:

node demo/node-template-express.js

延伸阅读:

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规