Juicer一个 Javascript 模板引擎の实现与优化            流火 @ TaobaoUED            Blog: http://benben.cc
var json={    name:"liuhuo",    blog:"ued.taobao.com"};
var json={               name:"liuhuo",               blog:"ued.taobao.com"           };<span class="name">流火 (blog: ued.t...
var json={                        name:"liuhuo",                        blog:"ued.taobao.com"                    };       ...
function sub(str,data) {    return str        .replace(/{(.*?)}/igm,function($,$1) {            return data[$1]?data[$1]:$...
var tpl=<span class="name">{name} (blog: {blog})</span>;var html=sub(tpl,json);
YUI.Lang.sub
JSON   Template
JSON   Template
JSON   Template        Engine    Template
JSON   Template        Engine    Template
JSON   Template        Engine    Template
JSON   Template        Engine    Template         HTML       Fragment
water     juicer     fruitsJSON    Template         Engine    Template          HTML        Fragment
doT      yayaTemplate    ejs             Mustache                             artTemplatenTenjin                    Kissy ...
“如无必要,勿增实体”Entia non sunt multiplicanda praeternecessitatem.
Security
Security XSS escape
Security          XSS escapeSyntax
Security                        XSS escape Syntaxeasy to write & read
Security                        XSS escape Syntax                              Performanceeasy to write & read
Security                        XSS escape Syntax                              Performanceeasy to write & read            ...
Security                        XSS escape Syntax                              Performanceeasy to write & read            ...
Security                        XSS escape Syntax                              Performanceeasy to write & read            ...
Security                        XSS escape Syntax                              Performanceeasy to write & read            ...
Syntax<ul>                                               <ul>                                            <ul>    {{#list}}...
JSONvar data={    list:[        {name:liuhuo,show:true},        {name:benben,show:false},        {name:taobao,show:true}  ...
JSON                                  EXPECTED RESULTvar data={                            <ul>    list:[                 ...
<ul>    {@each data.list as it,k}        {@if it.show}            <li>${it.name} (index: ${k})</li>        {@/if}    {@/ea...
<ul>    {{#each list as it,index}}        {{#if it.show}}            <li>{{it.name}} (index: {{index}})</li>        {{/if}...
<ul>    {{#list}}        {{#show}}            <li>{{name}} (index: {{index}})</li>        {{/show}}    {{/list}}    {{#bla...
<ul>    <% for(var i=0;i<list.length;i++) { %>        <% if(list[i].show) { %>            <li><%= list[i].name %> (index: ...
<ul>    <?js for(var i=0;i<it.list.length;i++) { ?>        <?js if(it.list[i].show) { ?>            <li>${it.list[i].name}...
Performance
Performance              http://jsperf.com/javascript-template-engine/11
Performance test result without       escape.
Performance test result without       escape.
Performance    test result without          escape.http://juicer.name/speedtest
Securityvar json={" output:<script>alert("XSS");</script>};
Securityvar json={" output:<script>alert("XSS");</script>};document.write
Securityvar json={" output:<script>alert("XSS");</script>};document.write                        $(node).html()
Securityvar json={" output:<script>alert("XSS");</script>};document.write                        $(node).html()juicer.to_h...
template
compiletemplate             reusable function
compiletemplate             reusable function                           compiled template
compile                             rendertemplate             reusable function                  html code               ...
var json={    list:[        {name:"benben"},        {name:"liuhuo"}    ]};var tpl={@each data.list as value,key}$${value.n...
function anonymous(data) {    var data = data || {};    var out = ;    out += ;    for (var i0 = 0, l = data.list.length; ...
Several Optimization Point
Several Optimization Point                using += instead of array.push
Browser string optimizations have changed the stringconcatenation picture.Firefox was the first browser to optimize string ...
The V8 javascript engine (used in Google Chrome) uses this codeto do string concatenation:// ECMA-262, section 15.5.4.6fun...
Several Optimization Point                             avoid using with {}
var person = {                        The with construct introduces an extra scope for    name: "Nicholas",               ...
Several Optimization Point                  cache the compiled template.
1 循环 {@each}…{@/each}2 判断 {@if}…{@else if}…{@else}…{@/if}3 变量(支持函数)${varname|function}4 注释 {# comment here}
a demo, then docs.          http://juicer.name
Juicer Docsjuicer is a high-performance lightweight javascript template engine, the benefits of using juicer is that youca...
* API> compile and render the template with given data immediately.juicer.to_html(tpl,data,options);> only compile the tem...
* Syntaxa. ${var}using ${} to evaluating expressions and functions.${data.name}${data.name|function}lets use a demo to ill...
{@each data.list as it,k}    <span class=”{@if k+2>data.list.length}notdot{@/if}”>...</span>{@/each}
http://taobao.com/s?q=%E6%B7%98%E5%AE%9D                                                  json={                          ...
escape/unescapeit is noteworthy that, for security reasons, ${output} will do escape to the output, if youdo not want it t...
b. {@each} ... {@/each}when you need iterate a list, you can use `each` like this.{@each data.list as item}"   ${item.prop...
c. {@if} ... {@else} ... {else if} ... {@/if}you can also use if-else if you need.{@each data.list as item,index}"   {@if ...
* running on the Node.js environmentbash:   npm install juicervar juicer=require(juicer);var html=juicer.to_html(tpl,data,...
juicer.to_html(         ‘${data.end}’,Q&A      {end:‘thanks!’}      );              http://juicer.name
Juicer   javascript template engine
Juicer   javascript template engine
Juicer   javascript template engine
Juicer   javascript template engine
Juicer   javascript template engine
Juicer   javascript template engine
Juicer   javascript template engine
Juicer   javascript template engine
Upcoming SlideShare
Loading in …5
×

Juicer javascript template engine

1,125 views

Published on

Juicer javascript template engine
http://juicer.name

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,125
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
10
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Juicer javascript template engine

    1. 1. Juicer一个 Javascript 模板引擎の实现与优化 流火 @ TaobaoUED Blog: http://benben.cc
    2. 2. var json={    name:"liuhuo",    blog:"ued.taobao.com"};
    3. 3. var json={     name:"liuhuo",     blog:"ued.taobao.com" };<span class="name">流火 (blog: ued.taobao.com)</span>
    4. 4. var json={     name:"liuhuo",     blog:"ued.taobao.com" }; <span class="name">流火 (blog: ued.taobao.com)</span>var html;html=<span class="name">+json.name+ (blog: +json.blog+)</span>;
    5. 5. function sub(str,data) { return str .replace(/{(.*?)}/igm,function($,$1) { return data[$1]?data[$1]:$; });}
    6. 6. var tpl=<span class="name">{name} (blog: {blog})</span>;var html=sub(tpl,json);
    7. 7. YUI.Lang.sub
    8. 8. JSON Template
    9. 9. JSON Template
    10. 10. JSON Template Engine Template
    11. 11. JSON Template Engine Template
    12. 12. JSON Template Engine Template
    13. 13. JSON Template Engine Template HTML Fragment
    14. 14. water juicer fruitsJSON Template Engine Template HTML Fragment
    15. 15. doT yayaTemplate ejs Mustache artTemplatenTenjin Kissy template micro template ... jQuery tmpl
    16. 16. “如无必要,勿增实体”Entia non sunt multiplicanda praeternecessitatem.
    17. 17. Security
    18. 18. Security XSS escape
    19. 19. Security XSS escapeSyntax
    20. 20. Security XSS escape Syntaxeasy to write & read
    21. 21. Security XSS escape Syntax Performanceeasy to write & read
    22. 22. Security XSS escape Syntax Performanceeasy to write & read as faster as you can
    23. 23. Security XSS escape Syntax Performanceeasy to write & read as faster as you can Error Handling
    24. 24. Security XSS escape Syntax Performanceeasy to write & read as faster as you can Error Handling robustness
    25. 25. Security XSS escape Syntax Performanceeasy to write & read as faster as you can Error Handling robustness
    26. 26. Syntax<ul> <ul> <ul>    {{#list}}     {@each data.list as it,k}     {{#each list as it,k}}        {{#show}}         {@if it.show}         {{#if it.show}}            <li>{{name}} (index: {{index}})</li>             <li>${it.name} (index: ${k})</li>             <li>{{it.name}} (index: {{k}})</li>        {{/show}}         {@/if}         {{/if}}    {{/list}}     {@/each}     {{/each}}    {{#blah}}     {@each data.blah as it}     {{#each blah as it}}        <li>         <li>         <li>            num: {{num}}             num: ${it.num}             num: {{it.num}}            ...             {@if it.num==3}             {{#if it.num==3}}            {{#inner}}                 {@each it.inner as it2}                 {{#each it.inner as it2}}                <li>{{time}}</li>                     <li>${it2.time}</li>                     <li>{{it2.time}}</li>            {{/inner}}                 {@/each}                 {{/each}}            ...             {@/if}             {{/if}}        </li>         </li>         </li>    {{/blah}}     {@/each}     {{/each}}</ul> </ul> </ul><ul> <ul>    <% for(var i=0;i<list.length;i++) { %>     <?js for(var i=0;i<it.list.length;i++) { ?>        <% if(list[i].show) { %>         <?js if(it.list[i].show) { ?>            <li><%= list[i].name %> (index: <%= i %>)</li>             <li>${it.list[i].name} (index: ${i})</li>        <% } %>         <?js } ?>    <% } %>     <?js } ?>    <% for(var i=0;i<blah.length;i++) { %>     <?js for(var i=0;i<it.blah.length;i++) { ?>        <li>         <li>            num: <%= blah[i].num %>             num: ${it.blah[i].num}            <% if(blah[i].num==3) { %>                        <?js if(it.blah[i].num==3) { ?>                           <% for(var j=0;j<blah[i].inner.length;j++) { %>                 <?js for(var j=0;j<it.blah[i].inner.length;j++) { ?>                    <li><%= blah[i].inner[j].time %></li>                     <li>${it.blah[i].inner[j].time}</li>                <% } %>                 <?js } ?>            <% } %>             <?js } ?>        </li>         </li>    <% } %>     <?js } ?></ul> </ul>
    27. 27. JSONvar data={    list:[        {name:liuhuo,show:true},        {name:benben,show:false},        {name:taobao,show:true}    ],    blah:[        {num:1},        {num:2},        {num:3,inner:[            {time:15:00},            {time:16:00},            {time:17:00},            {time:18:00}        ]},        {num:4}    ]};
    28. 28. JSON EXPECTED RESULTvar data={ <ul>    list:[     <li>liuhuo (index: 0)</li>        {name:liuhuo,show:true},     <li>benben (index: 1)</li>        {name:benben,show:false},     <li>taobao (index: 2)</li>        {name:taobao,show:true}     <li>num: 1</li>    ],     <li>num: 2</li>    blah:[     <li>num: 3</li>        {num:1},     <li>15:00</li>        {num:2},     <li>16:00</li>        {num:3,inner:[     <li>17:00</li>            {time:15:00},     <li>18:00</li>            {time:16:00},     <li>num: 4</li>            {time:17:00}, </ul>            {time:18:00}        ]},        {num:4}    ]};
    29. 29. <ul>    {@each data.list as it,k}        {@if it.show}            <li>${it.name} (index: ${k})</li>        {@/if}    {@/each}    {@each data.blah as it}        <li>            num: ${it.num}            {@if it.num==3}                {@each it.inner as it2}                    <li>${it2.time}</li>                {@/each}            {@/if}        </li>    {@/each}</ul> using juicer http://jsfiddle.net/paulguo/LpvwH/1/
    30. 30. <ul>    {{#each list as it,index}}        {{#if it.show}}            <li>{{it.name}} (index: {{index}})</li>        {{/if}}    {{/each}}    {{#each blah as it}}        <li>            num: {{it.num}}            {{#if it.num==3}}                {{#each it.inner as it2}}                    <li>{{it2.time}}</li>                {{/each}}            {{/if}}        </li>    {{/each}}</ul> using kissy http://jsfiddle.net/paulguo/yLg4Y/1/
    31. 31. <ul>    {{#list}}        {{#show}}            <li>{{name}} (index: {{index}})</li>        {{/show}}    {{/list}}    {{#blah}}        <li>            num: {{num}}            {{#inner}}                <li>{{time}}</li>            {{/inner}}        </li>    {{/blah}}</ul> using mustache http://jsfiddle.net/paulguo/VCH9k/1/
    32. 32. <ul>    <% for(var i=0;i<list.length;i++) { %>        <% if(list[i].show) { %>            <li><%= list[i].name %> (index: <%= i %>)</li>        <% } %>    <% } %>    <% for(var i=0;i<blah.length;i++) { %>        <li>            num: <%= blah[i].num %>            <% if(blah[i].num==3) { %>                           <% for(var j=0;j<blah[i].inner.length;j++) { %>                    <li><%= blah[i].inner[j].time %></li>                <% } %>            <% } %>        </li>    <% } %></ul> using micro http://jsfiddle.net/paulguo/KsDhC/1/
    33. 33. <ul>    <?js for(var i=0;i<it.list.length;i++) { ?>        <?js if(it.list[i].show) { ?>            <li>${it.list[i].name} (index: ${i})</li>        <?js } ?>    <?js } ?>    <?js for(var i=0;i<it.blah.length;i++) { ?>        <li>            num: ${it.blah[i].num}            <?js if(it.blah[i].num==3) { ?>                           <?js for(var j=0;j<it.blah[i].inner.length;j++) { ?>                    <li>${it.blah[i].inner[j].time}</li>                <?js } ?>            <?js } ?>        </li>    <?js } ?></ul> using nTenjin http://jsfiddle.net/paulguo/W7eVV/1/
    34. 34. Performance
    35. 35. Performance http://jsperf.com/javascript-template-engine/11
    36. 36. Performance test result without escape.
    37. 37. Performance test result without escape.
    38. 38. Performance test result without escape.http://juicer.name/speedtest
    39. 39. Securityvar json={" output:<script>alert("XSS");</script>};
    40. 40. Securityvar json={" output:<script>alert("XSS");</script>};document.write
    41. 41. Securityvar json={" output:<script>alert("XSS");</script>};document.write $(node).html()
    42. 42. Securityvar json={" output:<script>alert("XSS");</script>};document.write $(node).html()juicer.to_html(${output},json);//输出:&lt;script&gt;alert("XSS");&lt;/script&gt;juicer.to_html($${output},json);//输出:<script>alert("XSS");</script>
    43. 43. template
    44. 44. compiletemplate reusable function
    45. 45. compiletemplate reusable function compiled template
    46. 46. compile rendertemplate reusable function html code compiled template
    47. 47. var json={    list:[        {name:"benben"},        {name:"liuhuo"}    ]};var tpl={@each data.list as value,key}$${value.name}{@/each};var compiled_tpl=juicer.compile(tpl,{errorhandling:false});
    48. 48. function anonymous(data) {    var data = data || {};    var out = ;    out += ;    for (var i0 = 0, l = data.list.length; i0 < l; i0++) {        var value = data.list[i0];        var key = i0;        out += ;        out += ((value.name));        out += ;    }    out += ;    return out;}
    49. 49. Several Optimization Point
    50. 50. Several Optimization Point using += instead of array.push
    51. 51. Browser string optimizations have changed the stringconcatenation picture.Firefox was the first browser to optimize string concatenation. Beginning withversion 1.0, the array technique is actually slower than using the plus operatorin all cases. Other browsers have also optimized string concatenation, soSafari, Opera, Chrome, and Internet Explorer 8 also show better performanceusing the plus operator. Internet Explorer prior to version 8 didn’t have such anoptimization, and so the array technique is always faster than the plus operator.— Writing Efficient JavaScript: Chapter 7 – Even Faster Websites
    52. 52. The V8 javascript engine (used in Google Chrome) uses this codeto do string concatenation:// ECMA-262, section 15.5.4.6function StringConcat() {  if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {    throw MakeTypeError("called_on_null_or_undefined", ["String.prototype.concat"]);  }  var len = %_ArgumentsLength();  var this_as_string = TO_STRING_INLINE(this);  if (len === 1) {    return this_as_string + %_Arguments(0);  }  var parts = new InternalArray(len + 1);  parts[0] = this_as_string;  for (var i = 0; i < len; i++) {    var part = %_Arguments(i);    parts[i + 1] = TO_STRING_INLINE(part);  }  return %StringBuilderConcat(parts, len + 1, "");}
    53. 53. Several Optimization Point avoid using with {}
    54. 54. var person = { The with construct introduces an extra scope for name: "Nicholas", the script engine to search through whenever a age: 30 variable is referenced. This alone produces a}; minor performance decrease. However, the contents of that scope are not known at compilefunction displayInfo(){ time, meaning that the compiler cannot optimize var count = 5; for it, in the same way as it can with normal scopes with(person){ (such as those created by functions). alert(name + " is " + age); alert("Count is " + count); }}displayInfo();
    55. 55. Several Optimization Point cache the compiled template.
    56. 56. 1 循环 {@each}…{@/each}2 判断 {@if}…{@else if}…{@else}…{@/if}3 变量(支持函数)${varname|function}4 注释 {# comment here}
    57. 57. a demo, then docs. http://juicer.name
    58. 58. Juicer Docsjuicer is a high-performance lightweight javascript template engine, the benefits of using juicer is that youcan seperate your data and the html structure. it can also running on node.js environment.the name of juicerif the data is fruit, the template compared to water, through the juicer will be able to put them mixed intohtml code.import juicer.js<script type="text/javascript" src="juicer-min.js"></script>* Licensejuicer is published under the apache license and hosted on github. if you find errors or typos please file anissueor a pull request on the repository.
    59. 59. * API> compile and render the template with given data immediately.juicer.to_html(tpl,data,options);> only compile the template, itll return a reusable function for the given `template`.var tpl=juicer.compile(tpl,options);> render the complied template with given data.var tpl=juicer.compile(tpl,options);var html=tpl.render(data);Options{" cache:true/false," loose:false/true, errorhandling:true/false}cache in the options means that whether cache the pre-compiled templates.
    60. 60. * Syntaxa. ${var}using ${} to evaluating expressions and functions.${data.name}${data.name|function}lets use a demo to illustrate this usage.var json={" name:benben," age:23};var inc=function(number) {" return number+1;};//itll be benbenjuicer.to_html(${data.name},json);//itll be 24juicer.to_html(${data.age|inc},json);
    61. 61. {@each data.list as it,k} <span class=”{@if k+2>data.list.length}notdot{@/if}”>...</span>{@/each}
    62. 62. http://taobao.com/s?q=%E6%B7%98%E5%AE%9D json={ query:’淘宝’, ... }http://taobao.com/s?q=${query|encodeURIComponent}
    63. 63. escape/unescapeit is noteworthy that, for security reasons, ${output} will do escape to the output, if youdo not want it to be escaped, you can use $${output} to avoid this. for example:var json={" value:<strong>juicer</strong>};var escapetpl=${data.value};var unescapetpl=$${data.value};juicer.to_html(escapetpl,json); //itll be &lt;strong&gt;juicer&lt;/strong&gt;juicer.to_html(unescapetpl,json); //itll be <strong>juicer</strong>
    64. 64. b. {@each} ... {@/each}when you need iterate a list, you can use `each` like this.{@each data.list as item}" ${item.prop}{@/each}you can also get the index while eaching.{@each data.list as item,index}" ${item.prop}" ${index} //index{@/each}
    65. 65. c. {@if} ... {@else} ... {else if} ... {@/if}you can also use if-else if you need.{@each data.list as item,index}" {@if index===3}" " the index is 3, the value is ${item.prop}" {@else}" " the index is not 3, the value is ${item.prop}" {@/if}{@/each}d. {# comment}you can also write comments in the template code to facilitate future management.{# some comment here}
    66. 66. * running on the Node.js environmentbash: npm install juicervar juicer=require(juicer);var html=juicer.to_html(tpl,data,options);
    67. 67. juicer.to_html( ‘${data.end}’,Q&A {end:‘thanks!’} ); http://juicer.name

    ×