Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于前端框架设计的一些思考 #30

Open
FE-Sadhu opened this issue May 6, 2023 · 0 comments
Open

关于前端框架设计的一些思考 #30

FE-Sadhu opened this issue May 6, 2023 · 0 comments
Labels
技术方案 Pull requests that update a dependency file

Comments

@FE-Sadhu
Copy link
Owner

FE-Sadhu commented May 6, 2023

框架的通用之处

核心思路

任何现代 UI 库的设计抽象来说都符合一个公式:

                                             UI = f(state)

UI 即代表描述 UI 的数据结构,state 代表状态,f 代表转换 state 为 UI 的内部运行机制。而各个库的主要区别点就是 f 的实现不同。

换句话说,现代 UI 库都是状态(state)驱动(f)视图(UI),符合 MVVM 架构。

Model(state)改变 -> ViewModel(虚拟 DOM、Fiber 树类似描述 UI 的数据结构)改变 -> View(视图)改变。

组件

先来想想组件这个产物为什么会出现?

试想就算状态驱动视图,若状态与视图都维护在一个地方,开发者关注点集中在此,代码越多越容易乱。

一般这种情况下,如果是纯 JS 逻辑我们会考虑「拆分逻辑到不同的模块去管理」,那么完整逻辑就由各个模块的逻辑组合而成,若遇到问题,定位到对应模块修改,拆得好就不会影响到其他模块。这就是一种关注点分离,大逻辑分散到一个个小逻辑中,可维护性很好。同时我们在拆逻辑的时候若遇到使用频率高的逻辑,可以再拆成一个模块,再遇到就可以直接复用了,显然也提升了代码复用性。

在这个思维基础上加上视图呢?就是「拆分逻辑和视图到不同的模块去管理」。此时这个模块就是所谓组件。对比拆分模块,完整的逻辑和视图被拆分到一个个组件中,某块 UI 遇到问题就定位到具体组件去处理,拆得好就不会影响到其他 UI,一样得,若发现使用频率高的逻辑和视图,则可以再拆成一个公共组件,再遇到直接复用。

所以我觉得出现组件的本质原因是「关注点分离」,组件的定义就是 UI 工程中封装了状态、逻辑及视图的松散耦合单元。

我们知道了组件的意义,那怎么去拆呢?

我觉得只要遵循着职责清晰(耦合程度)逻辑清晰(易于阅读)可复用性好的前提下去拆组件就好。这没有绝对的银弹,并不意味着耦合度越低、灵活性越高就代表组件设计得好。比如对于开发各个团队通用的组件库时,把一个组件设计得很灵活是好事,可以提供不同 props 给开发者控制该组件不同功能。但是针对拆业务组件,只要你这一整块业务逻辑就是很多地方都需要用到的,并且代码量不算很大,编码逻辑清晰,那设计成一个大组件有何不可呢,再拆成粒度更细的一个个小组件则无意义了。

我认为组件、MVVM 都是在社区中经过实践一路演变来的利于软件工程开发的架构级别产物。目前各类前端框架还是实践着这类架构级别产物,没有说有哪个框架开创出一种更有优势的架构。

框架的不同之处

既然架构级别产物是通用的,理论上用 React 也能很好地开发完成需求,那为什么有其他框架的诞生呢?私认为这个话题离不开商业相关,一是有需求的地方就有市场,二是研究竞品创造可能有的需求来达到有市场的目的。

从用户使用的角度来看

以 React、Vue、Svelte 来讨论

  • React 是提供了相对较少的 API,给予开发者比较大的自由去进行开发,但是这些 API 的使用除了文档以外,需要开发者理解 React 的心智模型才能用得好,否则新手开发者容易写出 bug 或遇到性能瓶颈不知道怎么解决问题。
  • Vue 则是提供了相对较多的 API 以及一些约束,降低灵活性但是使得开发者学习了文档后能 hold 住大部分问题,对新手友好。
  • Svelte 为了 React 用户易上手,设计 API 时尽量贴近 React API 风格。

从产物性能的角度来看

用户的操作肯定是代码运行时的行为,理论上运行时发生的行为造成的代码执行量越少越不容易让用户感觉卡顿(掉帧)。

  • React 对于用户操作的反应路径是:用户操作导致状态改变 -> 从整个项目根节点开始 DFS 找出可复用的节点或状态改变导致有变化的节点 -> 提交到 UI 上
  • Vue 对于用户操作的反应路径是:用户操作导致状态改变 -> 根据绑定关系直接找出状态所在组件,diff 组件内的所有节点,找出可复用或有变化的节点 -> 提交到 UI 上
  • Svelte 对于用户操作的反应路径是:用户操作导致状态改变 -> 根据绑定关系直接找出状态对应节点并进行改变 -> 提交到 UI

可以感知到,运行时状态改变,尽管各个框架的目的都是找出变化的节点,对应改变 UI。但是由于内部实现机制不同, React 要从根节点开始找,Vue 从组件开始找,Svetle 直接找到对应节点。

所以,产物性能相较下来就是 React 够用、Vue 好一些、Svelte 最好。

想到什么再补充...

@FE-Sadhu FE-Sadhu added the 技术方案 Pull requests that update a dependency file label May 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
技术方案 Pull requests that update a dependency file
Projects
None yet
Development

No branches or pull requests

1 participant