Javascript模版引擎简介

系统 1819 0

回顾

  • Micro-Templating

出自John Resig 2008年的一片文章,以及其经典实现:

    
      
        // Simple JavaScript Templating
      
      
        // John Resig - http://ejohn.org/ - MIT Licensed
      
      
(
      
        function
      
      (){
  
      
        var
      
       cache = {};

  
      
        this
      
      .tmpl = 
      
        
          function
        
        
          tmpl
        
        
          (str, data)
        
        {
      
      
        // Figure out if we're getting a template, or if we need to
      
      
        // load the template - and be sure to cache the result.
      
      
        var
      
       fn = !
      
        /\W/
      
      .test(str) ?
      cache[str] = cache[str] ||
        tmpl(document.getElementById(str).innerHTML) :

      
      
        // Generate a reusable function that will serve as a template
      
      
        // generator (and which will be cached).
      
      
        new
      
       Function(
      
        "obj"
      
      ,
        
      
        "var p=[],print=function(){p.push.apply(p,arguments);};"
      
       +

        
      
        // Introduce the data as local variables using with(){}
      
      
        "with(obj){p.push('"
      
       +

        
      
        // Convert the template into pure JavaScript
      
      
        str
          .replace(
      
        /[\r\t\n]/g
      
      , 
      
        " "
      
      )
          .split(
      
        "<%"
      
      ).join(
      
        "\t"
      
      )
          .replace(
      
        /((^|%>)[^\t]*)'/g
      
      , 
      
        "$1\r"
      
      )
          .replace(
      
        /\t=(.*?)%>/g
      
      , 
      
        "',$1,'"
      
      )
          .split(
      
        "\t"
      
      ).join(
      
        "');"
      
      )
          .split(
      
        "%>"
      
      ).join(
      
        "p.push('"
      
      )
          .split(
      
        "\r"
      
      ).join(
      
        "\\'"
      
      )
      + 
      
        "');}return p.join('');"
      
      );

    
      
        // Provide some basic currying to the user
      
      
        return
      
       data ? fn( data ) : fn;
  };
})();
    
  
  1. 基本的replace生成代码,终端动态编译方案
  2. 使用with解决context问题
  • Mustache.js & othors

更加丰富的模版语法,以及更加容易扩展。

    
      /**
   * Breaks up the given `template` string into a tree of tokens. If the `tags`
   * argument 
      
        is
      
       given here it must be an array 
      
        with
      
       two string values: the
   * opening 
      
        and
      
       closing tags used 
      
        in
      
       the template (e.g. [ 
      
        "<%"
      
      , 
      
        "%>"
      
       ]). Of
   * course, the default 
      
        is
      
       to use mustaches (i.e. mustache.tags).
   *
   * A token 
      
        is
      
       an array 
      
        with
      
       at least 
      
        4
      
       elements. The first element 
      
        is
      
       the
   * mustache symbol that was used inside the tag, e.g. 
      
        "#"
      
      
        or
      
      
        "&"
      
      . If the tag
   * did 
      
        not
      
       contain a symbol (i.e. {{myValue}}) this element 
      
        is
      
      
        "name"
      
      . For
   * all text that appears outside a symbol this element 
      
        is
      
      
        "text"
      
      .
   *
   * The second element of a token 
      
        is
      
       its 
      
        "value"
      
      . For mustache tags this 
      
        is
      
      
   * whatever 
      
        else
      
       was inside the tag besides the opening symbol. For text tokens
   * this 
      
        is
      
       the text itself.
   *
   * The third 
      
        and
      
       fourth elements of the token are the start 
      
        and
      
       end indices,
   * respectively, of the token 
      
        in
      
       the original template.
   *
   * Tokens that are the root node of a subtree contain two more elements: 
      
        1
      
      ) an
   * array of tokens 
      
        in
      
       the subtree 
      
        and
      
      
        2
      
      ) the index 
      
        in
      
       the original template at
   * which the closing tag 
      
        for
      
       that section begins.
   */
    
  

我们可以从这段备注中简单的看出Mustache.js的编译原理。

性能优化之路

模版引擎成功将动态HTML代码从Javascript中分离出来,避免了从前频繁的Javascript代码中的字符串拼接,简化了编码工作,实则是前端发展的大跃进。但当部分人还在痴迷与模版引擎的功能时,已经有人朝性能方向迈进。

  • 缓存技术

每次将Template字符串转化成函数己经变成一种浪费,缓存简单说是编译后将函数cache起来,仅此而已。

  • context预赋值

为了避免使用with这种效率较低的方法而出现的,简单的说就是把传入的数据对象中的所有节点都变成局部变量,下面是一个简单的例子:

    
      
        var
      
       compile = 
      
        function
      
      (str){
        
      
        //避免with语法
      
      
        var
      
       strFn = 
      
        "var _$jstpl='',__fn__=(function(__d__){var __v__='';for(var __k__ in __d__){__v__+=('var '+__k__+'=__d__[\"'+__k__+'\"];');};eval(__v__);_$jstpl+='"
      
       + parse(str) + 
      
        "';__v__=null;})(param);__fn__ = null;return _$jstpl;"
      
      ;
        
      
        return
      
      
        new
      
       Function(
      
        "param"
      
      , strFn);
    };
    
  
  • 规范关键字

作为最快的模版引擎,doT根本不使用with,而是直接通过规范关键字传入参数为it,然后所有参数都用it的节点来引用。

  • 线下编译

浏览器编译过程转为线下,直接生成执行函数。

  • 拼接方法

字符串拼接方法一般有:

  1. arr.push & arr.join
  2. res += tmp
  3. res = res + tmp

很多人误以为数组 push 方法拼接字符串会比 += 快,要知道这仅仅是 IE6-8 的浏览器下。实测表明现代浏览器使用 += 会比数组 push 方法快,而在 v8 引擎中,使用 += 方式比数组拼接快 4.7 倍。最新的一些测试结果还发现 res = res + tmp 在v8某些版本甚至比 res += tmp 还快。

未来

有些时候流行总在轮回,比如黑框眼睛以前是我们奶奶那辈人戴的,但现在年轻人都开始戴了。

模版从后端render,变成前端render,变成线下render……现在又随着NodeJS的崛起回来了后端(前台?)render,部分大公司如: Facebook Google 已经线上应用。

Javascript模版引擎简介


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论