前端框架的优缺点
Vue
Vue优点
- 简单:官方文档很清晰,比 Angular 简单易学。
- 快速:异步批处理方式更新 DOM。
- 组合:用解耦的、可复用的组件组合你的应用程序。
- 紧凑:~18kb min+gzip,且无依赖。
- 强大:表达式 无需声明依赖的可推导属性 (computed properties)。
- 对模块友好:可以通过 NPM、Bower 或 Duo 安装,不强迫你所有的代码都遵循 Angular 的各种规定,使用场景更加灵活。
Vue缺点
- 新生儿:Vue.js是一个新的项目,没有angular那么成熟。
- 影响度不是很大:google了一下,有关于Vue.js多样性或者说丰富性少于其他一些有名的库。
- 不支持IE8
Angular
Angular优点
- 模板功能强大丰富,自带了极其丰富的angular指令。
- 是一个比较完善的前端框架,包含服务,模板,数据双向绑定,模块化,路由,过滤器,依赖注入等所有功能;
- 自定义指令,自定义指令后可以在项目中多次使用。
- ng模块化比较大胆的引入了Java的一些东西(依赖注入),能够很容易的写出可复用的代码,对于敏捷开发的团队来说非常有帮助。
- angularjs是互联网巨人谷歌开发,这也意味着他有一个坚实的基础和社区支持。
Angular缺点
- angular 入门很容易 但深入后概念很多, 学习中较难理解.
- 文档例子非常少, 官方的文档基本只写了api, 一个例子都没有, 很多时候具体怎么用都是google来的, 或直接问misko,angular的作者.
- 对IE6/7 兼容不算特别好, 就是可以用jQuery自己手写代码解决一些.
- 指令的应用的最佳实践教程少, angular其实很灵活, 如果不看一些作者的使用原则,很容易写出 四不像的代码, 例如js中还是像jQuery的思想有很多dom操作.
- DI 依赖注入 如果代码压缩需要显示声明.
React
React优点
- 速度快:在UI渲染过程中,React通过在虚拟DOM中的微操作来实现对实际DOM的局部更新。
- 跨浏览器兼容:虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。
- 模块化:为你程序编写独立的模块化UI组件,这样当某个或某些组件出现问题是,可以方便地进行隔离。
- 单向数据流:Flux是一个用于在JavaScript应用中创建单向数据层的架构,它随着React视图库的开发而被Facebook概念化。
- 同构、纯粹的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 的性能如何?
我希望我只需要指出一件事,但它确实是最重要的许多选择决定的:
- 显式响应性,因此只跟踪应该反应性的事物。
- 编译时考虑到初始创建。Solid 使用启发式算法来松散粒度以减少计算次数,同时保持关键更新的粒度和性能。
- 响应式表达式只是函数。这使得 "消失的组件" 能够通过惰性 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 上帮助你构建它们。我们有基础,只需要在这些基础上再接再厉。