angular2 JIT and AOT

为什么需要编译

Angular应用中包含的组件、HTML模板(比如:@Directive、@Component、@NgModule、@Pipe)很多都是JS VM无法解析的,所以在浏览器渲染应用之前,组件和模板必须要被Angular编译器转换为可以执行的JavaScript。

angular2编译模式

在 Angular 2 中有两种编译模式:

  • JIT - Just-In-Time
  • AOT - Ahead-Of-Time

JIT事件流:
开发流程:

  • 使用TypeScript开发Angular应用(此处以ts举例)
  • tsc编译
  • 构建
  • 压缩
  • 部署

用户打开浏览器,他将经历以下步骤 (没有严格的CSP):

  • 下载所有的JavaScript资源
  • 启动Angular
  • 通过JIT 编译处理生产js代码
  • 渲染应用


AOT事件流:

  • 使用Typescript开发Angular 应用
  • 使用 ngc来编译应用(目前的ngc编译报错还不太好用,angular团队正在用tsc的方式进行优化,据说很快就会发包)
  • 模板会被ngc编译成TypeScript文件(通常是)
  • TypeScript编译为JavaScript代码
  • 构建
  • 压缩
  • 部署

用户打开浏览器,他将经历以下步骤:

  • 下载所有的资源
  • 启动Angular
  • 渲染应用


aot将compile的过程放在应用部署前,所以浏览器端承载的工作量就会大幅度减少,相应的页面加载时间也会大幅度减少,这也就意味着更快更好的用户体验。

JIT vs AOT:

编译方式 编译时机 构建速度 打包大小 性能/渲染速度 模板错误检查时间 安全性
JIT app运行时 - - app运行时
AOT app构建阶段 - 更快 app构建阶段

AOT优势:

  • 渲染得更快
    使用AOT,浏览器下载预编译版本的应用程序。 浏览器直接加载运行代码,所以它可以立即渲染该应用,而不用等应用完成首次编译,我们两个项目AOT加载速度相比JIT有3-5倍的提高

  • 需要的异步请求更少
    编译器把外部HTML模板和CSS样式表内联到了该应用的JavaScript中。 消除了用来下载那些源文件的Ajax请求。

  • 需要下载的Angular框架体积更小
    如果应用已经编译过了,自然不需要再下载Angular编译器了。 该编译器差不多占了Angular自身体积的一半儿,所以,省略它可以显著减小应用的体积。但是angular采用 Code Generation 的方式,生成的 ts/js 代码肯定是会比原来的 html 的文件大小要大的,所以在应用足够大(模版足够多)的情况下 AOT 的大小是可以反超 JIT 的大小的,很不幸,我们项目就是如此

  • 提早检测模板错误
    AOT编译器在构建过程中检测和报告模板绑定错误,避免用户遇到这些错误。

  • 更安全
    AOT编译远在HTML模版和组件被服务到客户端之前,将它们编译到JavaScript文件。没有模版可以阅读,没有高风险客户端HTML或JavaScript可利用,所以注入攻击的机会较少

JIT优势:
编译时间短,除非确实有动态组件的需求,否则jit唯一的优势就是能用来做在线 Demo和开发调试,参考知乎答案

我们两个项目AOT和JIT对比效果:
项目A:

编译方式 打包大小 渲染速度
JIT 5.86M
AOT 10.8M

项目B:

编译方式 打包大小 渲染速度
JIT 4.12M
AOT 6.21M

官方在View 和 DI 上了 View Engine 后aot编译后没有太多静态文件了,目前aot的编译大小已经低于jit(2017/10/19更新)

懒加载

懒加载也叫延迟加载,即在需要的时候进行加载,随用随载

在单页面应用中,如果没有应用懒加载,进入首页时会导致需要加载的内容过多,延时过长,不利于用户体验

运用懒加载将页面进行划分,按需加载页面,可以分担首页所承担的加载压力,减少加载用时

如果对首屏启动有更严格的要求,最好采用服务端渲染

angular2懒加载可以参考官方文档

摇树优化:

作用:消除unused code
原理:通过跟踪import和export语句进行静态分析,排除那些被导出过但又从未被导入的代码(ES6 modules 的静态特性)

目前大部分工具只能对ES2015模块摇树,因为那里有import和export语句,所以需要将ts编译成es2015(通过tsconfig配置实现)

  • 摇树优化详细介绍可以参考angular官方文档
  • gulp+rollup摇树优化可以参考angular-seed
  • webpack2自带了tree-shaking,配置可以参考工程angular-starter
  • angular-cli搭建工程:推荐使用,已经帮你集成,不需要再去繁琐配置各种打包摇树优化等

webpack2的摇树和rollup摇树区别可以参考知乎上这个回答

webpack2注意事项

项目目前使用的是webpack2,总结了下开发过程中遇到的坑:

  • ngc-webpack不要设置resourceOverride,否则打包后的图片url等会有问题
  • "JavaScript heap out of memory"可以通过设置node参数 node --max_old_space_size=4096(如不管用,参数可以设置更大试试)
  • typescript使用2.0以上版本(摇树需要)
  • 使用awesome-typescript-loader包的2.x及以上版本(摇树需要)
  • 保证我们的应用和Angular2库代码在同一个位置(摇树需要)
  • UglifyJsPlugin压缩代码, Webpack2可以删除Bundle中未使用的引用代码,但不会从Bundle中删除未使用的代码,在这种情况下就需要使用UglifyJsPlugin,它能够智能的移除未使用的代码
  • 使用AOT在build时,浏览器渲染快,但是在模板足够多的情况下大于jit打包体积,配合gzip使用最佳,项目使用的是nginx,gzip在nginx详细配置可参考这篇文章

AOT注意事项

由于AoT的特性,部分在JIT模式下可用的方法在AoT下是不可行或者官方不建议的,开发代码的童鞋在aot模式下需要注意额外注意这些情况,github上8000+star的angular-starter工程总结如下(英文捉急,就不在这献丑翻译了):

  • Don’t use require statements for your templates or styles, use styleUrls and templateUrls, the angular2-template-loader plugin will change it to require at build time.
  • Don’t use default exports.
  • Don’t use form.controls.controlName, use form.get(‘controlName’)
  • Don’t use control.errors?.someError, use control.hasError(‘someError’)
  • Don’t use functions in your providers, routes or declarations, export a function and then reference that function name
  • @Inputs, @Outputs, View or Content Child(ren), Hostbindings, and any field you use from the template or annotate for Angular should be public

补充一些我们项目开发过程中遇到的问题,O(∩_∩)O 都是开发时代码不规范埋下的坑:

  • 定义的函数传参必须匹配
  • 等和非等判断类型必须一致
  • 未在ts定义的变量不要在html模板中使用

总结

推荐大家在dev时使用jit可以提高开发调试效率,在prod时使用aot

参考:
http://blog.mgechev.com/2016/08/14/ahead-of-time-compilation-angular-offline-precompilation/
http://blog.rangle.io/optimize-your-angular2-application-with-tree-shaking/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 中文翻译 ng help ng build 构建您的应用程序并将其放入输出路径(dist /默认情况下)。 别名:...
    4ea0af17fd67阅读 2,021评论 0 0
  • 因个人精力有限,暂停简书的维护,欢迎大家关注我的知乎https://www.zhihu.com/people/we...
    尾尾阅读 1,173评论 3 13
  • AOT是Ahead of Time compile 的缩写,顾名思义提前编译。 关于AOT的好处,在这里就不一一细...
    lolivialucky阅读 5,696评论 0 4
  • 一个智慧的父母一定要学会在孩子面前示弱,让孩子具有心理优势,让孩子在你面前体验赢的感觉,以此推动孩子建立自信体系。...
    善默勤容阅读 364评论 0 0
  • 早起 人们都说坚持过一周,一切都会变得简单起来。 晨间日记: 喝水+早餐 参加早会 整理赶集收到的简历 准备备用金...
    理想几块钱一斤阅读 195评论 0 0