干货丨angular2 JIT and AOT
Posted 中兴开发者社区
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了干货丨angular2 JIT and AOT相关的知识,希望对你有一定的参考价值。
为什么需要编译
Angular应用中包含的组件、html模板
(比如:@Directive 链接:https://github.com/Directive
、@Component 链接:https://github.com/Component
@NgModule 链接:https://github.com/NgModule
@Pipe 链接:https://github.com/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
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和开发调试
参考知乎答案:https://www.zhihu.com/question/53434390
我们两个项目AOT和JIT对比效果:
项目A:
项目B:
懒加载
懒加载也叫延迟加载,即在需要的时候进行加载,随用随载
在单页应用中,如果没有应用懒加载,进入首页时会导致需要加载的内容过多,延时过长,不利于用户体验
运用懒加载将页面进行划分,按需加载页面,可以分担首页所承担的加载压力,减少加载用时
如果对首屏启动有更严格的要求,最好采用服务端渲染
angular2懒加载可以参考官方文档
链接:https://angular.cn/docs/ts/latest/guide/router.html#!#lazy-loading-route-config
摇树优化
作用:消除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摇树区别可以参考知乎上这个回答
链接:https://www.zhihu.com/question/41922432
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详细配置可参考这篇文章
链接:https://yq.aliyun.com/ziliao/111439
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/
以上是关于干货丨angular2 JIT and AOT的主要内容,如果未能解决你的问题,请参考以下文章