http://www.web008.net

美高梅手机版前端框架天下三分,这个锅我不背

Angular说:这个锅我不背

2016/05/30 · JavaScript · 2 评论 · AngularJS, React

本文作者: 伯乐在线 - 亚里士朱德 。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

前端这几年的技术发展很快,细分下来,主要可以分成四个方面:

楔子

最近月影大神翻译的一篇文章很火——《别责怪框架:我使用 AngularJS 和 ReactJS 的经验》,标题看似客观,不过先扬后抑,借黑Angular之际狠赞了一下React。

看完之后也让我有感而发。写这篇文章的目的,并不是想反作者之道,褒Angular贬React,只是希望读者抛开个人情绪,对两者(或者Angular?)有一个更客观地认识。

  1. 开发语言技术,主要是ES6&7,coffeescript,typescript等;
  2. 开发框架,如Angular,React,Vue.js,Angular2等;
  3. 开发工具的丰富和前端工程化,像Grunt,Gulp,Webpack,npm,eslint,mocha这些技术;
    就开发框架这块,Angular(1&2),React,Vue目前占据着主流地位而且会相持比较长的一段时间,所以这里对比一下这三门技术,以便之后的技术选型。

ReactJS与Angular

还记得一年前刚接触Angular的时候感觉既惊喜又恐惧。惊喜的是双向绑定、指令…这些功能太炫酷了,恐惧的是感觉是在重新学习一门新的语言,如果说小米重新定义了手机的话,那么Angular应该是重新定义了javascript。

它的模块功能以及依赖注入很像AMD规范的requirejs,它的视图数据绑定更像是DOM操作升级版,它的路由功能又与backbone有异曲同工之妙,内置的$q$http服务很好的解决了异步通信问题,不和jquery冲突的同时内置了类似jquery风格的原生DOM操作方式…最难能可贵的是,它还提供了单元测试和端到端的解决方案。

而对ReactJS我还只停留在hello world的层次,曾经在知乎上看到有人评价react的时候说是因为Angular的指令系统太难学,所以搞了一套这个玩意,不知真假。参考官网宣传及各种文章对react的吹捧,觉得优点应该有3个吧:

一. 趋势

Vue.js

美高梅手机版 1

Reactjs

美高梅手机版 2

Angularjs

美高梅手机版 3

2.对比
虽然放在一起Angular还是最火的,但从单个趋势图可以看出来reactjs和vuejs明显是火箭一般上升。很明显可以看到Angular在16时候有个大跌幅,那时候正是React坐火箭上升最快的。就是那时候很多Angular的项目转成了React。如果Angular没有出2,那估计Angular就真的离灭亡不远了。

美高梅手机版 4

3.GitHub受欢迎程度

美高梅手机版 5

4.定位
虽然Vue.js被定义为MVC framework,但其实Vue本身还是一个library,加了一些其他的工具,可以被当成一个framework。ReactJS也是library,同样道理,配合工具也可以成为一个framework。AngularJS(本文AngularJS特指Angular 1, Angular 2特指第二版Angular)是一个framework,而Angular 2虽然还是一个framework,但其实在设计之初,Angular 2的团队站在了更高的角度,希望做一个platform。
5.上手容易度
Vue.js hello world

美高梅手机版 6

ReactJS hello world

美高梅手机版 7

** 6.文档清晰度**
现在的前端framework,用起来就像按照说明书使用家用电器一样。按照文档一步步写就好了,所以文档的清晰度非常重要。同时小伙伴也很重要,越多的人使用,那遇到一样问题的人就越多,stackoverflow上面可能早就有帮你解决问题的小伙伴了。就这几个来说,我个人认为Vue.js的文档最恳切。我认为结合文档和遇到问题Google答案的匹配度来讲:

Vue.js > ReactJS > AngularJS > Angular 2

组件化

Angular的指令完全能实现组件化,支持嵌套和数据绑定,它的依赖注入使得引用也非常方便。

二. 数据流

1.Angular 使用双向绑定即:界面的操作能实时反映到数据,数据的变更能实时展现到界面。
实现原理:
$scope
变量中使用脏值检查来实现。像ember.js是基于setter,getter的观测机制,
$scope.$watch
函数,监视一个变量的变化。函数有三参数,”要观察什么”,”在变化时要发生什么”,以及你要监视的是一个变量还是一个对象。
使用ng-model时,你可以使用双向数据绑定。 使用$scope.$watch
(视图到模型)以及$scope.$apply
(模型到视图),还有$scope.$digest
双向绑定的三个重要方法:
$scope.$apply()$scope.$digest()$scope.$watch()
在AngularJS双向绑定中,有2个很重要的概念叫做dirty check,digest loop,dirty check(脏检测)是用来检查绑定的scope中的对象的状态的,例如,在js里创建了一个对象,并且把这个对象绑定在scope下,这样这个对象就处于digest loop中,loop通过遍历这些对象来发现他们是否改变,如果改变就会**调用相应的处理方法来实现双向绑定。

  1. Vue 也支持双向绑定,默认为单向绑定数据从父组件单向传给子组件。在大型应用中使用单向绑定让数据流易于理解
    Vue相比():
    Vue.js 有更好的性能,并且非常非常容易优化,因为它不使用脏检查。Angular,当 watcher 越来越多时会变得越来越慢,因为作用域内的每一次变化,所有 watcher 都要重新计算。
    并且,如果一些 watcher 触发另一个更新,脏检查循环(digest cycle)可能要运行多次。 Angular 用户常常要使用深奥的技术,以解决脏检查循环的问题。有时没有简单的办法来优化有大量 watcher 的作用域。
    Vue.js 则根本没有这个问题,因为它使用基于依赖追踪的观察系统并且异步列队更新,所有的数据变化都是独立地触发,除非它们之间有明确的依赖关系。唯一需要做的优化是在 v-for 上使用 track-by。

  2. React-单向数据流
    MVVM流的Angular和Vue,都是通过类似模板的语法,描述界面状态与数据的绑定关系,然后通过内部转换,把这个结构建立起来,当界面发生变化的时候,按照配置规则去更新相应的数据,然后,再根据配置好的规则去,从数据更新界面状态。
    React推崇的是函数式编程和单向数据流:给定原始界面(或数据),施加一个变化,就能推导出另外一个状态(界面或者数据的更新)。
    React和Vue都可以配合Redux来管理状态数据。

虚拟DOM提升性能

PC端上就现代浏览器内核的渲染性能而言,用Angular没出现过什么性能问题。

移动端在操作比较多的DOM时,低端机上会出现卡顿。不过还是有优化方案的,而且Angular本身也是不提倡频繁、大量的操作DOM,比如HTML游戏。

三. 视图渲染

  1. AngularJS的工作原理是:HTML模板将会被浏览器解析到DOM中, DOM结构成为AngularJS编译器的输入。AngularJS将会遍历DOM模板, 来生成相应的NG指令,所有的指令都负责针对view(即HTML中的ng-model)来设置数据绑定。因此, NG框架是在DOM加载完成之后, 才开始起作用的。
    React
  2. React 的渲染建立在 Virtual DOM 上——一种在内存中描述 DOM 树状态的数据结构。当状态发生变化时,React 重新渲染 Virtual DOM,比较计算之后给真实 DOM 打补丁
    Virtual DOM 提供了函数式的方法描述视图,它不使用数据观察机制,每次更新都会重新渲染整个应用,因此从定义上保证了视图与数据的同步。它也开辟了 JavaScript 同构应用的可能性。
    超大量数据的首屏渲染速度上,React 有一定优势,因为 Vue 的渲染机制启动时候要做的工作比较多,而且 React 支持服务端渲染
    React 的 Virtual DOM 也需要优化。复杂的应用里可以选择 1. 手动添加 shouldComponentUpdate 来避免不需要的 vdom re-render;2. Components 尽可能都用 pureRenderMixin,然后采用 Flux 结构 + Immutable.js。其实也不是那么简单的。相比之下,Vue 由于采用依赖追踪,默认就是优化状态:动了多少数据,就触发多少更新,不多也不少
    React 和 Angular 2 都有服务端渲染和原生渲染的功能。
  3. Vue.js 不使用 Virtual DOM 而是使用真实 DOM 作为模板,数据绑定到真实节点。Vue.js 的应用环境必须提供 DOM。Vue.js 有时性能会比 React 好,而且几乎不用手工优化。

React Native

我看好React的原因很大程度在于它,这种跨平台能力还是很有价值的。这一点也是可以秒杀Angular的,不过目前还不了解是否有成熟的大型应用~

四. 性能与优化

性能方面,这几个主流框架都应该可以轻松应付大部分常见场景的性能需求,区别在于可优化性和优化对于开发体验的影响。Vue 的话需要加好 track-by 。React 需要 shouldComponentUpdate 或者全面 Immutable,Angular 2 需要手动指定 change detection strategy。从整体趋势上来说,浏览器和手机还会越变越快,框架本身的渲染性能在整个前端性能优化体系中,会渐渐淡化,更多的优化点还是在构建方式、缓存、图片加载、网络链路、HTTP/2 等方面。

解决方案

对于文中所提问题,我以自己对Angular的粗浅了解,花了几分钟,试着解答了一下~

1.改变 URL 的时候不重新加载 controller 或者渲染基础模板。

如果认真看了官方文档关于$location服务的介绍之后,要解决这个问题并不难。通过$location服务在hash值中添加url参数,这个参数不在路由中配置就不会刷新controller和视图,同时,又可以通过$location服务来获取它。具体方法我已写在了issue上。

2.想要从一个准备发送给服务器的 JSON 中移除一些空白字段时,发现 UI 中对应的数据也被一并移除了 —— 丫的双向绑定 ╮(╯▽╰)╭。

双向绑定应该是利大于弊的(虽然脏检测机制经常遭人诟病),基本上不再需要手动操作DOM。简化了逻辑,少了很多重复代码,同时也减少了视图与数据层忘记同步带来的错误。

这个问题当然也非常好解决,前提是如果你读过官方文档关于表达式的表述。那就是用用双冒号::可以实现单次绑定,之后操作数据就不会再与视图同步了,或者直接创建一个只含需要属性的新对象更简单,方法很多~

3.当想要使用 ngShow 和 ngHide 来显示一个 HTML 块同时隐藏另一个 HTML 块时,在一瞬间,两者同时显示了。

ng-cloak和loading页,随便选一个即可。

五. 模块化与组件化

Angular1 -> Angular2
Angular1使用依赖注入来解决模块之间的依赖问题,模块几乎都依赖于注入容器以及其他相关功能。不是异步加载的,根据依赖列出第一次加载所需的所有依赖。
可以配合类似于Require.js来实现异步加载,懒加载(按需加载)则是借助于 ocLazyLoad 方式的解决方案,但是理想情况下应该是本地框架会更易懂。
Angular2使用ES6的module来定义模块,也考虑了动态加载的需求。
Vue
Vue中指令和组件分得更清晰指令只封装 DOM 操作,而组件代表一个自给自足的独立单元 —— 有自己的视图和数据逻辑**。在 Angular1 中两者有不少相混的地方。

React
一个 React 应用就是构建在 React 组件之上的。 组件有两个核心概念:props,state。 一个组件就是通过这两个属性的值在 render 方法里面生成这个组件对应的 HTML 结构。
传统的 MVC 是将模板放在其他地方,比如 script 标签或者模板文件,再在 JS 中通过某种手段引用模板。按这种思路,想想多少次我们面对四处分散的模板片段不知所措?纠结模板引擎,纠结模板存放位置,纠结如何引用模板。
React 认为组件才是王道,而组件是和模板紧密关联的,组件模板和组件逻辑分离让问题复杂化了。所以就有了 JSX 这种语法,就是为了把 HTML 模板直接嵌入到 JS 代码里面,这样就做到了模板和组件关联,但是 JS 不支持这种包含 HTML 的语法,所以需要通过工具将 JSX 编译输出成 JS 代码才能使用(可以进行跨平台开发的依据,通过不同的解释器解释成不同平台上运行的代码,由此可以有RN和React开发桌面客户端)

写在最后

很多人都有一种畏难的心理,放弃学习Angular,或者向之前文章作者那样赶鸭子上架地被迫学习,从而变得痛恨,(就像你没有使用过VIM就无法理解为什么它被称作编辑器之神,不知道它是如何依靠“模式”来实现无鼠标操作光标,不知道它的宏之强大…)这其实是一种损失。因为Angular确实是一个优秀的框架,它的优秀不仅仅在于前面我说的那些优点。它不单单是强大的开发框架,更像是饱含了作者设计思想和理念的艺术品(当你阅读完官网开篇介绍的最后一部分:Angular的禅道之时愈发会有此感)。

最后引用罗胖说过的一句话做为文章的结尾。

“我创业之后越来越少负面地区评价一个人和一件事,是因为我清楚地知道,一旦我做出这样一个结论,以我的知识和逻辑能力,我马上会编造一套理由,在自己内心里来论证自己这个判断。而因此的结果就是我从此丧失了对这个人这个事代表的所有现象的好奇心和求知欲,也就是说,我认知的大门就关上了。”

打赏支持我写出更多好文章,谢谢!

打赏作者

六. 语法与代码风格

React,Vue,Angular2都支持ES6,Angular2官方拥抱了TypeScript这种 JavaScript 风格。
React 以 JavaScript 为中心,Angular 2 依然保留以 HTML 为中心。Angular 2 将 “JS” 嵌入 HTML。React 将 “HTML” 嵌入 JS。Angular 2 沿用了 Angular 1 试图让 HTML 更强大的方式。
React 推荐的做法是 JSX + inline style,也就是把 HTML 和 CSS 全都整进 JavaScript 了。Vue 的默认 API 是以简单易上手为目标,但是进阶之后推荐的是使用 webpack + vue-loader 的单文件组件格式(template,script,style写在一个vue文件里作为一个组件)

打赏支持我写出更多好文章,谢谢!

任选一种支付方式

美高梅手机版 8 美高梅手机版 9

1 赞 3 收藏 2 评论

七. 一些大公司使用例子

郑重声明:本文版权归美高梅163888所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。