前端的框架是什么意思,前端框架是什么意思

聚客2022-06-01  32

框架是什么(前端框架是什么)

作者:神说要有光来源:神说要有光

最早的时候,页面是由服务器渲染的,也就是PHP和JSP技术。服务器通过模板引擎填充数据,返回生成的html,交给浏览器渲染。届时,表单将同步提交,服务器将返回结果页面的html。

后来有了ajax技术,浏览器可以异步请求,服务器返回xml或者json。Ajax最初是基于xml的,这也是它名字的由来。因为xml有很多不必要的标签,内容更多,所以后来json流行起来。

网页和服务器的数据交互变成了异步,服务器可以返回json数据,在浏览器中拼接html,然后渲染(在浏览器中生成dom相当于渲染)。基本不需要刷新页面,于是后来单页应用SPA(single page application)逐渐演变。

在页面开发初期,使用浏览器的dom api操作dom进行渲染和交互,但是dom api比较啰嗦,当时浏览器的兼容性比较麻烦。不同的浏览器有不同的书写方法。为了简化dom操作,更方便的兼容各种浏览器,jquery出现并迅速流行。当时jquery正如火如荼。

我一直习惯把网页分为物理层和逻辑层。dom是物理层,jquery是一系列操作dom的工具函数,也是网站在物理层的工作。

一个网页所做的事情基本上就是获取数据来渲染dom,在数据发生变化后更新dom。这个过程是普遍的。后来逐渐出现了mv Baxter vm框架自动将数据变化映射到dom,不再需要手动操作dom。也就是vue,react等现代前端框架。我称这一层为逻辑层。

前端框架不仅提供了数据驱动视图变化的功能,还支持dom的逻辑划分,可以将dom的一部分封装成组件,组件之间可以相互组合,形成整个接口。物理层还是dom,但是实现了数据到dom的自动映射之后,我们只需要在逻辑层写组件就可以了。

现在前端入口将不再学习物理层操作dom的jquery,而是直接从vue、react等逻辑层的前端框架开始。

但并不意味着完全不需要jquery。前端框架主要解决数据与dom的绑定,可以在发生变化后自动更新dom。如果不需要更新,直接操作dom就可以了,比如各种活动页面,不需要任何数据更新。用jquery操作dom还是很方便的。

前端框架是UI = f(state)的声明式思想,只需要声明组件的视图、组件的状态数据以及组件之间的依赖关系,那么dom就会在状态发生变化时自动更新。而直接操作dom的工具库jquery则势在必行。

React和vue使用不同的方案来描述视图。react是js对jsX语法的扩展,由babel实现。描述视图时可以直接用JS写逻辑。这没什么新鲜的。Vue是实现一套模板的DSL,引入了插值、指令、过滤等模板语法,比jsx更简洁。模板的编译器由vue实现。

Etemplate受到限制,只能访问数据、属性和方法,这些数据和方法可以进行静态分析和优化。但是react的jsx因为直接是js语法,有更多的动态逻辑,所以不能做静态分析和优化。

但是vue模板也不全是好的,因为它脱离了js上下文,很难引入typescript进行类型派生。您需要分别声明所有类型的属性、方法和数据。而react的jsx和js是同一个上下文,自然要结合typescript。

所以vue templ Baxter ate和react jsx各有优劣。

前端框架是数据驱动的视图变化,这些数据分散在各个组件中。在数据改变后,我们如何更新dom?

基本上只有三种方法可以检测数据的变化:观察、脏检查和不检查。

Vue是一款基于数据的手表。组件级通过Object.defineProperty监控对象属性的变化,重写array的api监控数组元素的变化,然后更新dom。

Angular基于脏检查。在每个可能改变数据的逻辑之后,它比较数据是否已经改变。如果是,它更新dom。

React不检查,不是一直渲染所有dom吗?不,我不勾选是因为我不直接渲染到dom,而是在中间加一层虚拟dom,每次都渲染到这个虚拟dom。然后,diff下渲染的虚拟dom是否有变化,如果有,更新对应的dom。

这就是前端框架数据驱动视图变化的三个思路。

Vue是一个组件级的数据手表。当组件内部有很多地方需要监控数据变化时,一次更新可能会有特别大的计算量,大量的计算可能会导致丢帧,也就是渲染卡顿。所以vue的优化方法是把大的组件拆分成小的,这样每个数据不会有太多的watcher。

React不监听数据变化,而是渲染整个虚拟dom,然后diff。基于该方案的优化方法是通过shouldComponentUpdate跳过不需要重新生成vdom的组件的渲染。

但是当应用的组件树特别大的时候,只有shouldComponentUpdate跳过部分组件渲染,仍然可能导致计算量特别大。如果计算量过大,也可能导致渲染卡顿。我该怎么办?

有两种方法可以遍历树:深度优先和宽度优先。组件树的渲染是深度优先的,一般是通过递归,但是如果路径可以用链表记录,就可以变成循环。当它变成一个循环时,可以按照时间片进行分段,这样vdom的生成就不再阻塞页面渲染,就像操作系统对多个进程的分时调度一样。

把组件树改成链表,把vdom的生成从递归改成循环的功能就是react fiber。

与前面的组件节点相比,纤程节点不具有父节点和子节点的属性,而是具有子节点、兄弟节点和返回节点的属性。

通过纤程链表树,优化了渲染性能。

可以看出,vue的性能优化与react不同:

Vue是一种组件级的数据监控方案,当一个属性中有太多的观察器时可能会出现问题。所以优化的思路是把大的组件拆分成小的,保证每个属性没有太多的观察者。

React不监控检查数据变化,每次都渲染生成vdom,然后对比vdom。然后优化的思路是shouldComponentUpdate跳过部分组件的渲染,在react内部做组件树的链表(纤程)把递归变成可中断渲染,按照时间片逐步生成整个vdom。

组件之间必然存在逻辑复用。react和vue有不同的方案:

vue的组件是option对象,所以通过混合对象属性自然可以想到逻辑复用。vue2中的逻辑复用方案是mixin,但是mixin很难区分混合属性和方法的来源,导致混乱,代码可维护性差。但是没有更好的计划了。

React一开始也支持mixin,后来就放弃了。

react的组件有类和函数两种形式,所以高阶组件类似于高阶函数的方式更加自然,即组件设置组件,在父组件中执行一些逻辑,然后渲染子组件。

除了增加一层组件的HOC方法,没有逻辑的部分可以直接把jsx的那部分作为道具转移到另一个组件中重用,也就是渲染道具。

和hocrenderprops是react的类组件支持的两种逻辑重用方案。

初始函数组件没有状态,只是作为类组件呈现的辅助而存在。

但是,HOC的逻辑复用模式最终导致组件的深度嵌套,类的内部生命周期更多,逻辑放在一起,导致组件更大。

如何解决类组件嵌套深、组件大的问题?你不能引入破坏性的更新,否则你可能会很痛苦。

因此,react团队仔细研究了函数组件。它也能在函数组件中支持状态吗?它不是通过扩展一些API的破坏性更新。

功能组件需要支持状态,那么状态存在于哪里呢?

类节点有一个状态,它在成为纤程节点后仍然存在。功能组件没有状态,因此在纤程节点中也没有状态。

为什么不直接给函数组件的纤程节点添加状态呢?

所以react在函数组件的纤程节点上添加了memorizedState属性来存储数据,然后通过api使用函数组件中的数据,这些API叫做hooks api。

因为使用了纤程节点上的数据,所以这个api被命名为useXxx。

每个钩子api必须有自己的位置来存储数据。如何组织?有两种方案,一种是map,一种是array。

如果使用map,钩子api应该指定键,并根据键访问纤程节点中的数据。

使用数组时,顺序不能改变,所以钩子api不能出现在if之类的逻辑块中,只能出现在顶层。

为了简化使用,hooks最终使用了数组的方式。当然是用链表实现的。

每个钩子api获取相应的fiber.memoriedState中的数据以供使用。

钩子api可以分为3类:

第一种类型是数据类型:

  • UseState:将数据存储在fiber.memoriedState的相应元素中
  • UseMemo:数据存储在fiber.memoriedState对应的元素中,值是缓存函数计算的结果,状态改变后重新计算值。
  • UseCallback:数据存储在fiber.memoriedState对应的元素中,值是一个函数,状态变化后重新执行函数,这是在值是函数的场景下,useMemo的简化api。比如useCallback(fn,[a,b])相当于useMemo(() =本文地址:https://www.diemang.com/post/100461.html.
  • 转载请注明原文地址:https://juke.outofmemory.cn/read/222261.html

    最新回复(0)