Nodejs 让 ejs 更加快 | Let ejs faster with `options._with = false`

Nodejs 让 ejs 更加快 | Let ejs faster with options._with = false

今天看 ejs 源代码的时候,发现 with 是可以设置为 false 的。 根据 从tenjin到nTenjin的几点性能优化方法 的优化经验, 不使用 with 会有很大的性能提高。

ejs 普通版使用方式

默认地,ejs 都会开启 with 模式:

var TPL_WITH_TRUE = '\
<% if (user) { %>\
  <h2>with_true: <%= user.name %></h2>\
<% } %>';

var render = ejs.compile(TPL_WITH_TRUE); var s = render({user: {name: ‘fengmk2’}}); console.log(’_with: true’, s);

options._with = false 强制关闭 with 模式

var TPL_WITH_FALSE = '\
<% if (locals.user) { %>\
  <h2>with_false: <%= locals.user.name %></h2>\
<% } %>';

var render = ejs.compile(TPL_WITH_FALSE, {_with: false});
var s = render({user: {name: 'fengmk2'}});
console.log('_with: false', s);

对比 ejs 生成的两个模板方法

  • 开启 with
try {
var buf = [];
with (locals || {}) { (function(){ 
 buf.push('');__stack.lineno=1; if (user) { ; buf.push('  <h2>with_true: ', escape((__stack.lineno=1,  user.name )), '</h2>');__stack.lineno=1; } ; buf.push(''); })();
} 
return buf.join('');
} catch (err) {
  rethrow(err, __stack.input, __stack.filename, __stack.lineno);
}
  • 关闭 with
try {
var buf = [];
 buf.push('');__stack.lineno=1; if (locals.user) { ; buf.push('  <h2>with_false: ', escape((__stack.lineno=1,  locals.user.name )), '</h2>');__stack.lineno=1; } ; buf.push('');
return buf.join('');
} catch (err) {
  rethrow(err, __stack.input, __stack.filename, __stack.lineno);
}

Benchmark 性能测试

通过 options_with.js 的测试结果可以看到, 不使用 with 差不多有 4X 的性能提高。

使用 {_with: false} 性能就提高了!就这么简单!

$ node options_with.js

_with: false <h2>with_false: fengmk2</h2> _with: true <h2>with_true: fengmk2</h2> options._with = false x 821,470 ops/sec ±3.55% (85 runs sampled) options._with = true x 268,084 ops/sec ±7.05% (87 runs sampled) Fastest is options._with = false

有爱

^_^ 希望本文对你有用。

原文: http://fengmk2.github.io/benchmark/ejs/with_false_better_than_true.html


13 回复

Nodejs 让 ejs 更加快 | Let ejs faster with options._with = false

今天看 ejs 源代码的时候,发现 with 是可以设置为 false 的。根据 从tenjin到nTenjin的几点性能优化方法 的优化经验,不使用 with 会有很大的性能提高。

ejs 普通版使用方式

默认地,ejs 都会开启 with 模式:

var TPL_WITH_TRUE = `
<% if (user) { %>
  <h2>with_true: <%= user.name %></h2>
<% } %>
`;

var render = ejs.compile(TPL_WITH_TRUE);
var s = render({user: {name: 'fengmk2'}});
console.log('_with: true', s);

options._with = false 强制关闭 with 模式

var TPL_WITH_FALSE = `
<% if (locals.user) { %>
  <h2>with_false: <%= locals.user.name %></h2>
<% } %>
`;

var render = ejs.compile(TPL_WITH_FALSE, {_with: false});
var s = render({user: {name: 'fengmk2'}});
console.log('_with: false', s);

对比 ejs 生成的两个模板方法

  • 开启 with

    try {
      var buf = [];
      with (locals || {}) { (function(){
        buf.push('');
        __stack.lineno = 1;
        if (user) {
          buf.push('  <h2>with_true: ', escape((__stack.lineno = 1, user.name)), '</h2>');
          __stack.lineno = 1;
        }
        buf.push('');
      })(); }
      return buf.join('');
    } catch (err) {
      rethrow(err, __stack.input, __stack.filename, __stack.lineno);
    }
    
  • 关闭 with

    try {
      var buf = [];
      buf.push('');
      __stack.lineno = 1;
      if (locals.user) {
        buf.push('  <h2>with_false: ', escape((__stack.lineno = 1, locals.user.name)), '</h2>');
        __stack.lineno = 1;
      }
      buf.push('');
      return buf.join('');
    } catch (err) {
      rethrow(err, __stack.input, __stack.filename, __stack.lineno);
    }
    

Benchmark 性能测试

通过 options_with.js 的测试结果可以看到,不使用 with 差不多有 4X 的性能提高。

$ node options_with.js

_with: false   <h2>with_false: fengmk2</h2>
_with: true   <h2>with_true: fengmk2</h2>
options._with = false x 821,470 ops/sec ±3.55% (85 runs sampled)
options._with = true x 268,084 ops/sec ±7.05% (87 runs sampled)
Fastest is options._with = false

有爱

^_^ 希望本文对你有用。

原文: http://fengmk2.github.io/benchmark/ejs/with_false_better_than_true.html


通过这些示例代码,我们可以看到在编译 EJS 模板时,通过设置 options._with = false 可以显著提高渲染性能。希望这些信息对你的项目有所帮助!


今天在http://ectjs.com/看到模板引擎性能对比没使用with速度快了不少

把模板编译成静态函数靠不靠谱?

自从写了jade之后看到<% %> 就头晕目眩

如果你的模板文件是动态更新的,那么就需要重新编译一次。

收藏了

suqian大大文章看了果然收益啊~学习了

我想弱弱的问一下…这个with 的作用是?

我的都是基础性的,看你的都是高深啊

今天重新测试了一下 https://github.com/fengmk2/fengmk2.github.com/blob/master/benchmark/ejs/options_with.js 的性能 环境 node v2.3.0, v8 4.2.77.20

结果:

_with: false   <h2>with_false: fengmk2</h2>
_with: true   <h2>with_true: fengmk2</h2>
options._with = false x 336,185 ops/sec ±1.80% (83 runs sampled)
options._with = true x 249,998 ops/sec ±1.27% (87 runs sampled)
Fastest is options._with = false

_with: false 的结果竟然比帖子里的慢那么多,好奇怪。可能 ejs 版本不同了。

在使用 EJS 渲染模板时,可以通过设置 options._with = false 来提升渲染性能。默认情况下,EJS 会使用 with 语句来简化对局部变量的访问,但这可能会带来一些性能开销。禁用 with 可以避免这种开销,从而提高渲染速度。

示例代码

开启 with 模式(默认)

const ejs = require('ejs');

const TPL_WITH_TRUE = `
<%- if (user) { -%>
  <h2>with_true: <%= user.name %></h2>
<%- } -%>
`;

const renderWithTrue = ejs.compile(TPL_WITH_TRUE);
const resultWithTrue = renderWithTrue({user: {name: 'fengmk2'}});
console.log('with: true', resultWithTrue);

关闭 with 模式

const ejs = require('ejs');

const TPL_WITH_FALSE = `
<%- if (locals.user) { -%>
  <h2>with_false: <%= locals.user.name %></h2>
<%- } -%>
`;

const renderWithFalse = ejs.compile(TPL_WITH_FALSE, {_with: false});
const resultWithFalse = renderWithFalse({user: {name: 'fengmk2'}});
console.log('with: false', resultWithFalse);

性能对比

通过性能测试可以看到,禁用 with 模式后,渲染速度大约提升了 4 倍。

$ node options_with.js

_with: false   <h2>with_false: fengmk2</h2>
_with: true   <h2>with_true: fengmk2</h2>
options._with = false x 821,470 ops/sec ±3.55% (85 runs sampled)
options._with = true x 268,084 ops/sec ±7.05% (87 runs sampled)
Fastest is options._with = false

结论

通过设置 options._with = false,你可以显著提高 EJS 模板的渲染性能。这在处理大量数据或高并发场景下尤其有用。

回到顶部