【问题标题】:Most efficient way for rendering string templates using javascript使用 javascript 呈现字符串模板的最有效方法
【发布时间】:2015-02-22 16:08:35
【问题描述】:

我需要在我的 node.js 应用程序中呈现一个模板字符串。我不想使用 Jade、Ejs、React 或类似的库。出于各种原因,我想使用纯 JavaScript 来做到这一点。我想知道哪种方法最有效,我想了两种方法。

一个示例模板字符串可以是:

<html>
<head></head>

 <body>
   <div>{{data1}}</div>
   <span>{{data2}}</span>
 </body> 

</html>

我需要用一些数据替换{{data1}}{{data2}}。 我想知道在使用正则表达式和多次调用的性能方面,这是否是一个更好的解决方案:

templateString.replace(/{{data1}}/, data)

或循环字符串的每个字符并以下列方式在 for 循环中执行渲染,而不使用正则表达式:

for(i = 0; i &lt; templateString.length; i++) {//binding logic}

我不知道replace 方法在较低级别是如何工作的,所以我想知道是否多次执行它比循环一次我的字符串的所有字符在性能上更差。

感谢您的建议!

【问题讨论】:

  • 我猜 for 循环在找到匹配项时会稍微快一些,但你仍然需要替换一些东西,而且对于这样的事情使用正则表达式要简单得多,所以这就是我会使用的,或者不是真的,我会使用 EJS 而不是重新发明轮子,它正是使用正则表达式来做到这一点的。
  • 你为什么不从 jquery tmpl 中屠宰它?修剪(标记) .replace(/([\\'])/g, "\\$1") .replace(/[\r\t\n]/g, " ") .replace(/\$\{ ([^\}]*)\}/g, "{{= $1}}") .replace(/\{\{(\/?)(\w+|.)(?:(((?:[ ^\}]|\}(?!\}))*?)?))?(?:\s+(.*?)?)?((((?:[^\}]|\}(? !\}))*?)))?\s*\}\}/g, 函数(all, slash, type, fnargs, target, parens,
  • 因为我认为每次替换都应该在后台循环整个字符串以找到匹配项,并且我想要一种更快的方法来循环整个字符串一次! @MhammadChehab
  • 好吧,我以为你想要一些又快又脏的东西! @莫里斯达

标签: javascript regex node.js performance rendering


【解决方案1】:

这是我用于“模板”的字符串扩展,不需要正则表达式。也许它对你有用。它应该比正则表达式/替换更快,参见this test

String.prototype.format = format;

var str = ('<div>This is {0}</div><span>And here we have {1}</span>' +
           '<span>{2} I repeat {0} or {1}</span>').replace(/</g,'&lt;');

log('<b>the original string</b>: ', str);
log('<b>the formatted string</b>: ', 
     str.format('<i>data1</i>', '<i>data2</i>','&nbsp;--'));
log('<b>back to html</b>: ',
     str.replace(/&lt;/g, '<')
     .format('<i>data1</i>', '<i>data2</i>','&nbsp;--'));

log('or just ... hello {0}'.format('world!'));

function log() {
  var args = Array.apply([], {length: arguments.length})
             .map( function (v, i) { return this[i]; }, arguments);
  document.querySelector('#result').innerHTML += '<p>{0}</p>'.format(args.join(''));
  
}

// this function parses tokens with pattern {\d+} within a string
function format() {
  return function (text, args) {
    var len       = text.length,
        index     = 0,
        parsed    = '',
        currToken = ''
    ;
    while (index < len) {
      if (text[index] === '{' && !isNaN( parseInt(text[index + 1],10) ) ) {
                index += 1;
                currToken = '';
                var istoken = true;
                while (text[index] !==  '}' ) {
                  if ( isNaN( parseInt(text[index],10) ) ) {
                    istoken = false;
                    break;
                  }
                  currToken += text[index];
                  index += 1;
                }
                parsed += istoken && args[+currToken]
                          || '{' + currToken + (text[index] || '');
      }else {
        parsed += text[index];
      }
      index += 1;
    }
    return parsed;
  }(this, arguments);
};
body {
  font: 12px normal verdana, arial;
}
&lt;div id="result"&gt;&lt;/div&gt;

【讨论】:

    【解决方案2】:

    解决此问题的常用方法是在 replace 回调中处理占位符:

     markup = template.replace(/{{(.+?)}}/g, function(_, placeholder) {
          // return data for the placeholder
     });
    

    【讨论】:

      【解决方案3】:

      更简单的是使用 JavaScript 字符串插值

      const resultTemplate = (data) => `
      <div>${he.encode(data.param)}</div>
      `
      
      const html = resultTemplate(data);
      

      注意:我使用的编码:https://www.npmjs.com/package/he

      或者如果您需要更多: https://ejs.co/

      【讨论】:

        猜你喜欢
        • 2021-12-15
        • 2018-06-10
        • 2013-05-23
        • 1970-01-01
        • 1970-01-01
        • 2010-09-06
        • 2012-04-12
        • 2016-07-28
        相关资源
        最近更新 更多