Skip to content
导航

为什么需要JS框架

JS框架简介

背景

在基础的前端开发中,开发者通过HTML描述文档结构及内容,CSS描述文档样式,JS执行逻辑、收发请求、控制文档更新。

JS通过操作DOM来控制文档的更新。早期使用jQuery这个库提供的工具方法,来帮助开发者提高开发效率。也出现了ExtJS这种大体量的工具,被归类为JS框架。

什么是库,什么是框架?

分别用jQuery、ExtJS的代码示例来展开说明

jQuery

js
$('body').append('<p>Hello World!</p>')

ExtJS

js
Ext.create('Ext.panel.Panel', {
    title: 'Hello',
    width: 200,
    html: '<p>World!</p>',
    renderTo: Ext.getBody()
})

没有使用过ExtJS,上面示例的实际展示效果与jQuery不完全一致,仅做参考

在上面的例子中,都实现了将Hello World!展示到页面上。

  • jQuery等同于执行了
    js
    const $p = document.createElement('p')
    $p.innerHTML = 'Hello World!'
    document.body.appendChild( $p )
  • ExtJS则提供了一套组件配置,根据传入配置来渲染组件,在正确配置前,你无法预料它会发生什么。

下面是比较清晰的概念区分描述:

  • 库通常是一组松散耦合的代码集合,开发者可以根据自己的需要选择使用其中的部分代码,而不必使用整个库。
  • 框架通常是一种紧密耦合的代码集合,开发者需要按照框架的规范进行开发,否则可能会导致代码不兼容或者无法正常工作。

为什么需要JS框架

JS框架方便选型

如果说JS模块化及构建工具,将前端开发从原始时期进化到“石器时代”,那么JS框架则是使前端开发从石器时代进化到了“工业时代”。

在“石器时代”,开发者在创建项目、为项目增加依赖时,往往要考虑这些依赖将如何与已选的依赖库协作,是否会产生预期外的影响,例如你使用rollup(构建工具) + jQuery(操作DOM) + axios(网络请求)+...
理想情况下,这些库是相互独立,互不影响的。
实际上,jQuery也有$.ajax封装方法,与axios有功能重叠,没有冲突还好,只会造成代码冗余;有代码冲突,就需要考虑避免冲突或更换方案了。

在“工业时代”,开发者在创建项目、为项目增加依赖时,就是在做技术选型,做选择题。例如你选择UI框架是Ant Design,那么框架就要求你使用React库,React生态下就为你准备了Redux等一系列库或工具。这就像RPG游戏点亮技能树,点开一个分支,就会有分支下的细分选择。

JS框架解决的问题

不同JS框架侧重于解决的问题可能不同,例如UI框架Ant Design,它侧重于统一视觉设计风格。

为方便展开后续对React、Vue、Angular、Svelte的介绍,这里说说它们解决的问题。

解决DOM操作性能问题

操作DOM是一个明显消耗页面性能的同步动作,会阻塞页面渲染和交互,在DOM节点多,更新内容多的情况下,性能问题会更突出。

随着应用规模的增长,如何降低DOM操作的性能消耗,成为前端领域热议的问题。

如何降低DOM操作的性能消耗?对于这个问题本身是没有优化方案的,它是一个浏览器特性,开发方案就是尽可能少地操作DOM。

如何减少DOM操作,思路有

  • 将大量DOM替换操作细分为必要的DOM替换或更新
  • 控制频率,将短时间多次DOM操作合并为一次

这些思路都绕不开一个过程,读取DOM的结构→变更结构→根据变更内容应用DOM操作。

更高效的办法是虚拟DOM,直接在JS中维护一个描述DOM结构的对象,更新这个对象后,将更新内容通过DOM操作反映到页面上。

MVVM模式的开发实践

在HTML、CSS、JS开发中,自由度很高,你可以在<head>标签里写样式、脚本,也可以在<body><div>等任何标签里写样式、脚本。

想象一下,你把与某一模块相关的HTML标签的独立的代码通过这种方式写一起,代码示例如下

html
<ul>
  <li>
    <p>这是一个商品</p>
    <button>购买</button>
  </li>
  <style>p{};button{};</style>
  <script>
  function buy(){}
  </script>
</ul>

这样写是可以工作的,但是很容易受到全局样式污染,全局函数也容易被覆盖。

在没有实现作用域命名的情况下,如何组织代码结构避免命名冲突、提高代码可读性、提高项目的可维护性,就成为了工程化问题,早期的解决方案是通过架构模式来解决,从MVC、MVP模式演进到MVVM模式。

  • MVC模式 所有通信是单向的
  • MVP模式 所有通信是双向的,Model和View不直接通信
  • MVVM模式 基本上与 MVP 模式一致,区别是它采用双向绑定:View的变动,自动反映在 ViewModel,反之亦然。

使用React、Vue、Angular、Svelte等框架,就可以应用MVVM模式进行开发实践。

参考资料