angular怎么进行性能优化


这篇“angular怎么进行性能优化”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“angular怎么进行性能优化”文章吧。什么是页面流畅度?页面流畅度是通过帧率 FPS(Frames Per Second – 每秒传输帧数)判定的,一般主流的浏览器屏幕刷新率都在 60Hz(每秒刷新60次),最优的帧率免费云主机域名在 60 FPS,帧率越高,页面就越流畅,60Hz意味着每隔16.6ms会刷新一次显示屏,也就是每一次渲染页面需要在16.6ms内完成,否则就会导致页面失帧,出现卡顿现象。根因在于:浏览器中的 JavaScript 执行和页面渲染会相互阻塞。在 Chrome 的 devtools 中我们可以执行 Cmd+Shift+P 输入 show fps 来快速打开 fps 面板,如下图所示:通过观察 FPS 面板,我们可以很方便的对当前页面的流畅度进行监控1 影响页面性能的因素页面交互是否流畅,在于页面响应是否流畅,而页面响应其本质上就是把页面状态的变更重新渲染到页面上的过程。页面响应过程大致如下:一般情况Event Handler事件处理逻辑不会消耗太多时间,所以影响angular性能的因素主要在于异步事件触发变更检测
一般情况Event Handler事件处理逻辑不会消耗太多时间,所以影响angular性能的因素主要在于异步事件触发和变更检测。对angular来说,页面渲染的过程就是变更检测的过程,可以理解为angular的变更检测要在16.6ms内完成才不会导致页面失帧、卡顿。可以从以下三方面优化页面响应的性能。(1)对于触发事件阶段,可以减少异步事件的触发,来减少整体的变更检测次数和重新渲染;(2)对于 Event Handler 执行逻辑阶段,可以通过优化复杂代码逻辑来减少执行时间;(3)对于 Change Detection 检测数据绑定并更新 DOM 阶段,可以减少变更检测模板数据的计算次数来减少渲染时间;对于(2)Event Handler要具体问题具体分析,不做讨论,主要针对(1)(3)进行优化2 优化方案2.1 减少异步事件触发Angular在默认变更检测模式下,异步事件会触发全局的变更检测,因此,减少异步事件的触发会大大的提升angular的性能。异步事件包括Macro Task(宏任务)事件和Micro Task微任务事件对异步事件的优化主要是针对document的监听事件。比如document上的click、mouseup、mousemove…等监听事件。监听事件场景:Renderer2.listen(document, …)fromEvent(document,…)document.addEventListener(…)dom监听事件,在不需要触发的时候一定要移除。举例:[pop]提示框指令使用场景:表格列筛选,点击图标以外的地方,或者页面滚动,列筛选弹框隐藏以前的做法是直接在pop指令里监听document的click事件和scroll事件,这样有个弊端就是提示框未显示,但依然存在监听事件,很不合理。合理的解决方案:当提示框显示的时候才去监听click和scroll事件,隐藏的时候就移除监听事件。对于频繁触发的dom监听事件,可以使用rjx的操作符对事件进行优化。详情参考Rjx操作符。RxJS Marbles。2.2 变更检测什么是变更检测?要理解变更检测,我们可以从变更检测的目标寻找答案。angular变更检测目标,是让模型(TypeScript代码)与模板(HTML)保持同步。因此,变更检测可以理解为:检测模型变更的同时,更新模板( DOM 变更检测流程是什么?通过在组件树中按照自顶向下的顺序执行变更检测,也就是先对父组件执行变更检测,再对子组件进行变更检测。首先检查父组件的数据变更,然后更新父组件模板,在更新模板的时候遇到子组件,会去更新子组件上绑定的值,然后进入子组件,看@Input输入值的索引是否改变,如果改变就将该子组件标记为dirty,也就是后续需要变更检测的,标记完子组件之后,继续更新父组件中子组件后面的模板,父组件模板全部更新完之后再去对子组件做变更检测。2.2.1 angular变更检测原理在默认变更检测default模式下,异步事件触发Angular的变更检测的原理是 angular通过使用Zone.js处理异步事件时调用了ApplicationRef 的tick()方法从根组件到子组件执行变更检测。 Angular 应用初始化过程中,实例化了一个zone (NgZone),然后将所有逻辑都跑在该对象的 _inner 对象中。Zone.js实现了以下几个类:Zone类,JavaScript 事件的执行环境,和线程一样,它们可以带一些数据,并且可能拥有父子 zone。ZoneTask类,包装后的异步事件,这些 task 有三种子类:
MicroTask,由 Promise 创建。MacroTask,由 setTimeout 等创建。EventTask,由 addEventListener 等创建,比如dom事件。ZoneSpec对象,创建一个 ngZone 时给它提供的参数,有三个可以触发检测的钩子:
onInvoke,调用某个回调函数时触发的钩子。onInvokeTask,ZoneTask 被触发时触发的钩子,比如 setTimeout 到时。onHasTask,检测到有或无 ZoneTask 时触发的钩子(即对第一个 schedule 的 zone 和最后一个 invoke 或 cancel 的 task 触发)。ZoneDelegate类,负责调用钩子。检测过程原理大概如下:用户操作触发异步事件(比如:dom事件,接口请求…)=> ZoneTask类处理事件。invokeTask()函数中调用zone的runTask()方法,在runTask方法中,zone通过_zoneDelegate实例属性,调用ZoneSpec的钩子=> ZoneSpec的三个钩子(onInvokeTask、onInvoke、onHasTask)钩子里通过checkStable()函数触发zone.onMicrotaskEmpty.emit(null)通知=> 根组件监听onMicrotaskEmpty后调用tick(),tick方法中调用 detectChanges()从根组件开始检测=> refreshView()调用executeTemplate()executeTemplate方法中调用templateFn()更新模板、子组件绑定的值(这时候会去检测子组件的@Input()输入引用是否改变,如果有改变,会将子组件标记为Dirty,也就是该子组件需要变更检测)详细变更检测原理流程图:简化流程:触发异步事件=> ZoneTask处理事件=> ZoneDelegate 调用ZoneSpec的钩子触发onMicrotaskEmpty通知=> 根组件收到onMicrotaskEmpty通知,执行tick(),开始检测并更新dom由以上代码可知,当微任务为空的时候才会触发变更检测。简略变更检测原理流程图:2.2.2 变更检测优化方案1 )使用OnPush 模式原理:减少1次变更检测的耗时。OnPush模式与Default模式的区别在于:dom监听事件、timer事件、promise都不会触发变更检测。Default模式的组件状态始终为CheckAlways,表示组件每次检测周期都要检测。OnPush模式下:以下情况会触发变更检测S1、组件的@Input引用发生变化。S2、组件的DOM绑定的事件,包括它子组件的DOM绑定的事件,比如 click、submit、mouse down。@HostListener()注意:通过renderer2.listen()监听的dom事件不会触发变更检测通过dom.addEventListener()原生监听方式也不会触发变更检测S3、Observable 订阅事件,同时设置 Async pipe。S4、利用以下方式手动触发变化检测:ChangeDetectorRef.detectChanges():触发当前组件和非OnPush子组件的变更检测。ChangeDetectorRef.markForCheck():将当前视图及其所有的祖先标记为脏,下次检测周期时候会触发检测。ApplicationRef.tick():不会触发变更检测2 )使用NgZone.runOutsideAngular()原理:减少变更检测次数将全局dom事件监听写在NgZone.runOutsideAngular()方法的回调里面,dom事件将不会触发angular的变更检测。如果当前组件未更新,可以在回调函数里执行ChangeDetectorRef的detectChanges()钩子来手动触发当前组件的变更检测。举例:app-icon-react动态图标组件2.2.3 调试方式方式1:可以在浏览器控制台,使用Angular DevTools插件查看某一次dom事件,angular的检测情况:方式2:可以在控制台直接输入:ng.profiler.timeChangeDetection()查看检测时间,这种方式可查看全局的检测时间。参考博客 Profiling Angular Change Detection2.3 模板(HTML)优化2.3.1 减少DOM渲染:ngFor加trackBy使用 *ngFor 的 trackBy 属性,Angular 只更改和重新渲染已更改的条目,而不必重新加载整个条目列表。比如:表格排序场景。ngFor如果加了trackBy,表格渲染的时候只会移动行dom元素,如果不加trackBy,会先删除现有的表格dom元素,再新增行dom元素。显然只移动dom元素性能会好很多。2.3.2 模板表达式中不要使用函数不要在Angular 模板表达式中使用函数调用,可以用管道pipe代替,也可以通过手动计算后用一个变量代替。模板中使用函数,不管值有没有改变,每次变更检测的时候都会执行函数,会影响性能。模板中使用函数的场景:2.3.3 减少ngFor的使用使用ngFor,数据量大的时候会影响性能。举例:使用ngFor:不使用ngFor:性能提升10倍左右以上就是关于“angular怎么进行性能优化”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注百云主机行业资讯频道。

相关推荐: C语言入门代码实例分析

本文小编为大家详细介绍“C语言入门代码实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言入门代码实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。——代码的运行1只会从main函数开始执行,从上到下,逐行运行。2一个…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 04/02 12:26
Next 04/02 12:26

相关推荐