angular.js 中的静态与动态插值及其性能
static vs dynamic interpolations in angular.js and their performance
简而言之,我想问一下两者的区别:
A: {{ variable | filter }}
和
B: {{ 'static string' | filter }}
这些是我的问题:
- 是都叫插值还是只叫插值
A
?
A
使用 $interpolate
,而 B
使用 $parse
- 是这样吗? (基于另一个SO question)
- 性能差异是什么?当我使用
A
时,每次 variable
值更改时,模板都会更新(侦听变量的更改)。如果有大量插值,例如 A
,可能会因为大量监听模型而出现性能问题。 B
有什么不同吗?特别是,我正在考虑使用 http://angular-translate.github.io/,它使用 translate
过滤器。某处有一个全局变量,保存界面中使用的实际语言,当它发生变化时,所有使用 translate
过滤器的 B
插值将被更新。但它在底层是如何工作的,什么在听什么?语言变量值(保存在 angular 配置中)是否只有一个侦听器可以注册多个 i18n 标签,以便在语言更改时进行翻译?还是有多个听众?如果我有 500 {{ 'static string' | translate }}
个插值,它会因为听众而减慢我的应用程序吗?
如有错误,请指正。
都是插值。每当涉及 {{
和 }}
时(除非您当然更改了符号),包装的内容将通过插值服务。
如上所述,A
和 B
都将使用 $interpolate
服务。 $interpolate
服务使用 $parse
服务,因此 A
和 B
都将 "use" 这两种服务。
这些是将从 $interpolate
传递到 $parse
的确切字符串:
案例 A: variable | uppercase
案例 B: 'static string' | filter
两种情况下添加的观察者数量没有区别,因为正在观察的是节点的组合 nodeValue。
比如这两种情况下添加的观察者数量也没有区别:
<div>{{one}}</div>
<div>{{one}} {{two}}</div>
case A
和 B
之间的性能差异归结为用于获取表达式左侧的函数。
万一A
基本上就是:
function (locals, scope) {
return ((locals && locals.hasOwnProperty('variable')) ? locals : scope).variable;
}
如果 B
(其中 string
保存在 clojure 中并且具有 static string
的值:
function() { return string; }
两者在执行时间上的差异应该不会很明显(除非你有大量的插值)。
通常过滤器应该保持简单,因为它们可以执行多次。
在 AngularJS 1.3.0-rc.2 中过滤器默认是无状态的,这是一个主要的性能改进。
举个例子:
<div>{{ variable | uppercase }}</div>
当摘要循环运行时,它将检测 variable
的值并应用过滤器。下次摘要循环运行时 variable
的值可能没有改变。由于过滤器是无状态的,这意味着左侧的一个值应该始终从过滤器生成相同的值,因此它不必再次应用过滤器,而是可以使用上次应用过滤器时的缓存值。
再次简化了一些,但您可以阅读更多相关内容 here。
过滤器可以覆盖它并成为有状态的,Angular 翻译中的 translate
过滤器已经做到了。这是必需的,因为您可以更改语言运行时,并且 hello
的值显然不会在每种语言中转换为相同的值。
我不太了解Angular翻译一下它的性能,但我明天会仔细看看它并编辑我的答案。
简而言之,我想问一下两者的区别:
A: {{ variable | filter }}
和
B: {{ 'static string' | filter }}
这些是我的问题:
- 是都叫插值还是只叫插值
A
? A
使用$interpolate
,而B
使用$parse
- 是这样吗? (基于另一个SO question)- 性能差异是什么?当我使用
A
时,每次variable
值更改时,模板都会更新(侦听变量的更改)。如果有大量插值,例如A
,可能会因为大量监听模型而出现性能问题。B
有什么不同吗?特别是,我正在考虑使用 http://angular-translate.github.io/,它使用translate
过滤器。某处有一个全局变量,保存界面中使用的实际语言,当它发生变化时,所有使用translate
过滤器的B
插值将被更新。但它在底层是如何工作的,什么在听什么?语言变量值(保存在 angular 配置中)是否只有一个侦听器可以注册多个 i18n 标签,以便在语言更改时进行翻译?还是有多个听众?如果我有 500{{ 'static string' | translate }}
个插值,它会因为听众而减慢我的应用程序吗?
如有错误,请指正。
都是插值。每当涉及 {{
和 }}
时(除非您当然更改了符号),包装的内容将通过插值服务。
如上所述,A
和 B
都将使用 $interpolate
服务。 $interpolate
服务使用 $parse
服务,因此 A
和 B
都将 "use" 这两种服务。
这些是将从 $interpolate
传递到 $parse
的确切字符串:
案例 A: variable | uppercase
案例 B: 'static string' | filter
两种情况下添加的观察者数量没有区别,因为正在观察的是节点的组合 nodeValue。
比如这两种情况下添加的观察者数量也没有区别:
<div>{{one}}</div>
<div>{{one}} {{two}}</div>
case A
和 B
之间的性能差异归结为用于获取表达式左侧的函数。
万一A
基本上就是:
function (locals, scope) {
return ((locals && locals.hasOwnProperty('variable')) ? locals : scope).variable;
}
如果 B
(其中 string
保存在 clojure 中并且具有 static string
的值:
function() { return string; }
两者在执行时间上的差异应该不会很明显(除非你有大量的插值)。
通常过滤器应该保持简单,因为它们可以执行多次。
在 AngularJS 1.3.0-rc.2 中过滤器默认是无状态的,这是一个主要的性能改进。
举个例子:
<div>{{ variable | uppercase }}</div>
当摘要循环运行时,它将检测 variable
的值并应用过滤器。下次摘要循环运行时 variable
的值可能没有改变。由于过滤器是无状态的,这意味着左侧的一个值应该始终从过滤器生成相同的值,因此它不必再次应用过滤器,而是可以使用上次应用过滤器时的缓存值。
再次简化了一些,但您可以阅读更多相关内容 here。
过滤器可以覆盖它并成为有状态的,Angular 翻译中的 translate
过滤器已经做到了。这是必需的,因为您可以更改语言运行时,并且 hello
的值显然不会在每种语言中转换为相同的值。
我不太了解Angular翻译一下它的性能,但我明天会仔细看看它并编辑我的答案。