Angular性能优化
基础
一些好的的性能优化基础提高渲染。
ngFor加trackBy
<ul>
<li *ngFor = "let item of arr;index as i;trackBy:trackByFn">
{{item.id}}
</li>
</ul>
少重复运算,多使用存Pipe管道
在业务逻辑中,一般情况使用管道轻松,因为管道中执行一次,有缓存。但是如果使用自定义函数运算就会执行多次。
少监听DOM:避免频繁触发变更检测
像click、mousemove这些时间,少做全局监听,ngDoCheck里面你会发现会类似冒泡的方式向上触发多次。
触发Angular变更检测
- 监听浏览器事件click、mouseover、keyup等
- setTimeout()和setInterval()
- Ajax请求
——默认情况下每一个监听事件,都会触发一次全局变更检测
如何监听事件不触发变更检测
- runOutsideAngular
- onPush
this.NgZone.runOutsideAngular(()=>{
this.Renderer2.listen(document,"click",this.fun())
})
减少变更检测:OnPush策略
——仅在以下情况变更检测:
OnPush:只有当组件的@Input属性发生变化,或者组件内部事件,才能调用本组件的变更检测。
- @Input输入引入发生变更。
- 事件起源于组件或其子元素。
- 我们显式运行更改检测:ChangDetectorRef.markForCheck()
- 使用async管道,它内部调用了ChangeDetectorRef.markForCheck()
组件传值@Input的变化监听
IterableDiffer、IterableDiffers、SimpleChanges(监听引用是否变化)
可以看看Immutable.js-不可变数据集合
Angular生命周期优化
执行一次:ngOnInit、ngAfterContentInit、ngAfterViewInit、ngOnDestory
执行多次:ngDoCheck、ngOnChanges、ngAfterContentChecked、ngAfterViewInit
- 请不要在生命周期钩子里面实现复杂的逻辑,尤其是上面四个会被反复执行的钩子,否则会造成页面卡顿。
- DoCheck是最高频繁的,尽量避免复杂逻辑。
- ngOnInit在绘制之前,ngAfterVIewChecked在绘制之后,日志、发送网络请求等,大家习惯性写在constructer/ngOnInit,实质上延误了绘制。
- 无关绘制的逻辑,建议写在ngAfterViewChecked
预加载和懒加载
- 应用在启动时,有些模板可能根本就用不上,比如在一个商场系统中,用户打开首页时,只需要向用户展示商品,支付模块此时根本没用,因此对于支付模块就可以使用懒加载。
- 缺点:懒加载还是不能解决的是,如果某个懒加载的模块体积过大,当加载时还是可能发生加载速度慢的情况,用户的页面被阻塞,体验下降。
- 当应用启动后,后续功能可能会被使用到,因此在用户可以使用基础的功能后,再去加载可能使用到的模块,比如前述中的支付模块。这样一旦用户需要对某个商品付费时,支付模块可以立即使用而无需等待。
- 通过预加载,可以弥补懒加载中的缺点,基本功能可用后在后台加载那些体积较大,加载耗时较长的模块。