During Normal coding, you often need to splice strings. For example, if json data is displayed in HTML, String concatenation and logic mixing will obscure the code, increased collaboration and maintenance costs. The front-end template mechanism can effectively solve this problem.
There are many open-source front-end templates, but the "javascript micro templating" developed by John Resig, jQuery's author, is the most subtle. With just a few clicks, the core functions of the template engine are implemented.
See the author's blog: http://ejohn.org/blog/javascript-micro-templating/ for its introduction and usage
Let's first look at his source code:
The Code is as follows:
(Function (){
Var cache = {};
This. tmpl = function (str, data ){
Var fn =! /\ W/. test (str )?
Cache [str] = cache [str] |
Tmpl (document. getElementById (str). innerHTML ):
New Function ("obj ",
"Var p = [], print = function () {p. push. apply (p, arguments) ;};" +
"With (obj) {p. push ('" +
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 ('');");
Return data? Fn (data): fn;
};
})();
Despite being small and dirty, the sparrow has a caching mechanism and logic support in addition to basic data appending. Now, if I want to rank the most energy-efficient custom function in javascript, the first place is the $ function (document. getElementById Lite version), and the second place is tmpl.
Of course, it is not perfect. I found some problems during use:
Tmpl weaknesses
1. escape characters cannot be correctly processed, for example:
The Code is as follows:
Tmpl ('<% = name %> // <% = id %>', {name: 'sugar bread ', id: '2016 '});
It will report an error. If it works properly, it should output: sugar cake/1987
In fact, it is easy to solve. Add a regular line to escape the escape character:
The Code is as follows:
Str. replace (// \\/ g ,"\\\\")
2. Sometimes it cannot correctly distinguish whether the first parameter is ID or template.
If the Page Template ID is underlined, for example, tmpl-photo-thumb, it does not search for the template with this name, and it is considered that the input is the original template and the output is compiled directly.
The most intuitive difference between the original template and element id is whether it contains spaces. Therefore, modify the regular expression:
View sourceprint? 1! /\ S/. test (str)
3. It also contains a code for testing and can be deleted.
The Code is as follows:
Print = function () {p. push. apply (p, arguments );}
Tmpl efficiency concerns
Until I read a soft article about YayaTemplate from Baidu mux some time ago, the author of the original article tested the efficiency of various popular template engines, and finally concluded that YayaTemplate is the fastest. Although the test result tmpl is inferior to YayaTemplate, it also dispelled my concerns about performance. In practice, it is similar to the traditional String concatenation. They only have to perform super-large-scale parsing to have a large performance gap. (Ultra-large scale? Javascript itself is not suitable for this. If the programmer inserts thousands of List data records into the browser at a time and it is extremely slow, there is no doubt: the problem lies in this programmer, and he will not cherish the user's browser .)
When talking about the engine efficiency ranking, I don't think this is not the top standard for measuring the template engine. The template syntax is also an important part. At this time, the template syntax of YayaTemplate is much obscure, it is clever in template syntax to save a few regular expressions.
First, the source code of YayaTemplate is displayed:
The Code is as follows:
// Author: yaya, jihu
// Uloveit.com.cn/template
// How to use? YayaTemplate ("xxx"). render ({});
Var YayaTemplate = YayaTemplate | function (str ){
// Core Analysis Method
Var _ analyze = function (text ){
Return text. replace (/{\$ (\ s | \ S )*? \ $}/G, function (s ){
Return s. replace (/("| \)/g," \ $1 ")
. Replace ("{$", '_ s. push ("')
. Replace ("$ }",'");')
. Replace (/{\ % ([\ s \ S] *?) \ %}/G, '", $1 ,"')
}). Replace (/\ r | \ n/g ,"");
};
// Intermediate code
Var _ temp = _ analyze (document. getElementById (str )? Document. getElementById (str). innerHTML: str );
// Return generator render Method
Return {
Render: function (mapping ){
Var _ a = [], _ v = [], I;
For (I in mapping ){
_ A. push (I );
_ V. push (mapping [I]);
}
Return (new Function (_ a, "var _ s = [];" + _ temp + "return _ s ;")). apply (null, _ v ). join ("");
}
}
};
Why is tmpl slower than YayaTemplate if we try to solve the performance problem to a high degree of "academic problem?
Syntax Parsing? Although YayaTemplate uses a novel javascript wrapped html method as the template syntax, it eventually needs to be parsed into a standard javascript syntax using a regular expression. Here, the regular expression efficiency will not be much different, both parties use the cache mechanism to ensure that only the original template is parsed once.
Data conversion? The template engine will save the data in the form of variables in the closure to get the template. Here we will first compare the variable declaration mechanism of both parties:
YayaTemplate is implemented in the form of traditional parameter passing. It traverses the data object, separates the Object Name and value, and uses the object member name as the new Function parameter name (that is, the variable name) respectively ), then, use the appley call method of the function to pass those parameters.
Tmpl is implemented using a with statement that is not commonly used in javascript. The implementation method is concise, saving the keyword var.
The performance problem of tmpl lies in. The with statement provided by javascript is intended to access the attributes of objects more quickly. Unfortunately, the existence of the with statement in the language seriously affects the speed of the javascript engine, because it blocks the lexical scope binding of variable names.
Optimize tmpl
If tmpl is removed from the with statement, the performance of passing parameters using the traditional method is greatly improved. After measurement, firefox can be increased by 5 times, chrome 0.24 million times, and opera 2.4 times, safari 2.1 times, IE6 1.1 times, IE9 1.35 times, And YayaTemplate.
Test address: http://www.planeart.cn/demo/tmpl/tmpl.html
Final code of tmpl optimized version:
The Code is as follows:
/**
* Micro template engine tmpl 0.2
*
* 0.2 update:
* 1. Fixed the BUG of Escape Character and id judgment.
* 2. Discard inefficient with statements to increase the execution efficiency by up to 3.5 times.
* 3. Use random internal variables to prevent conflicts with template Variables
*
* @ Author John Resig, Tang Bin
* @ See http://ejohn.org/blog/javascript-micro-templating/
* @ Name tmpl
* @ Param {String} The template content or the element ID containing the template content
* @ Param {Object} additional data
* @ Return {String} the parsed Template
*
* @ Example
* Method 1: embed a template on the page
*