跳转到主要内容

根据参与项目的开发人员的可用专业知识和个人偏好,通常会临时决定新项目的开发框架。然而,对于一个企业来说,更合理的方法是考虑开发框架应该满足的具体标准。做出这种选择的“一般科学”是简单而成熟的。有一定的标准来衡量备选方案的性能,并选择累积性能最高的备选方案。一个标准可能比另一个更重要。选择标准并相互权衡是一门艺术,在软件开发社区中,没有公认的选择正确软件框架的最佳实践。

考虑到这一背景,在选择网络框架时注意特定的标准是很重要的。最常见的选择标准包括速度、成熟度、稳定性、学习曲线和社区支持。本文中考虑的最突出的选项是React和Vue.js。这两个选项在速度、成熟度、学习曲线和社区支持方面都有很高的性能分数。两者之间的选择并不简单,为了使选择合理化,我们在Web UI发展的历史背景下研究了框架。

比较React和Vue

Web UI框架一直遵循MVC(模型-视图-控制器)设计模式。最初,React在MVC中被称为V,而事实上,它的设计者正在努力将React概念化为一个纯粹的功能,将UI状态转换为UI的视觉表示。Vue.js是MVC设计模式中最优秀、最干净的样本。Vue.js和React之间的区别在于干净的MVC编程模型和将Web UI概念化为一个纯函数的新兴范式之间的区别。随着用户界面的广泛采用,功能用户界面已经成为一种新的范式,这是一种关于用户界面的新思维方式。

Vue.js和React这两个关键参与者现在正遵循这一模式。因此,可以肯定地说,功能性UI已经成为主流。遵循功能性UI趋势对React来说是一个明显的改进,因为它让React表达了其概念上的纯粹性,而这是它一直难以实现的,但这一趋势对Vue.js来说并不那么好,因为它标志着与使Vue.js简单易懂的干净MVC设计的背离。React API是稳定的,但Vue.js API正处于进化过程中。因此,React目前处于UI范式发展的前沿,而Vue.js正在迎头赶上。自2020年初以来,React似乎更适合新的企业级项目。

决策问题

2024年开始的新企业级项目,您会选择什么UI框架?选择必须合理,并包含一系列标准:

一般标准

  1. API的表达能力和简洁性
  2. 框架性能
  3. JS代码的大小——占用空间
  4. 易于学习
  5. 良好的API设计,便于维护
  6. 可测试性
  7. 工具、库和小部件的可用性
  8. 论坛上的社区支持
  9. 确保未来框架发展的社区或企业支持
  10. API的稳定性

公司/项目特定标准

  1. 适合特定项目要求
  2. 已经在组织中工作的具有框架经验的开发人员的可用性

问题是有许多优秀的框架可供选择。有React、Vue.js、Angular,以及LitElement/lit-html等新兴玩家。现在哪一个最好?

事实上,更有趣的问题是:一年、两年或三年后,哪一个会是最好的?如果这个问题听起来像是一个边缘问题,那么你还记得几年前AngularJS发生了什么吗?许多用AngularJS编写的企业项目甚至在完成之前就成为了技术债务,因为谷歌决定创建Angular 2。或者,还记得Silverlight吗?那些忘记过去的人注定会重蹈覆辙。了解web UI的历史可能有助于预测事情的发展方向,并做出更安全的选择,而在2024年做出这样一个更安全的决定就是本文的主题。

Web UI简史

一开始,Web UI是在服务器上生成的,表示逻辑、业务逻辑和数据访问代码混合在一起。一片混乱。从这种混乱中出现了模型-视图-控制器(MVC)模式。就好像有人说:“让表示逻辑收集在视图中,让业务逻辑收集在模型中,让控制器将模型和视图分离,并充当两者之间的中介”,结果就是这样——各种框架,如Spring、Django、Rails和ASP.NET MVC模式的出现,并成为Web UI的主要设计模式。MVC模式强制执行了“关注点分离”这一重要的体系结构原则,以确保数据访问、业务逻辑和表示逻辑在单独的单元中处理。

在基于Web的MVC框架中,控制器将定义一组操作。每个操作都处理对特定URL的GET、POST、PUT或DELETE web请求。为了执行操作,控制器将查询模型以使用业务逻辑和数据。然后,Action将生成一组参数,并使用这些参数来呈现HTML模板。视图是一个具有自由参数的HTML模板。呈现视图(模板+参数)可以生成动态HTML页面。在这个模型中,Web UI的状态保存在服务器上的会话对象、缓存、数据库或URL查询字符串中。对UI状态的每次更新都需要往返于服务器,然后刷新网页。那是一个网络还很新而且速度很慢的时代。

AJAX的发明允许异步和部分网页更新。成功的AJAX框架仍然使用MVC模式,只是操作不会返回整个HTML页面,而是返回JSON对象或HTML块,并且该输出将用于部分页面更新。有了AJAX,Web变得更快更好了,但仍然不够快。需要丰富UI的应用程序将依赖Silverlight和Adobe Flash

自从JavaScript作为HTML5标准的一部分被采用以来,情况发生了巨大的变化。未来每个浏览器都必须实现一个稳定的JavaScript API,这一保证导致了依赖新Web标准的新UI框架的复兴。Silverlight和Adobe Flash已经过时。有些公司在Silverlight停产之前就在Silverlight上下了赌注。我帮助一家这样的公司开始在他们的Web UI中使用JavaScript。当时,架构师和开发人员并不容易相信JavaScript可以像Silverlight一样丰富。HTML5和新的JavaScript框架的采用改变了一切。

大多数新的JavaScript框架都采用了熟悉的MVC设计模式。就好像同一个声音说:“因为它在服务器上在上面,所以它应该在浏览器上在下面。”事实变成了这样。在浏览器中,MVC模式的工作原理如下:模型定义了网页的状态。Controller定义了一组Actions,通常是更新DOM的JavaScript函数视图是保存在模型中的HTML模板+基于浏览器的状态。通常情况下,模板还包含控制器操作与浏览器事件的绑定。浏览器事件然后调用控制器的操作。Actions可以使用JavaScript更改DOM。操作还可以更改存储在模型中的本地状态。MVC模式在客户端采用,有几种变体:模型-视图-视图-模型(MVVM)模型-视图(MV*)。Knockout.js是最早的MVC JavaScript库。然后是Backbone.js和Ember.js。AngularJS稍晚出现,成为第一个成功的Web UI库,在企业环境中得到了最广泛的采用。

React是继AngularJS之后第二个被广泛采用的库。如今,React拥有最大的用户群,在受欢迎程度上遥遥领先于其他框架。最初,React在MVC中被称为V,但其设计者正在努力使React成为一个将UI状态转换为UI视觉表示的纯函数。与其他流行的Web UI框架不同,React没有单独的模板语言。虽然其他框架会扩展HTML以引入模板语言,但React在JavaScript中表示DOM,并使用名为JSX的JavaScript扩展来提供对HTML DOM的更友好的描述。

本质上,React视图是一个组件树,这些组件是知道如何渲染自己的JavaScript对象。React还有一些功能组件,它们是纯函数,在给定一组参数作为输入参数的情况下,生成HTML DOM作为输出。在引入React Hooks之前,这些功能组件不允许将组件的状态归该组件所有。通过添加React Hooks,这些功能组件可以完成常规React组件所能做的一切,包括具有内部组件状态。功能性React组件正成为React开发的主要焦点,未来的React开发似乎将基于这些功能性组件。

React使用虚拟DOM,这是一个表示DOM树的JavaScript对象。当对网页进行一系列更新时,React会更新虚拟DOM,然后将真实DOM与虚拟DOM进行匹配。这一更新策略使React比其竞争对手更快。此外,使用虚拟DOM,可以将实际渲染与虚拟DOM分离,并且可以支持不同于Web浏览器的渲染器。这使得诸如服务器上的无头渲染和移动设备上的渲染等技术成为可能。React Native之所以成为可能,是因为有了虚拟DOM。有一个问题:要使用虚拟DOM的所有优点,所有DOM更新都必须由虚拟DOM控制。由于jQuery直接访问浏览器DOM,因此不鼓励将jQuery与React(或Vue.js)一起使用。

React JSX的支持者抱怨MVC框架中HTML模板和控制器被保存在单独的文件中,他们会说这种分离不是关注点的分离,而是技术的分离。还有一个小组认为,与JSX相比,MVC框架中使用的HTML模板更好,设计更干净。HTML模板对用户体验设计师来说很友好,因为有些人不精通JavaScript,但对HTML很熟悉。Vue.js的存在正是出于这些考虑。它为那些对JSX不满意的前AngularJS开发人员提供了熟悉的HTML模板。它还提供了将JavaScript控制器和模板保存在相同文件中的机会,正如JSX的支持者所希望的那样。Vue.js还使用了虚拟DOM,速度与React一样快。Vue.js被设想为更好的Angular和更好的React。

状态管理与“寻求单一的真理来源”

从一开始,管理Web UI状态就一直是最重要的设计问题之一。在传统的MVC设计中,状态存储在模型中,并且在大多数情况下都能很好地工作。Facebook开发人员遇到的一个问题是,当状态分布在不同的模型之间时,MVC无法扩展。Facebook的软件工程师陈静(Jing Chen)提出了Flux设计模式,该模式强制UI和State之间的单向信息流。Flux模式成为最流行的React状态管理工具Redux的基础和灵感来源,该工具也由Facebook工程师Dan Abramov开发。

Vue.js紧随潮流推出了Vuex,本质上是对Redux的改编。Angular 2+也有一个类似的状态管理工具,称为NgRx,这也是一种基于RxJS库使用反应式编程模式实现的Redux。

Redux及其衍生物的工作原理如下:

  1. Store是唯一一个存储所有UI State的Model。Store是整个UI状态的“单一真相来源”。当UI是一个单页应用程序时,应用商店可能会变得非常大。
  2. 对状态(存储)的所有更改都是通过发出Actions进行的。
  3. 状态的变化是用称为Reducers的纯函数计算的。

Reducer的签名如下:

  • Reducer(State, Action) => NewState

虽然存储在Store中的状态树是一个,但可能有许多Reducer负责处理状态树的各种特定分支。Redux与功能的纯粹性作斗争,并强制执行国家的不变性,要求还原者始终返回一个新的国家。Vuex允许状态可变。Vuex还放宽了“单一真相来源”原则,允许其在不同模块之间传播国家。

Redux/Flux模式具有以下几个优点:

  1. 由于Reducer是纯功能,因此可以很容易地测试UI逻辑。
  2. Redux模式随着应用程序的增长而扩展得很好。
  3. 由于状态更改是纯函数,因此可以回滚。这允许开发诸如“时间旅行调试器”之类的东西(React和Redux开发工具都有这样的东西)。

一些交叉的UI问题不容易融入Redux模式——例如,浏览器历史状态和短暂的UI副作用(如指示UI正在等待对后端的查询结果的等待符号)如何?在Redux的早期,Facebook上许多有影响力的人都非常喜欢Flux/Redux模式,他们进行了“意识形态纯洁性的斗争”,以某种方式在使用它的React应用程序的所有UI问题上强制执行该模式。由于这次推送,React Router的新版本可以将浏览器历史状态存储在Redux store中。为了处理副作用(如动画或对后端API的请求),引入了Redux-Sagas。总的来说,这些都是非常有价值的改进;然而,在这个过程中,一些非常复杂的高样板编程模式也被React开发人员引入并广泛使用。

可以肯定地说,Redux或其等价物被用作现代UI应用程序的主要状态管理模式。以下是关于Redux vs Vuex的状态管理的资源。帖子还指出Vuex比Redux更简单,这让我们想到了以下一点。

Vue在2017年表现优于React

Vue.js是作为更好的React和更好的Angular引入的,Vue API的许多元素都有更少的样板。与Redux相比,Vuex还有一个更简单的API。虽然这两个框架的性能和浏览器占用空间大致相同(Vue.js略胜一筹),但这两种框架都享有广泛的社区支持、工具、小部件库和未来开发的保证。Vue.js在使用简单性和无样板代码方面胜过React。Vue.js的采用率非常高,因为用户社区非常热情。对于那些学会欣赏AngularJS的模板系统和最快学习曲线的开发人员来说,Vue.js是一个明确的选择框架。

React Hooks与功能UI革命

UI是State的函数:UI = F(State)。这是许多React开发人员一直在努力提出的观点。因此,最好将UI表示为纯函数。

官方建议在React中思考的方法是从UI必须呈现的抽象状态开始,并将UI设计为组件的层次结构,每个组件将全局状态的一小部分转换为视觉表示。如果那些UI组件是纯功能的,那不是很好吗?React有纯功能组件,但在推出React Hooks之前,它们的能力是有限的。它们不允许具有内部状态,只允许呈现从父组件传递的参数。在引入React Hooks之后,整个React UI可以由纯功能组件构建,每个人似乎都喜欢这种方法。

React Hooks是一个非常好的架构创新,许多其他框架都希望采用这种模式并跳上功能UI带宽-e.g.,LitElement项目获得了功能版本,Vue.js项目提出了Vue 3 functional API提案。

2020年是React赢得Web框架竞赛的一年

对Vue 3 API提案的反应非常有争议。对该提议的一些负面评论如下:“如果你想用Vue.js制作React,为什么不简单地使用React呢?”(If you want to make React out of Vue.js, why not simply use React?)想想这篇博客文章的标题“Vue最黑暗的一天”

尽管作者认为负面反应是少数,但很明显,对Vue.js的热情并没有那么强烈。这并不是关于Vue.js本身,而是关于向功能性UI的范式转变,这是React的一个自然的增量改进,也是Vue.js的一个范式突破性变化。备受喜爱的Vue.js模板系统并没有像React使用JSX渲染HTML的方法那样清晰地表达“UI是状态的函数”的想法。由于未来的Vue 3 API将有一个突破性的变化,现在不是在Vue.js上进行新开发的好时机。

在过去的两年里,React得到了逐步的改进,极大地简化了React开发人员使用的模式和最佳实践。除了增强功能性UI组件的功能外,React Hooks还为代码的可重用性提供了优雅的模式。它们还为解决许多常见问题提供了简单得多的编码模式。针对各种问题的解决方案,如维护State、从后端API获取数据、存储UI状态变量、控制副作用等等,都以React Hooks的形式打包,并在Github上为React开发人员提供。

其他框架正试图复制React社区已经完成的工作。最终,他们会得到它,但这需要时间。2024年,React似乎是一个新项目的首选web框架。

文章链接