一、数据流
Angular:双向绑定,界面的操作能实时的访问到数据,数据的变更能实时展现到页面。$scope 变量通过脏值检查来实现。像 ember 是基于getter/setter的观测机制。
双向绑定的三个重要方法
- $scope.apply()
- $scope.digest()
- $scope.digest()
Angular 的双向绑定中有两个很重要的概念叫 dirty check(脏检查)
和 digest loop(消化循环)
。dirty check 是用来检查绑定的 scope
中的对象的状态的,例如JS创建了一个对象,并且把这个对象绑定到了 scope
中,这样这个对象就处于 digest loop
中,loop 通过遍历这些对象来发现他们是否改变,如果改变就会调用相应方法来实现双向绑定
Vue 也支持双向绑定,默认是单向绑定(数据从父组件单向传递给子组件)。在大型的应用中使用单向绑定让数据更易于理解。
dirty check(脏检查)的利弊
和 ember 等技术的 getter/setter
观测机制相比(优)
getter/setter 每次对 DOM 产生变更,它都要修改DOM树的结构,性能影响大,Angular 会把批量操作延时到一次更新,性能相对较好。
和 Vue 的 依赖追踪
相比(劣)
在 Angular 中,当 watcher 越来越多时会越来越慢,因为作用域内的每一次变化,watcher 都要重新计算。并且,如果一些 watcher 触发另一个更新,脏检查循环(dirty cycle)可能要运行多次,影响性能。Vue 则不会有这个问题,因为它使用基于 依赖追踪 的观察系统并且异步列队更新,所有的数据变化都是独立的触发,除非他们之间有明确的依赖关系。
React——单向数据流
React 推崇的是函数式编程和单向数据流,给定原始界面(或数据),施加一个变化,就能推导出另外一个状态(界面或数据的更新)。
二、视图渲染
Angular 的工作原理
HTML模板会被浏览器解析到 DOM 中,DOM 结构成为 AngularJS 编译器的输入。AngularJS 将会遍历 DOM 模板,来生成相应的 NG 指令,所有的 NG 指令负责针对 View 来设置数据绑定。
React 的渲染建立在 虚拟DOM
(一种在内存中描述DOM树状态的数据结构) 上。当状态发生变化时,React 重新渲染 虚拟DOM
,比较之后给 真实的DOM
打补丁。
虚拟DOM 使用了函数式的方法描述视图,它不使用数据观察机制,每次更新都会重新渲染整个应用,因此从定义上保证了视图和数据的同步。
在超大数据的首屏渲染速度上,React 有一定优势,因为 Vue 的渲染机制在启动时要做的工作比较多,而且 React 还支持服务端渲染(Angular2也支持)。
React的虚拟DOM如何优化
- 1、手工通过
shouldComponentUpdate
方法来避免不需要的虚拟DOM的二次渲染; - 2、组件通过尽可能的使用 Mixin,采用 flux 结构 ImmuTable。
相比之下,Vue
由于采用依赖追踪,默认就是优化状态:动了多少数据,就触发多少更新。
Vue 不使用 虚拟DOM
而是使用真实的DOM作为模板,数据绑定到真实节点。Vue 应用环境必须提供DOM,有时性能会比React好很多,而且几乎不用手动优化。
三、性能和优化
性能方面,这三大主流框架都可以轻松应付大部分常见场景的性能需求,区别在于优化性和优化对于开发体验的影响。
-
Angular 需要手动指定
change detection strategy(变化检测策略)
; -
React 需要
shouldComponentUpdate
或者全面Immutable
; -
Vue 需要加好
track-by
。
从整体趋势来说,浏览器和手机还会越来越快,框架本身的渲染性能在整个前端性能优化体系中会越来越淡化,更多的优化点在于构建方式、缓存、图片加载、网络连接和HTTP上。
四、模块化和组件化
Angular1 使用依赖注入来解决模块之间的依赖问题,模块几乎都依赖于注入容器以及其他相关功能。不是异步加载的,根据依赖列出第一次所需的所有加载。配合 Require
来实现异步加载。
Angular2 使用 ES6 的 module
来定义模块,也考虑了动态加载的需求。
Vue 的指令和主见分得更清晰。指定之封装DOM操作,而组件则代表一个自给自足的独立单元 —— 有自己的视图和数据逻辑,
React 是构建在组件之上的,组件有两个核心概念 props
和 state
,一个组件就是通过这两个属性的值在 render
方法里面生成这个组件对应的HTML结构。
React 认为组件才是王道,而组件和模板是紧密关联的,组件模块和组件逻辑分离让问题复杂化了。所以就有了 JSX
语法,就是为了把 HTML 直接嵌入到 JS 里面,这样就做到了模块和组件关联。但是 JS 不支持这种包含的 HTML 的语法,所以需要通过工具将 JSX 语法编译成 JS 代码带能使用。
五、语法和代码风格
React、Angular和 Vue 都支持 ES6
语法
React 以 JavaScript 为中心,Angular 以 HTML 为中心。React 将 “HTML” 嵌入到 JavaScript 中,Angular将 “JavaScript” 嵌入到 HTML 中。