深色模式
Angular 8 于 2019 年 5 月 28 日正式发布。Ivy 以 opt-in 方式进入预览,差异化加载默认开启。实际体验了一个月,来讲讲升级经验和各项功能的实际效果。
差异化加载:默认开启
构建后的产物变化
# Angular 7 (老)
dist/
main.js # 所有浏览器的 ES5 包
# Angular 8 (新)
dist/
main-es2015.js # 现代浏览器(Chrome 61+, Firefox 60+)
main-es5.js # 老浏览器(IE11 备用)自动生成的 HTML:
html
<script type="module" src="main-es2015.js"></script>
<script nomodule src="main-es5.js"></script>实测数据(操个中等规模 Angular 项目):
- 现代浏览器下 main bundle 减小 20%+
- 运行时解析速度明显提升
Ivy opt-in 使用过程
json
// tsconfig.app.json
{
"angularCompilerOptions": {
"enableIvy": true
}
}开启 Ivy 后的变化:
构建输出:组件的 factory 和 渲染代码直接生成到组件文件旁边,而不是单独的 ngfactory 文件。
typescript
// 之前:会生成 user.component.ngfactory.ts
// Ivy 之后:部署图 (instructions) 内嵌在组件类里
static ɵcmp = defineComponent({...}); // 编译器生成ngcc 兼容编译器
Ivy 需要所有依赖也是 Ivy 格式。对于还没用 Ivy 编译的第三方库,Angular 提供了 ngcc(Angular Compatibility Compiler)在安装时自动转换:
bash
# 安装依赖后自动运行 ngcc
# 也可手动执行
node_modules/.bin/ngccWeb Worker CLI 支持
bash
ng generate web-worker heavy-task
# 生成 src/app/heavy-task.worker.tstypescript
// heavy-task.worker.ts
onmessage = ({ data }) => {
// 这里的计算不会阻塞主线程
const result = data.reduce((sum: number, n: number) => sum + n * n, 0);
postMessage(result);
};
// component.ts 中使用
export class AppComponent {
compute(data: number[]) {
const worker = new Worker("./heavy-task.worker", { type: "module" });
worker.onmessage = ({ data: result }) => {
this.result = result;
};
worker.postMessage(data);
}
}升级建议
bash
# 升级命令
ng update @angular/cli @angular/core
# CLI 会自动将字符串 loadChildren 转成 import() 语法
# 如果用了 ViewChild(‘...’),提示需要加 { static: true/false }总结
Angular 8 的差异化加载是对现有项目影响最大的运行时改进。Ivy 还在预览阶段,但已可以开始梳理自己项目的 ViewChild 静态查询和惰性加载写法,为 Angular 9 的 Ivy 默认开启做好准备。