前端框架的优缺点Vue、Angular、React、Svelte以及Solid

前端框架的优缺点

Vue

Vue优点

  1. 简单:官方文档很清晰,比 Angular 简单易学。
  2. 快速:异步批处理方式更新 DOM。
  3. 组合:用解耦的、可复用的组件组合你的应用程序。
  4. 紧凑:~18kb min+gzip,且无依赖。
  5. 强大:表达式 无需声明依赖的可推导属性 (computed properties)。
  6. 对模块友好:可以通过 NPM、Bower 或 Duo 安装,不强迫你所有的代码都遵循 Angular 的各种规定,使用场景更加灵活。

Vue缺点

  1. 新生儿:Vue.js是一个新的项目,没有angular那么成熟。
  2. 影响度不是很大:google了一下,有关于Vue.js多样性或者说丰富性少于其他一些有名的库。
  3. 不支持IE8

Angular

Angular优点

  1. 模板功能强大丰富,自带了极其丰富的angular指令。
  2. 是一个比较完善的前端框架,包含服务,模板,数据双向绑定,模块化,路由,过滤器,依赖注入等所有功能;
  3. 自定义指令,自定义指令后可以在项目中多次使用。
  4. ng模块化比较大胆的引入了Java的一些东西(依赖注入),能够很容易的写出可复用的代码,对于敏捷开发的团队来说非常有帮助。
  5. angularjs是互联网巨人谷歌开发,这也意味着他有一个坚实的基础和社区支持。

Angular缺点

  1. angular 入门很容易 但深入后概念很多, 学习中较难理解.
  2. 文档例子非常少, 官方的文档基本只写了api, 一个例子都没有, 很多时候具体怎么用都是google来的, 或直接问misko,angular的作者.
  3. 对IE6/7 兼容不算特别好, 就是可以用jQuery自己手写代码解决一些.
  4. 指令的应用的最佳实践教程少, angular其实很灵活, 如果不看一些作者的使用原则,很容易写出 四不像的代码, 例如js中还是像jQuery的思想有很多dom操作.
  5. DI 依赖注入 如果代码压缩需要显示声明.

React

React优点

  1. 速度快:在UI渲染过程中,React通过在虚拟DOM中的微操作来实现对实际DOM的局部更新。
  2. 跨浏览器兼容:虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。
  3. 模块化:为你程序编写独立的模块化UI组件,这样当某个或某些组件出现问题是,可以方便地进行隔离。
  4. 单向数据流:Flux是一个用于在JavaScript应用中创建单向数据层的架构,它随着React视图库的开发而被Facebook概念化。
  5. 同构、纯粹的javascript:因为搜索引擎的爬虫程序依赖的是服务端响应而不是JavaScript的执行,预渲染你的应用有助于搜索引擎优化。
    6.兼容性好:比如使用RequireJS来加载和打包,而Browserify和Webpack适用于构建大型应用。它们使得那些艰难的任务不再让人望而生畏。

React缺点

React本身只是一个V而已,并不是一个完整的框架,所以如果是大型项目想要一套完整的框架的话,基本都需要加上ReactRouter和Flux才能写大型应用。

svelte

svelte的简介

Svelte是一个用于构建快速web应用程序的工具。
它类似于React和Vue等JavaScript框架,它们的共同目标是使构建流畅的交互式用户界面变得容易。
将你的应用程序转换成一个理想的时间段,而不是在你的应用程序运行的关键时刻。这意味着您不必为框架抽象的性能付出代价,而且在应用程序首次加载时也不会受到惩罚。
您可以使用Svelte构建整个应用程序,也可以将其增量添加到现有的代码库中。您还可以将组件作为独立的包在任何地方运行,而不需要依赖于传统框架的开销。

Svelte 有哪些好用的特性?

1.完全兼容原生 html 用法
编写代码是那么的自然,如下面就是一个组件。

<script>
  const content = 'test';
</script>
<div>
  { test }
</div>

2.响应式也是那么的自然

<script>
    let count = 0;
    function handleClick () {
        // calling this function will trigger an
        // update if the markup references `count`
        count = count + 1;
    }
</script>
<button on:click="handleClick">+1</button>
<div>{ count }</div>

3.表达式也可以是响应式的
这个更加的自然,这种特性只有静态编译才能做到,这个就是 svelte 目前独有的优势

<script>
    let numbers = [1, 2, 3, 4];
    function addNumber() {
        numbers.push(numbers.length + 1);
    }
    $: sum = numbers.reduce((t, n) => t + n, 0);
</script>
<p>{numbers.join(' + ')} = {sum}</p>
<button on:click={addNumber}>Add a number</button>

4.自动订阅的 svelte store
这个其实就是订阅发布模式,不过 svelte 提供了自身特有的便捷的绑定方式(自动订阅),用起来是那么的自然,那么的爽。
这种特性只有静态编译才能做到,这个就是 svelte 目前独有的优势。

stores.js

import { writable } from 'svelte/store';
export const count = writable(0);

A.svelte

<script>
    import { count } from './stores.js';
</script>
<h1>The count is {$count}</h1>

B.svelte

<script>
    import { count } from './stores.js';
  function increment() {
        $count += 1;
    }
</script>
<button on:click={increment}>增加</button>

5.所有组件都可以单独使用
可以直接在 react、vue、angular 等框架中使用。

// SvelteComponent.js 是已经编译后的组件
import SvelteComponent from './SvelteComponent';

const app = new SvelteComponent({
    target: document.body,
    props: {
        answer: 42
    }
});

Svelte 有什么缺点?

1.props 是可变的
当然这也是这个框架故意这样设计的,这样 props 也是可以响应式的。

<script>
  export let title;
  title = '前缀' + title
</script>
<h1>
  { title }
</h1>

2.props 目前无法验证类型

<script>
  export let propOne;
  export let propTwo = 'defaultValue';
</script>

3.自定义的组件无法直接访问到原生 DOM
需要利用 props 的双向绑定特性,这就可能导致深层次组件的需要层层传递 DOM 对象。
App.svelte


<script>
  export let customDOM;
</script>
<A bind:dom={customDOM}/>

A.svelte

<script>
  export let customDOM;
</script>

<div bind:this={customDOM}>
  test
</div>

4.只有组件才支持 svelte 的静态模板特性
js 文件是不支持 sevelte 静态模板特性的,像下面这样是会报错的。

import { count } from './stores.js';
function increment() {
  $count += 1;
}

Solid

Solid 是一个用于制作交互式 Web 应用程序的 JavaScript 框架。它利用自定义编译器将 JSX(一种受 HTML 启发的 JavaScript XML 方言)转换为高性能的 DOM 操作。更新则由细粒度的响应式系统提供支持,响应式系统减少了对比差异的开销,从而获得最佳性能。

React VS Solid

React 对 Solid 产生了很大的影响。React Hooks API 中的单向数据流和明确的读写分离影响了 Solid 的 API。Solid 更加像是一个 “渲染库” 而不是一个框架。Solid 对如何在应用程序开发中管理数据有着独到的看法,但并不试图约束执行。

然而,尽管 Solid 与 React 的设计理念保持一致,但它的底层运作方式完全不同。React 使用 Virtual DOM 而 Solid 没有。React 的抽象是自上而下的组件分区,其中渲染方法被重复调用和差异对比。相反,Solid 将每个模板整体渲染一次,构建其响应图,然后才执行与细粒度更改相关的指令。

Vue VS Solid

Solid 在设计方面并没有特别受到 Vue 的影响,但它们在方法上来讲是可以进行比较的。他们都在响应式系统中使用 Proxy,并能基于读取的自动跟踪。但这就是所有的相似之处。Vue 的细粒度依赖检测只是提供给一个细粒度的虚拟 DOM 和组件系统,而 Solid 将其粒度保持在它的直接 DOM 更新上。

Vue 重视简单,而 Solid 重视透明度。尽管 Vue 与 Vue 3 的新方向更符合 Solid 所采用的方法。这些库可能会随着时间的推移更加一致,这取决于它们如何继续发展。

Svelte VS Solid

Svelte 开创了 Solid 在一定程度上也采用的预编译消失型框架。这两个库都是真正的响应式,可以生成非常小的执行代码包,尽管 Svelte 是小型 demo 的赢家。Solid 需要在其声明中更加明确,更少依赖编译器的隐式分析,但这正是 Solid 卓越性能的一部分。Solid 还在运行时保留了更多东西,这在更大的应用程序中可以更好地扩展。Solid 的 RealWorld 演示实现比 Svelte 的小 25%。

这两个库都旨在帮助他们的开发人员编写更少的代码,但方法却完全不同。Svelte 3 专注于优化处理本地化更改的易用性,重点是普通对象交互和双向绑定。相比之下,Solid 通过故意采用 CQRS 和不可变接口来专注于数据流。通过功能模板组合,在许多情况下,Solid 允许开发人员编写比 Svelte 更少的代码,尽管 Svelte 的模板语法绝对更简洁。

Knockout.js

这个库的存在归功于 Knockout。该项目的动机是将其用于细粒度依赖性检测的模型现代化。Knockout 于 2010 年发布,支持 Microsoft Explorer 回到 IE6,而 Solid 的大部分内容根本不支持 IE。

Knockout 的绑定只是在运行时遍历的 HTML 中的字符串。它们取决于克隆上下文($parent 等...)。而 Solid 使用 JSX 或 JavaScript API 的标签模板字面量来模板化。

最大的区别可能是 Solid 的批处理更改方法可确保同步性,而 Knockout 具有使用延迟微任务队列的 deferUpdates。

Lit & LighterHTML

这些库非常相似,并且对 Solid 产生了一些影响。大多数情况下,Solid 的编译代码使用非常相似的方法来高效地初始渲染 DOM。克隆模板元素和使用注释占位符是 Solid 和这些库的共同点。

最大的区别是,虽然这些库不使用虚拟 DOM,但它们以相同的方式处理渲染,自上而下,需要组件分区以保持正常。相比之下,Solid 使用其细粒度的响应式图仅更新已更改的内容,并且这样做仅在其初始渲染中技术与之雷同。这种方法利用了仅适用于原生 DOM 的初始速度,并且还具有最高性能的更新方法。

S.js

这个库对 Solid 的反应式设计影响最大。Solid 在内部使用了 S.js 几年,直到特征需求使它们走上了不同的道路。S.js 是迄今为止最高效的响应式库之一。它像数字电路一样对所有同步时间步长进行建模,并确保一致性,而无需执行诸如 MobX 之类的库中的许多更复杂的机制。Solid 的反应性归根结底是 S 和 MobX 之间的一种混合。这使它比大多数反应式库(Knockout、MobX、Vue)具有更高的性能,同时为开发人员保留了易于使用的心智模型。S.js 最终仍然是性能更高的反应式库,尽管除了最严厉的综合基准测试之外,差异几乎不明显。

RxJS

RxJS 是一个响应式库。虽然 Solid 对 Observable 数据有类似的想法,但它有着许多观察者模式不同的应用。虽然 Signal 就像一个 Observable 的简单版本(只有 next),但自动依赖检测的模式取代了 RxJS 的一百个左右的操作符。Solid 有能力采用这种方法,事实上,该库的早期版本也包含类似的运算符,但在大多数情况下,在计算中编写自己的转换逻辑更为直接。在 Observable 是冷启动、单播和基于推送的情况下,客户端上的许多情况都是热启动和多播,这也是 Solid 的默认行为。

其他

Angular 和其他一些流行的库在这个比较中明显缺失。缺乏对这些库的使用经验会妨碍进行任何充分的比较。一般来说,Solid 与较大的框架几乎没有共同之处,而且很难直接比较它们。

常见问题

1. 没有 VDOM 的 JSX? 这是 雾件吗? 我听过像其他框架的作者强调说这是不可能的。

当你没有 React 的更新模型时,这是可能的。JSX 是一个模板 DSL,就像任何其他的模板一样。只是在某些方面更灵活的一种。插入任意 JavaScript 有时可能具有挑战性,但与支持扩展运算符没有什么不同。所以不,这不是雾件,而是一种被证明是最高效的方法。

真正的好处在于它的可扩展性。你有编译器为你工作,为你提供最佳的原生 DOM 更新,但你拥有像 React 这样的库的所有自由,可以使用诸如 Render Props 和高阶组件之类的技术以及响应式钩子来编写组件。不喜欢 Solid 的流程控制? 写你自己的。

2. Solid 的性能如何?

我希望我只需要指出一件事,但它确实是最重要的许多选择决定的:

  1. 显式响应性,因此只跟踪应该反应性的事物。
  2. 编译时考虑到初始创建。Solid 使用启发式算法来松散粒度以减少计算次数,同时保持关键更新的粒度和性能。
  3. 响应式表达式只是函数。这使得 "消失的组件" 能够通过惰性 props 求值移除不必要的包装器和同步开销。

这些是目前独特的技术组合,使 Solid 在竞争中具有优势。

3. 有 React 兼容包吗?

不会。而且可能永远不会有。虽然 API 是相似的,并且组件通常可以通过小的编辑距离策略来移动,但更新模型根本不同。React 组件会一遍又一遍地渲染,因此 Hooks 之外的代码的运行方式非常不同。闭包和钩子规则不仅是不必要的,它们还可以以在 Solid 不起作用的方式使用。

另一方面,Vue-compat 是可行的。虽然目前没有实施的计划。

4. 为什么解构不起作用?我觉得到我可以通过将整个组件包装在一个函数中来修复它。

响应性发生在 Prop 和 Store 对象的属性访问上。在绑定或响应式计算之外引用它们将不会被跟踪。在这些情况下,解构正常工作。

但是,将整个组件包装在一个函数中并不是你想不负责任地做的事情。Solid 没有 VDOM。因此,任何跟踪的更改都会再次运行整个函数,重新创建所有内容。不要这样做。

5. 你能添加对 Class 组件的支持吗? 我发现生命周期更容易推理。

不打算支持类组件。Solid 的生命周期与调度反应系统相关,并且是人为的。我想你可以用它创建一个类,但实际上所有非事件处理器代码基本上都在构造函数中运行,包括渲染函数。这只是你不细化数据要求更多语法的借口。

将数据及其行为组合在一起,而不是将生命周期组合在一起。这是一种已经奏效了数十年的响应式最佳实践。

6. 我真的不喜欢 JSX,模板 DSL 有机会吗? 哦,我看到你标记了标签模板字面量/HyperScript。也许我会用那些...

别。我会马上阻止你。我们像 Svelte 使用他们的模板一样使用 JSX 来创建优化的 DOM 指令。标签模板字面量 和 HyperScript 解决方案确实令人印象深刻,但除非你有真正的理由,例如无构建要求,否则它们在各方面都较差。较大的包、较慢的性能以及需要手动解决方法包装值。

有选择是件好事,但 Solid 的 JSX 确实是最好的解决方案。模板 DSL 也很棒,虽然限制更多,但 JSX 为我们免费提供了很多。现有解析器、语法高亮、TypeScript、Prettier、代码完成,以及最后但并非最不重要的 TypeScript。

我知道其他库一直在增加对这些功能的支持,但这是一项巨大的努力,但仍然不完美,并且一直是维护问题。这也确实是一种务实的态度。

7. 我什么时候使用 Signal 或者 Store? 它们有何不同?

存储自动包装嵌套值,使其成为深层数据结构,是数据模型的理想选择。对于大多数其他情况,Signal 是轻量级的,并且可以出色地完成工作。

尽管我很想将这些包装在一起作为一个单一的 API,但你不能代理基本数据类型。函数是最简单的接口,任何响应式式表达式(包括状态访问)都可以在传输时包装成一个,如果这提供了一个通用 API。你可以随意命名你的 signal 和状态,并且它保持最小。我想要做的最后一件事是在用户端强制键入 .get() .set() 或更糟的 .value。为了简洁起见,至少前者可以使用别名,而后者只是调用函数的最简单的方法。

8.为什么我不能像在 Vue.js Svelte MobX 中那样为 Solid 的 Store 赋值? 有双向绑定么?

响应性是一种强大的工具,但也是一种危险的工具。MobX 知道这一点并引入了严格模式和 Action 来限制更新发生的位置/时间。在 Solid 处理整个组件数据树时,我意识到我们可以从 React 中学到一些东西。只要你提供拥有相同约定的方法,你就不需要实际上是不可变的数据。

能够传递更新状态的能力可以说比决定传递状态更重要。因此,能够将其分开很重要,而且只有在读取不可变的情况下才有可能。如果我们仍然可以粒度更新,我们也不需要付出不可变的成本。幸运的是,ImmutableJS 和 Immer 有大量的现有技术。具有讽刺意味的是,Solid 主要用作具有可变内部结构和不可变接口,和 Immer 刚好相反。

9. 我可以单独使用 Solid 的响应性吗?

当然。虽然我没有导出一个独立的包,但很容易在没有编译器的情况下安装 Solid,只需使用反应 primitive。粒度响应性的好处之一是它与库无关。就此而言,几乎每个反应式库都是这样工作的。这启发了 Solid ,Solid 内部使用 DOM 表达式库 并根据纯粹的响应式系统来创建的渲染器。

列出一些可尝试的库: Solid, MobX, Knockout, Svelte, S.js, CellX, Derivable, Sinuous, 甚至最近的 Vue. 制作响应式库比将其标记到渲染器上工作量要多得多,例如 lit-html,但这有助于帮你找到感觉。

10. Solid 有我可以使用的 Next.js 或 Material Components 之类的库吗?

据我所知没有。如果你有兴趣构建一个,我可以随时在我们的 Discord 上帮助你构建它们。我们有基础,只需要在这些基础上再接再厉。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341