变化检测(脏检查)的基本任务是获取程序内部状态的变化,并使其在用户界面上以某种方式可见,这种状态的变化可以来自于 JavaScript 的任何数据结构,最终呈现为用户界面中的段落、表单、链接或者按钮等 DOM 对象。我们把输入数据结构并生成 DOM 结构显示给用户的过程叫作渲染。
然而在程序运行时发生变化情况比较复杂,我们需要确定模型中发生什么变化,以及什么地方需要更新 DOM 节点。操作 DOM 树十分昂贵,所以我们不仅需要找出待更新的地方,还需要保持操作数尽可能小。这可能通过许多不同的方式来解决:比如我们可以简单的发起 http 请求并重新渲染整个页面,或者可以区分 DOM 树的新旧状态并只重新渲染二者不同的部分(ReactJS 虚拟 DOM 的解决方案)。
// this is the new version of addEventListener
function addEventListener(eventName, callback) {
// call the real addEventListener
callRealAddEventListener(eventName, function() {
// first call the original callback
callback(...);
// and then run Angular-specific functionality
var changed = angular2.runChangeDetection();
if (changed) {
angular2.reRenderUIPart();
}
});
}
Angular 2.x+ 脏检查机制理解
目前几种主流的前端框架都已经实现双向绑定特性,但实现的方法各有不同:
下面我们就来了解一下 ng2.x+ 的版本中的脏检查机制是如何运行的。
什么是变化检测
什么会引起变化
谁通知 Angular 更新视图
Zone 负责通知 Angular 进行视图更新,Angular 封装有 NgZone,简单来说,通过 Angular 的部分源码我们可以知道有一个叫作 ApplicationRef 的东西负责监听 NgZone 中的 onTurnDone 事件,每当该事件触发时,它就执行 trick 方法进行变化检测的基本工作。
变化检测
如何触发变化检测
改善的脏检查
性能
更优的变化检测
理解不可变
How I optimized Minesweeper using Angular 2 and Immutable.js to make it insanely fast
不可变对象
OnPush 策略减少检测次数
Angular OnPush Change Detection and Component Design - Avoid Common Pitfalls
Observables
TAKING ADVANTAGE OF OBSERVABLES IN ANGULAR
ANGULAR CHANGE DETECTION EXPLAINED How does Angular Change Detection Really Work ? Change And Its Detection In JavaScript Frameworks