跑分方面,这款 JavaScript 库在全球框架榜单中的表现比 React 要好得多

开发 前端
Strve 是一个易用、快速、灵活且轻量级的 JavaScript 库,用于构建用户界面。基于 tagged template 的 HTML 模板引擎,利用 ES6 的模板字符串来进行模板的书写,利用浏览器的原生的能力进行模板渲染。

2021 年 11 月 左右,Strve 第一个版本发布,社区的反馈大部分是支持,也有少部分小伙伴提出了质疑,这都正常。你只要在社区发布一些作品,就必须接受其他人对你的作品的评价。

当初,开发 Strve 的初衷只是受到 JSX 语法的影响,觉得在 JavaScript 中编写 HTML 很酷,所以想能不能自己也开发一个前端框架。我最初给自己的目标就是能在 JavaScript 中写 HTML,然后通过编写 JavaScript 来改变页面状态。经过两个多周的调研,发现自己在原地打转。JSX 语法不能直接在浏览器运行,你必须通过类似 Babel 这种编译工具编译才能运行。所以,我就打算在模版字段串内编写 HTML。但是,又遇到了另一个问题,如何精确更新 DOM。当时,第一个想法就是利用虚拟 DOM,所以就抽时间来学习前端框架中都是怎么利用虚拟 DOM 来精确更新。不懂得就去网上查资料,然后就记下来。可能有些小伙伴就会问,是什么力量让你去做可能完成了也没什么意义的事情。怎么说呢!当时,我就是想要做出点东西来,觉得自己能做出来。至于做出来有什么意义,我没有多想。有时候我们做一件事情之前,考虑很多未必是好事,这往往会阻碍了我们做事情的脚步。

就这样,靠着自己的热情,第一个版本就这么问世了。

有很多小伙伴感觉 Strve 写法很像lit-html。说实话,开发 Strve 之前,我并不知道这个框架。后来看社区反馈,才到网上查看了有关的资料。虽然写法像,但并不是它的复制品。就比如 Strve 内部使用的是虚拟 DOM,这时的虚拟 DOM 还只是一个初版,只能说是简单的比对。

全新的认识

之前有看过我的文章的小伙伴,多多少少会知道 Strve。但是可能也只是停留在知道这个层面上,现在我通过几点来重新介绍下 Strve。

Strve 是一个易用、快速、灵活且轻量级的 JavaScript 库,用于构建用户界面。基于 tagged template 的 HTML 模板引擎,利用 ES6 的模板字符串来进行模板的书写,利用浏览器的原生的能力进行模板渲染。

  • 更容易上手:只要你对 HTML、CSS 和 JavaScript 已经基本熟悉,就可以直接上手。
  • 声明式渲染:我们可以声明式地描述最终输出的 HTML 和 JavaScript 状态之间的关系,开发者可以更加专注于业务逻辑的开发,不需要过多地关心 DOM 操作的细节。
  • 顺滑的用户体验:模板字符串来进行模板的书写,在一些场景中代码智能提示、代码格式化方面不是特别友好。所以,我们提供了新的一种编码方式,我们可以使用 JSX 语法编写 Strve,提升用户开发体验。
  • 性能出色:采用了虚拟 DOM 的模式,虚拟 DOM 使用 diff 算法的方法来计算出真正需要更新的节点,最大限度地减少了 DOM 操作以及 DOM 操作带来的排版与重绘损耗,从而显著提高了性能。另外,我们的 JavaScript 库在全球知名的测评榜单(js-framework-benchmark)上赢得了优秀的成绩。
  • 组件化:一个函数就是一个组件,可以根据应用规模任意组合。并且组件特有的 “孤岛特性”,使得将虚拟 DOM 树计算的级别控制在组件级别。
  • 灵活的应用场景:有无构建工具都可以使用,并且可以适配到其他前端框架开发的应用项目中去。
  • 轻量级:压缩后的文件大小不足 10k。另外,可以根据不同应用场景,选择不同类型的文件。

想要了解更多关于 Strve 的特性,可以到官方中文文档中去探索。

https://strvejs.gitee.io/strve-doc-zh。

贴心的优化

2023 年我陆续发布了几个大的版本,大部分时间都是在优化底层代码。包括虚拟 DOM 的算法优化、减轻使用 API 时 心智负担等等优化措施。

下面我们来展开看下。

如果你不打算使用构建打包工具开发项目,而是直接开发。推荐使用全局构建版本,通过 CDN 使用 Strve 时,不涉及“构建步骤”,这使得设置更加简单。

<script src="https://cdn.jsdelivr.net/npm/strve-js@6.6.6/dist/strve.full.prod.js"></script>
<script>
  const { html, defineComponent } = Strve;

  defineComponent(
    {
      mount: '#app',
    },
    ({ setData }) => {
      let count = 0;

      function add() {
        setData(() => {
          count++;
        });
      }

      return () => html`<h1 onClick=${add}>${count}</h1>`;
    }
  );
</script>

模板字符串来进行模板的书写,在一些场景中代码智能提示、代码格式化方面不是特别友好。所以,我们提供了一种新的编码方式,我们可以使用 JSX 语法编写 Strve 应用,这样就大大提升了用户开发体验。

defineComponent(() => {
  const state = {
    msg: 'Hello',
  };
  return () => h1>{state.msg}</h1>;
});

另外,我们底层采用了虚拟 DOM 的模式,虚拟 DOM 使用 diff 算法的方法来计算出真正需要更新的节点,最大限度地减少了 DOM 操作以及 DOM 操作带来的排版与重绘损耗,从而显著提高了性能。

Strve 应用程序是由 组件 组成的。一个组件是 UI(用户界面)的一部分,它拥有自己的逻辑和外观。组件可以小到一个按钮,也可以大到整个页面。

在 Strve 中,组件就是一个函数。

const MyComponent = defineComponent(({ setData }) => {
  let count = 0;

  function add() {
    setData(() => {
      count++;
    });
  }

  return () => (
    <div class='MyComponent'>
      <p>{count}</p>
      <button onClick={add}>MyComponent</button>
    </div>
  );
});

// 复用组件
defineComponent(
  {
    mount: '#app',
  },
  ({ setData }) => {
    let count = 0;

    const add = () => {
      setData(() => {
        count++;
      });
    };

    return () => (
      <div class='App'>
        <p>{count}</p>
        <button onClick={add}>App</button>
        <component $is={MyComponent} />
      </div>
    );
  }
);

Strve 内部的渲染系统是基于虚拟 DOM 构建的,虚拟 DOM (Virtual DOM,简称 VDOM) 是一种编程概念,意为将目标所需的 UI 通过数据结构“虚拟”地表示出来,保存在内存中,然后利用 Diff 算法来比对新老数据,将真实的 DOM 与之保持同步。

如何虚拟 DOM 树过于庞大,使得 Diff 计算时间大于 16.6ms,那么就可能造成性能的卡顿。组件有一个特性就是 ”孤岛“。何为“孤岛”,孤岛就是在 Strve 应用中我们可以理解成一个独立的模块。将一个庞大的虚拟 DOM 树分解成很多独立的模块,这样 Diff 计算时间就会控制在组件级别,大大缩减了计算的时间,提高了性能。

从 API 层面,我们尽可能的贴合易用的特性,将核心 API 缩减为 2 个。分别为defineComponent和setData。框架是需要容易使用的,太多繁琐的设置或者操作很容易增重心智负担。

丰富的生态

开发框架单单只有一个核心库肯定是不够的,你还需要其他生态工具来加以辅助。

你要有一套用于快速构建项目的命令行工具,也就是说用户可以通过输入命令快速搭建项目。CreateStrveApp 是一套用于快速构建 Strve 项目的命令行工具。CreateStrveApp 是使用 Vite 构建的,这是一个新的前端构建工具,可以显着提升前端开发体验。它有几个模版可供选择:strve、strve-apps、strve-jsx、strve-jsx-apps。

我们开发项目需要跳转多个页面,那么就需要路由管理器。StrveRouter 是 Strve 的官方路由管理器。它与 Strve 的核心深度集成,轻松构建单页应用程序。

另外,我们介绍两款编译时工具。BabelPluginStrve是一款 babel 插件,将 HTML 模板字符串转化为 Virtual Dom。从之前的运行时转移到编译时,大幅度提高渲染性能。如果你想使用 JSX 语法,BabelPluginJsxToStrve这款插件是必不可少的,它是一款 babel 插件,将 JSX 转换为与 Strve 一起使用的标记模板。CreateStrveApp 项目脚手架工具已默认安装,选择 strve-jsx 或者 strve-jsx-apps 模版即可。我们使用 CreateStrveApp 搭建完 Strve 项目你会发现,同时安装了 BabelPluginStrve、BabelPluginJsxToStrve,这是因为我们需要使用 BabelPluginJsxToStrve 将 JSX 转换为标签模版,之后再使用 BabelPluginStrve 将标签模版转换为 Virtual DOM。

我们最后压轴的一款生态工具可以说是近期更新力度最大的了。它被称为独立运行的可响应性 Strve,由 @vue/reactivity和 strve-js 提供支持的自定义元素 JavaScript 库。

主要特性有以下几个:

  • Web Components
  • Hooks
  • Reactivity API
  • Props
  • Emit
  • Slot
  • Styles
  • Automatic registration component
  • Virtual DOM

Strve 结合 Vue 组合式 API 形成了一款新的 JavaScript 库。只要你熟悉组合式 API,就可快速上手。

// MyComponent.jsx
import { ref, defineComponent, reactive } from 'strve-reactivity';

const MyComponent = defineComponent(() => {
  const items = reactive([
    {
      id: 1,
      tit: 'A',
    },
    {
      id: 2,
      tit: 'B',
    },
  ]);
  const count = ref(4);
  const increase = () => {
    items.unshift({
      id: count.value++,
      tit: 'C',
    });
  };

  return () => (
    <fragment>
      <button onclick={increase}>increase</button>
      <ul>
        {items.map((item) => (
          <li key={item.id}>
            <span>{item.id}</span>
            <span>-</span>
            <span>{item.tit}</span>
          </li>
        ))}
      </ul>
    </fragment>
  );
});

出色的跑分

我们只是口头说 Strve 性能是非常不错的,没有真凭实据那是说不过去的。跑分方面,Strve 在 js-framework-benchmark 中的表现比 React 要好得多。

图片

https://krausest.github.io/js-framework-benchmark/current.html。

巨人的肩膀

前端框架最近几年来层出不穷,出现这种情况好吗?我觉得是个好现象。大家都在为前端社区贡献自己的力量,使得前端的生态生机勃勃。

大家可能非常讨厌跟知名框架比较,可能有些人会说蹭热度。其实不妨换个角度想想,为什么会比较,是因为要更好。怎么样才能更好,那只能不断地优化。那么在这优化的过程中你不光是做出一个 JavaScript 库或者前端框架,更多的是你可以从中获得你在平时工作中得不到的东西。比如,对设计一款框架需要考虑哪些方面。作者在设计 API 时为什么会这么设计等等一些非工作业务上的事情。

我开发这款 JavaScript 库,我是另辟蹊径吗?我感觉并不是,我只是学习其他优秀框架中可以借鉴的思想,并按照自己想要的方式去展现它。只有站在巨人的肩膀上才能望得更远!

责任编辑:姜华 来源: 前端历劫之路
相关推荐

2012-09-20 09:28:26

PHP程序Web

2012-09-24 11:14:06

PHP编程语言Web开发

2020-08-26 15:31:52

选择

2023-03-20 07:48:03

2022-09-27 15:23:53

微软Windows 11Windows 10

2011-07-26 11:07:45

FacebookiPad

2023-10-26 00:33:51

JS框架React

2010-04-27 15:08:01

2022-10-17 13:33:25

云平台云计算服务

2023-02-15 17:26:11

Java实例化系统

2022-08-29 14:59:12

深度学习树的模型神经网络

2010-08-17 15:21:17

IEFirefoxHTML

2012-10-11 10:04:36

网络能耗思科

2012-07-24 09:00:18

键盘Windows 8

2022-05-05 20:57:20

谷歌Chrome浏览器

2010-11-02 10:44:12

2015-06-24 10:38:53

数据中心灾备计划

2020-11-26 15:30:05

VueReac前端

2017-01-03 19:12:56

数据中心冷却机架

2023-07-07 07:48:54

点赞
收藏

51CTO技术栈公众号