Angualr中的AOT(Ahead-of-Time Compilation)编译(一)

翻译 2017年01月06日 21:37:43

--------------------------------------------------------------------------------------------------------------------------------------------

最近学习Angular2的内容,国内资料较少,发现一篇对于AOT讲的特别好文章,以备自己学习回顾。

尝试翻译如下。如有任何版权相关问题,请联系。如有翻译错误或不准确的地方欢迎大家留言,我会积极修正。

非专业,不喜勿喷。

作者:Minko Gechev

原文链接:http://blog.mgechev.com/2016/08/14/ahead-of-time-compilation-angular-offline-precompilation/

--------------------------------------------------------------------------------------------------------------------------------------------

Angualr中的AOT(Ahead-of-Time Compilation)编译

作者写这篇文章的目的是因为该大牛为angular-seed (
关于angular-seed有仁兄已经写了博客,http://blog.csdn.net/ybdesire/article/details/50551486)框架添加了AOT,
导致有很多人提出了各种问题,然后作者详细解释了一下AOT的原理和用途。
主要有如下topic:
  • Angular中为什么需要编译?
  • 什么内容需要编译?
  • 如何进行编译?
  • 编译在什么时间点发生? Just-in-Time (JiT) vs Ahead-of-Time (AoT).
  • AOT有哪些优势?使用AOT我们能得到什么?
  • AOT编译是如何工作的,工作原理是什么?
  • 相对于JIT,使用AOT我们失去了哪些特性?

Angualr中为什么需要编译

简单来说:我们需要编译来达到更高效率的Angular程序。对于效率主要是指性能的改善,
但有时也带来带宽等方面的消耗。
AngularJS 1.x有渲染和变化检测的动态实现。例如,在AngularJS 1.x中的编译器是通用编译器。
它被设计用来执行任何模板的动态计算工作。虽然大多数情况下,它工作的特别好。因为动态特性,
导致JavaScript虚拟机(VM)只能进行较低层次的优化计算
由于VM不知道对象的结构,提供脏检查逻辑(即scope)的上下文,它的内联高速缓存得到了大量
的失误,从而减慢执行速度。

Angualr2和以上版本,使用了不同的实现方式,不再为每一个单独的组件使用相同的逻辑执行渲染和变化检测,
该框架runtime或build生成VM友好或者说VM更加容易识别和优化的代码。这使得JavaScript虚拟机
能够更加快速的访问缓存和执行变化检测/渲染。

请看如下例子:
// ...
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();
  }
};
// ...
上面代码来源于Angualr1.x的实现,上面我们在整个作用域树上进行深度优先搜索,寻找绑定的变化.。
这种方法将适用于任何指令。然而,与指令特定的代码相比,它明显运行速度较慢。
// ...
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);
// ...
上面这段代码来自于Angualr-seed项目,用来实现生成detectChangesInternal的方法。它使用直接属性访问
获取单个绑定的值,并使用最有效的方法将它们与新值进行比较。一旦发现它们的值是不同的,它只更新
DOM元素的影响。

通过回答”为什么需要编译?“我们同时回答了“什么内容需要编译”。我们希望编译组件的模板(templates)
成为JavaScript的classes。这些类(classes)提供在绑定过程中检测变化的方法和渲染用户接口的方法。
通过这种方法,我们就不需要同底层平台存在联系(除了markup格式)。换句话说,通过实现不同的
渲染器(renderer),我们能够不需要任何代码修改使用同样AOT编译后的模块进行渲染。
这样的模块(component)能够被NativeScript渲染。例如:渲染器能够尽可能的理解传递的参数。

Just-in-Time (JiT) vs Ahead-of-Time (AoT)

这一节同时包含编译在什么时间点发生?”的答案。
Anuglar的编译器比较cool的是可以在runtime(如用户的browser中)引入也可以build时点
(作为build流程的一部分)引入。
由于Angualr的便携性,我们可以在任何Javascript VM上运行我们的framework。那么我们
为什么不让Angular的编译器同时运行在browser和node上呢?

JIT编译中的事件流(event flow)

没有AOT时我们典型的开发流程:
  • 使用TypeScript开发Angular应用
  • 使用Tsc编译我们的应用
  • 打包(Bundling
  • 压缩最小化(Minification
  • 发布(Deployment
当用户打开浏览器查看我们已经部署的应用时,他将经历如下步骤(不包含内容安全策略(CSP)):
  • 下载JavaScript资源(assets)
  • Angular渲染页面(Angular bootstraps
  • Augular进行JIT编译过程,生成我们每个模块的JavaScript。
  • 应用被渲染(rendered)完成,展示给用户

AOT编译中的事件流(event flow)

使用AOT,经历如下步骤:

  • 使用TypeScript开发Angular应用
  • 使用ngc编译我们的应用.
    • 使用Angular编译器将模板(templates)编译成通常的TypeScript。
    • 将TypeScript编译JavaScript.
  • 打包(Bundling
  • 压缩最小化(Minification
  • 发布(Deployment

尽快看起来我们有更多的编译过程,但是对于用户来说,他只需要经历如下步骤:

  • 下载JavaScript资源(assets)
  • Angular渲染页面(Angular bootstraps
  • 应用被渲染(rendered)完成,展示给用户

我们可以看到对于用户来说,AOT编译使得第三部消失了。这就意味着更好更快的用户体验(UX)。
并且我们已经有软件支持自动编译了。NB如angular-seedangular-cli

综上所述,我们可以看出Angualr中JIT同AOT编译的主要不同点:

  • 编译选择的位置不同

  • JIT生成JavaScript(TypeScript没太关注这部分因为代码需要在浏览器被编译为JavaScript)。
    AoT生成TypeScript.

下一遍将更加深入的分析AOT,敬请期待。




相关文章推荐

AOT/JNI/Vala 的比较

转自:http://en.wikipedia.org/wiki/AOT_compiler An ahead-of-time (AOT) compiler is a compiler that ...
  • yasi_xi
  • yasi_xi
  • 2013年08月11日 12:01
  • 2353

Angular2 AoT编译以及Rollup摇树优化

1.先使用Angular-cli生成一个新的项目 ng new angular2-aot-rollup-seed2.创建完成之后,会自动生成一个根模块AppModule,为了说明问题,使用 ng g ...

Angular2 AOT编译

1、npm install @angular/compiler-cli @angular/platform-server --save 2、新建 tsconfig-aot.json { "...

依赖链接器最小化编译时间(Abusing the Linker to Minimize Compilation Time)

Abstract In this article, I will describe a technique that reduces coupling between an object tha...

Free Speech Concerns Ahead of Meeting With Muslim Nations on Religious Tolerance

Free Speech Concerns Ahead of Meeting With Muslim Nations on Religious Tolerance,sac hermes pas cher...

systematic compilation of

  • 2011年10月29日 16:50
  • 1.68MB
  • 下载

ORA-600 [2662] Block SCN is ahead of Current SCN 处理方法 说明

一. ORA-600[2662] 说明 关于ORA-600[2662]的的错误,之前的blog 有说明:        ORA-600[2662] "Block SCN is ahea...

Compilation unit name must end with .java, or one of the registered Java-like extensions (a error分析)

今天在改动项目代码的时候, 进行保存的代码, 保存不成功, tomcat报错:    Save Failed Compilation unit name must end with .java,...
  • luoww1
  • luoww1
  • 2014年02月25日 10:39
  • 1225
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Angualr中的AOT(Ahead-of-Time Compilation)编译(一)
举报原因:
原因补充:

(最多只允许输入30个字)