2015前端框架何去何从

这篇文章将从 AngularJS ReactJS Polymer 这几个流行的框架入手,分析前端框架在这几年发展中的关键技术点,作为2015前端技术选型的参考。摘要:

  • 初体验
  • 技术特点
  • 组件化
  • 应用架构
  • 总结

1. 初体验

拿TODO来作为引子好了.

Angular 的实现

React的实现(非flux架构)

Polymer的实现

三者共同对比

在Angular中有controller和component的概念是分离的,而react和polymer中只有component的概念。

实际上三者在最简单的使用场景下差异并不大,Angular和polymer模板和代码分离的方式更贴近于传统的前端做法,而React写法更像后端渲染。关于学习和使用成本的谁高谁低得问题没有什么好争论的,在MVVM已经流行了这么久的情况下,三者入门门槛都差不多,但要用好都需要深入其中的运行机制才行。

2. 技术特点

实际上所谓的MVVM框架的关键技术就一个:数据与视图的绑定。在Angular/polymer/knockout/vue/avalon 中,这项技术的实现又可以拆分成两个关键点:模板分析和数据监测。

模板分析的主要目的是对 {{title}} 这样的标记进行收集。收集完成之后生成一个视图更新函数,在函数内部保存着这个标记所在的Dom片段和相关的数据名称,函数被调用时会去重新取数据名称对应的数据(或者由外部将相应的数据作为参数传入),然后更新dom片段。这样就实现了视图的更新。一般框架会在启动时就将模板分析完,生成相应的视图更新函数。当数据更新的时候,就调用这些更新函数来更新视图,那么问题来了,如何检测数据的改动?

knockout/angular/avalon代表了三种方案:

  • 使用自定义的数据对象及其指定的get和set函数。例如你只能使用 user.set("name","john")来给user对象的name属性赋值,因为这样它才能在set函数中知道修改了什么属性,并且只调用相应的视图更新函数。这种方式不太爽的地方在于改变了原有的JS对象使用的方式。
  • 使用 Object.defineProperty 的get和set函数来检测对象属性的改动,本质上和上种没有什么区别。但是它有一个缺陷,就是无法检测新增的或删除的属性。有的框架是通过Object.observe来补充这种方案的,不过Object.observe 目前也只有chrome支持。这种方法改良了上面的开发体验,你可以像使用原生JS对象一样来操作你的数据。但是在实现上较为复杂。
  • dirty check。这是angular正在使用的机制,它并不能像前两种一样一旦数据发生变化立即触发更新回调。而是必须在调用了angular提供的一些方法,或者触发了页面上使用了ng-click等的元素上的事件后才会触发。这些触发时机是angular内部就已经实现了的,所以你几乎感觉不到。这种方法被称为"dirty"的原因是,它保存了所有属性上一次的值,检测是通过遍历对象的所有属性,对比它和上一次值是否一样来实现的。如果是深层对象的话,它会层层遍历。这种检测方式结合了上面两种的优势,但是对性能造成了负担。

至此,两个关键技术点都已讲清楚,用一张图来回顾一下

而在React中则相对简单,React用的是类似于重绘的机制,当触发了 setState 之后,就完全重新渲染(并非立即触发,中间有类似于缓存的性能提升机制)。这看起来比起前面的方案简单粗暴,但是却因为virtual dom的实现化腐朽为神奇了。virtual dom指的是React内部用来模拟真实dom的一种数据对象。当重新渲染时,实际上是先生成这样virtual dom,然后将其和上一次的virtual dom进行对比,找出差异,最后由react在真实的dom上更新有差异的部分就够了。因为virtual dom始终在内存中,真实的dom操作非常少,而前面的几种框架在更新视图时常常会有大量的dom操作,因此react在性能上大大领先前一种类型的框架。同时也因为virtual dom仍然是标准的 js对象,所以使得"服务端渲染"也成为可能。
值得注意的是,虽然React本身并不会像前面的框架一样深入的去检测数据的哪一部分发生了变化,但是可以通过官方提供的addon 和immutable.js来进一步提高这一块的性能。

3. 组件化

在组件化的方向上 react 和其他几种框架几乎已经分道扬镳了。从 angular2.0的设计和新出的 aurelia 等框架中可以看到大家都在尝试往 webcomponent 靠近。polymer号称下个版本代码将大幅减少,那无非是因为浏览器将实现标准了。靠近 webcomponent 的好处在于任何一个框架都将不再封闭,以 custom element作为接口层,能实现生态圈的融合。
虽然 react 也有封装成 custom element的方案,但是 react 并没有很好的调用其他框架生成的 custom element 的方案。"像使用原生dom元素一样使用custom element"的组件使用方式意味着尊重原生的dom使用方式,包括dom的事件等等。这和react"不操作真实dom"的基础已经方向相悖了。

react和其他框架的分歧其实目前看来并无优劣之分,因为webcomponent目前除了chrome以外其他浏览器支持仍然不全面。另外考虑到特殊国情的话,大公司的产品仍然要面对IE8。不幸的是目前polymer的polyfill最低也只到IE9。而React能无痛支持IE8。再考虑到移动端的浏览器情况的话,也是使用react的技术阻力远小于webcomponent。

总体来看,webcomponent肯定会是趋势,并且将促进各个框架变得更加开放,更易互相融合。而react也仍将继续依靠自己在实现上的优势继续走下去。也许未来在这中间又将诞生新东西。

暂时抛开react和webcomponent。我们继续深入两个目前讨论得很少但是却很重要的问题(下面讨论的组件问题都以封装成custom element为基础):

  • 如何能把组件变得更易重用? 具体一点:
    • 我在用某个组件时需要重新调整一下组件里面元素的顺序怎么办?
    • 我想要去掉组件里面某一个元素怎么办?
  • 如何把组件变得更易扩展? 具体一点:
    • 业务方不断要求给组件加功能怎么办?

针对第一个问题,我所在的团队目前提出一个叫做"模板复写"的规则,这个规则又分为"完全重写"和"部分重写"两种规则:

部分重写

这种方案已在angular中实现。并且在组件重用率高的系统中已经验证非常实用。但它也有缺陷,缺陷在于你必须知道当前组件的实现方式和原有模板才能复写。

第二个问题,可以用一种称为"共享作用域"的方式来解决。例如上面的例子中story没有显示like数量,现在要显示出来。常规方案有两种:

  • 改组件,在组件中增加这个功能。
  • 给组件增加api用于获取统计数据,同时在统计数据发生变化时抛出事件通知外部。

第一种方案可能碰到的问题是当再次发生变化,例如统计数据不要显示在组件里面了。就得继续改成第二种方案。 第二种方案可能碰到的问题是可能不断有新的需求提出来,最后不得不把每一个内部状态都暴露出来,每一个操作过程都抛出事件。

"作用域共享"共享的方案是: 通过在一个特殊标记 "import-to" 将某一段外部html引入到某个组件中去一起参与"模板解析"和"数据绑定",当完成时再放回原来的位置。这样这个外部html就能获取到组件内部任何状态和数据了。这种方案看起来有点像hack,但其实只是换了一种方式来理解组件:组件分成两个部分,一是数据,二是视图。视图理论上应该只受到它的逻辑是否足够内聚的约束,而不应该受到它的子元素是否放在一起的约束。但是目前我们刚好使用了dom作为视图的基础,所以视图受到html结构的约束,这个约束是不合理的。我们来用图对比一下使用"作用域共享"前后的场景:

当然,这种方案的缺陷仍然是你必须知道组件的具体实现。但这并不是一个不可克服的缺陷,我们看下aurelia的设计,它将template等等关键部分都设计成了可插拔的形式,这种结构意味着未来有可能实现一种通用的模板语法来实现上述两个功能。这样就不再和底层耦合。

4. 应用架构

应用架构的范围太广,我们这里只讨论那些已经很好地组件化了的应用,或者是没组件化但是有明确层级划分的应用。我们以React 对应的 FLUX 为切入点。

我们再来结合facebook的官方FLUX代码示例来看看每个部分:

facebook在介绍FLUX的时候的主要观点是"MVC扩展性不够,FLUX可扩展性高"。暂且不去讨论FLUX与MVC的区别, 我们先来它是如何扩展的,从上面的代码中可以看到,ACTION不只是一个界面上的点击事件所产生的,ajax请求、甚至一个初始化过程都可以产生动作,"动作"只是一个抽象。动作将传递给dispatcher,有dispatcher在去触发store注册的回调。你可能会想,从这个dispatcher实际上什么也没干,这和我直接定义一个方法,触发事件就直接调用这个方法有什么区别?区别在于,当应用增加功能、进行扩展时,应用可能有多个部分要协同对同一个action进行响应,并且不同的协同部分可能在执行顺序上有严格的先后之分。

举个例子,如果我要对上面的TODO增加一个"统计区块",如果是传统的MVC写法,你可能要新增一个statisticModel,然后在controller中的createTODO、deleteTODO中增加代码来操作这个新的statisticModel。而FLUX不用修改已有的任何代码,只需要写新的store,并注册一些回调到createAction、deleteAction中就够了。所以可以看做是将MVC中的 "C主动操作M" 反转成 "M来决定何时运行"(当然这种情况也就没有C了), 但更好的是理解成是一种"事件系统"的变种。这就是它和MVC的区别。严格来说 FLUX 并不能算是facebook"发明"出来的,这样的模型在很多事件驱动的后端框架中很常见,如zeroyii,只不过拿到前端来作为应用架构时比较新颖。

FLUX是目前高度推荐的应用架构方式,它并没有强制使用的库或者框架,所以并不局限于react,在angular、polymer中同样能自由实现。特别是目前angular、polymer中的应用开发并没有一种应用架构的最佳实践。angular中的模块化既没有异步加载也没有作用域隔离的作用,实际使用时很鸡肋。但是angular中的依赖注入、filter、service的设计非常全面,如果再能加上FLUX的架构的话,威力不容小觑。对polymer来说情况更简单,应为polymer目前只考虑到element这一层,所以上层的应用架构可以自由实现。

值得补充的是,FLUX中的store,dispatcher可以更好地加强一下。store可以使用一些自动支持REST的库来简化开发,dispatcher可以使用支持自定义顺序等高级的事件代理实现。

5. 总结

2015将是前端框架相互借鉴相互融合的一年,随着webcomponent的落地,大家都在像标准靠近。提前储备这方面的技术肯定没有问题。再深入到框架的技术细节中,我们看到在"渲染机制"、"数据绑定"、"组件化"、"模块化"这些关键技术点中各个框架中都有非常精彩的实现,值得深入学习。React异军突起,也推荐持续关注,特别是在"应用架构"上,FLUX确实在整个业界起到了启发的作用,相信会越来越流行,并且有越来越多实现方式。

时间: 2024-10-22 10:35:14

2015前端框架何去何从的相关文章

2015前端组件化框架之路(转)

https://github.com/xufei/blog/issues/19 1. 为什么组件化这么难做 Web应用的组件化是一个很复杂的话题. 在大型软件中,组件化是一种共识,它一方面提高了开发效率,另一方面降低了维护成本.但是在Web前端这个领域,并没有很通用的组件模式,因为缺少一个大家都能认同的实现方式,所以很多框架/库都实现了自己的组件化方式. 前端圈最热衷于造轮子了,没有哪个别的领域能出现这么混乱而欣欣向荣的景象.这一方面说明前端领域的创造力很旺盛,另一方面却说明了基础设施是不完善的

2015前端组件化框架之路

特别声明:本文转自@民工精髓的<2015前端组件化框架之路>.谢谢@民工精髓的分享!著作权归作者所有. 编辑推荐: 掘金是一个高质量的技术社区,从 CSS 到 Vue.js,性能优化到开源类库,让你不错过前端开发的每一个技术干货. 点击链接查看最新前端内容,或到各大应用市场搜索「 掘金」下载APP,技术干货尽在掌握中著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.原文: http://www.w3cplus.com/components-in-webapp.html ? w

2015年你必须学习的编程语言和前端框架

各种前端开发库和前端框架在不断的更新,为了适应潮流的需要,你必须不断的学习新的东西.但是下面提到的编程语言和前端框架会在很长的时间内占据重要的位置,学习和掌握它们是值得的和必须的.从长远来看,它们是十分受欢迎的,被广大社区支持,并且提供很多的就业机会. JAVASCRIPT 如果你正在从事前端web的开发工作,那么不论你使用什么后台语言,前台开发中javascript使你必须掌握的语言.你可以在浏览器中.在服务器上.在移动app中.甚至是在可编程硬件上使用JS.ECMAScript 6将会使语言

2015 年开源前端框架盘点 TOP 20

1.名称:Bootstrap 类别/语言:HTML.CSS.JavaScript 创建者: Twitter 人气:在Github上有91007 stars 描述:主流框架中毋庸置疑的老大,Bootstrap 是基于 HTML.CSS.JavaScript 的,它简洁灵活,使得 Web 开发更加快捷. 核心概念/原则: RWD 和移动优先制. 浏览器支持: Firefox, Chrome, Safari, IE8+ (你需要 Respond.js for IE8) 响应式: Yes 模块化: Ye

如何挑选适合的前端框架

来源于:https://github.com/RubyLouvre/agate/issues/8 最近几年,前端技术迅猛发展,差不多每年都会冒出一款主流的框架. 每次新开业务线或启动新项目时,是第一件事就是纠结:使用什么框架,重造什么轮子?我很高兴应CSDN的邀请谈我的看法. 在五六年,移动端还没有兴起,我们没有什么选择,就是jQuery.有人会说,jQuery只是类库,不是框架;但那时前端业务还没有像今天这么繁重,原本是后端干的事,全部挪到前端来,因为光是jQuery就可以包打天下.jQuer

2016国内最值得期待的响应式前端框架pintuer(拼图)--http://www.pintuer.com

近期,需要将项目从pc端的应用扩展到移动端. 当然移动框架的第一选择必然是bootstrap,但是bootstrap作为移动端明显过于死板,而且作为国外的产品,对于国内的应用明显水土不服.框架里总有那么些部分不符合心意,如果自己扩展,那就不是一般的工作量了. 然后是wex5,宣传上是最强大的移动开发框架,一旦测试,采用java的模式,将一个简单的工作直接变成了另一个windows编程的学习,那是一次痛苦的体验.当然也是因为wex5主要目标是app,而我要的仅仅是移动wap端.(wap这个词实际上

html5前端框架

本文由PHP100中文网编译 HTML5框架可以快速构建响应式网站,它们帮助程序员减少编码工作,减少冗余的代码.如今有很多免费的HTML5框架可供使用,由于它们有着响应式设计.跨浏览器兼容.相对轻量级等特点,这些框架在开发中都十分流行.如果你也对HTML5框架感兴趣,你可以看看下面我列出的一些最佳的响应式HTML5框架,帮助你快速开发网站. 1. Twitter Bootstrap Bootstrap来自Twitter,是目前最受欢迎的前端框架,它简洁灵活,使得Web开发更加方便快捷.它有着优雅

如何挑选适合的前端框架(去哪儿网前端架构师司徒正美)

前端框架不断推新,众多IT企业都面临着"如何选择框架","是否需要再造轮子"的抉择.去哪儿网前端架构师司徒正美分析了各主流行框架优劣点.适用场景,并针对不同规模的公司.项目给出了相应的前端技术选择方案. 最近几年,前端技术迅猛发展,差不多每年都会冒出一款主流的框架. 每次新开业务线或启动新项目时,首先第一件事就是纠结:使用什么框架,重造什么轮子?我很高兴应CSDN的邀请谈我的看法. RequireJS,前端技术发展分水岭 在五六年前,移动端还没有兴起,我们没有什么选

2015 前端[JS]工程师必知必会

2015 前端[JS]工程师必知必会 本文摘自:http://zhuanlan.zhihu.com/FrontendMagazine/20002850 ,因为好东东西暂时没看懂,所以暂时保留下来,供以后参考! MrSunny · 12 天前 上次我写<前端工程师必知必会>已经是三年前了,那是我写过最火的文章了.三年了,我仍然会在Twitter上收到关于这篇文章的消息. 从2012年到现在,一篇文章都没发过让我觉得有点羞羞哒.三年是一段很长的时间,很多东西都发生了改变.2012年,我鼓励同学们去