译文 | Angular中的AoT编译

最近我给-seed增加了对Ahead-of-Time(AoT)编译的支持 , 这引来了不少关于这个新特性的问题 。我们从下面这些话题开始来回答这些问题:
为什么需要编译?
这个问题的简短回答是:编译可以让应用达到更高层度的运行效率 , 我所说的效率 , 主要是指的性能提升 , 但也包括电池节能和节省流量 。
.x 有一个实现渲染和变化检测的很动态的方式 , 比如.x的编译器非常通用 , 它被设计为任何模板实现一系列的动态计算 , 虽然它在通常情况下运行的很好 , 但是JS虚拟机的动态特性让一些低层次的计算优化变得很困难 。由于js虚拟机无法理解那些我们作为脏检查的上下文对象(术语为scope)的形态 , 虚拟机的内联缓存常常不精确 , 这导致了运行效率的下降 。
译者:scope是.x中的一个重要对象 , 他是.x用于计算模板的上下文 。
+采用了一个不同的方式 。在给每个组件做渲染和变化检测的时候 , 它不再使用同一套逻辑 , 框架在运行时或者编译时会生成对js虚拟机友好的代码 。这些友好的代码可以让js虚拟机在属性访问的缓存 , 执行变化检查 , 进行渲染的逻辑执行的快的多 。
举个例子 , 看看下面的代码:
// ...Scope.prototype.$digest = function () {'use strict';var dirty, watcher, current, i;do {dirty = false;for (i = 0; i < this.$$watchers.length; i += 1) {watcher = this.$$watchers[i];current = this.$eval(watcher.exp);if (!Utils.equals(watcher.last, current)) {watcher.last = Utils.clone(current);dirty = true;watcher.fn(current);}}} while (dirty);for (i = 0; i < this.$$children.length; i += 1) {this.$$children[i].$digest();}};// ...
这个代码片段来自《轻量级.x实现》一文 。这些代码实现了对scope树做深度优先搜索 , 目的是为了寻找绑定数据的变化 , 这个方法对任何指令都生效 。这些代码显然比下面这些直接指定检查的代码慢:
// ...var currVal_6 = this.context.newName;if (import4.checkBinding(throwOnChange, this._expr_6, currVal_6)) {this._NgModel_5_5.model = currVal_6;if ((changes === null)) {(changes = {});}changes['model'] = new import7.SimpleChange(this._expr_6, currVal_6);this._expr_6 = currVal_6;}this.detectContentChildrenChanges(throwOnChange);// ...
译者:
《轻量级.x实现》的地址是
这里一下子提及了.x的好几个概念 , 包括scope , 数据绑定 , 指令 。不熟悉.x的同学理解起来费劲 , 想弄懂的话 , 自行搜索吧 。个人认为可以无视 , 毕竟这个文章的重点不是在这里 。你就认为+的处理方式比.x牛逼很多就好了 , 哈哈 。
上面代码包含了一个来自-seed的某个编译后的组件的代码 , 这些代码是由编译器生成的 , 包含了一个 l 方法的实现 。框架通过直接属性访问的方式读取了数据绑定中的某些值 , 并且采用了最高效的方式与新的值做比较 。一旦框架发现这些值发生了变化 , 它就立即更新只受这些数据波及的DOM元素 。