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

最初的动机

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 个。分别为defineComponentsetData。框架是需要容易使用的,太多繁琐的设置或者操作很容易增重心智负担。

丰富的生态

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

你要有一套用于快速构建项目的命令行工具,也就是说用户可以通过输入命令快速搭建项目。CreateStrveApp 是一套用于快速构建 Strve 项目的命令行工具。 CreateStrveApp 是使用 Vite 构建的,这是一个新的前端构建工具,可以显着提升前端开发体验。它有几个模版可供选择:strvestrve-appsstrve-jsxstrve-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/reactivitystrve-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 库,我是另辟蹊径吗?我感觉并不是,我只是学习其他优秀框架中可以借鉴的思想,并按照自己想要的方式去展现它。只有站在巨人的肩膀上才能望得更远!

有趣的事情

前不久,我在 Github 上创建了 Strve 组织。

在这里插入图片描述

如果,你愿意跟我一块做这件有趣的事情,欢迎加入 Strve 大家庭。

有意向的可以在 Strve 源码仓库提 issues或者在评论区私信我。

源码仓库:https://github.com/strveJs/strve

中文文档:https://strvejs.gitee.io/strve-doc-zh/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/638163.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ElasticSearch 7.x现网运行问题汇集2

问题描述 现网indices有数据&#xff0c;如下&#xff0c;GET /_cat/indices得到的结果里&#xff0c;待查索引显示有数据472033条&#xff0c;但是Postman 发查询语句GET /_search match_all&#xff0c;查不出数据&#xff1b;GET /_count也是0。索引状态也是open&#xff0…

【AI】深度学习在编码中的应用(9)

接上&#xff0c;本文来讨论基于条件熵编码的框架。 智能图像压缩中的基于条件熵编码的框架是一种先进的编码技术&#xff0c;它利用图像数据的统计特性来实现高效的压缩。以下是关于该框架的定义、原理、优势和劣势&#xff0c;以及关键技术的详细解释&#xff0c;同时包括框…

循序渐进学 JavaScript <二>

续 <一> 九、JavaScript常见内置类 9.1 原始类型的包装类 基本数据类型也可以调用属性 在理论上来说它们是没有办法获取属性或者调用方法的 原始类型是简单的值&#xff0c;默认并不能调用属性和方法js 为了可以使其获取属性和调用方法&#xff0c;对其封装了对应的包装…

CTFhub-bak文件

CTFhub-Web-信息泄露-备份文件下载-bak文件 题目信息 解题过程 看到提示说和index.php有关&#xff0c;在url后面加index.php.bak&#xff0c;跳转到http://challenge-7a4da2076cfabae6.sandbox.ctfhub.com:10800/index.php.bak网址&#xff0c;即&#xff1a; 跳转到下载页…

清理docker 无用数据

df -h 查看 overlay 使用88% docker ps 我只要跑一个 把没有用的删除了去 让chatgpt 帮搞一搞 删除未使用的 Docker 镜像、容器、卷和网络&#xff0c;您可以按照以下步骤操作。请注意&#xff0c;在进行这些操作之前&#xff0c;确保您不再需要这些资源&#xff0c;因为删…

numpy/torch中的广播机制

广播的作用 用于描述如何在算术运算期间处理具有不同形状的数组。 在满足特定限制的前提下&#xff0c;较小的数组“广播至”较大的数组&#xff0c;使两者形状互相兼容。 广播提供了一种矢量化数组操作的方法&#xff0c;以便在C而不是Python中进行循环。它可以在不制作不必要…

Elasticsearch的映射操作

本文来记录下Elasticsearch的映射操作 文章目录 映射的概述 映射的概述 Elasticsearch与mysql数据库对比 映射的概述 有了索引库&#xff0c;等于有了数据库中的 database。索引库(index)中的映射&#xff0c;类似于数据库(database)中的表结构(table)。创建数据库表需要设置字…

MySQL自增ID耗尽探究:分析与解决方案

MySQL自增ID耗尽探究&#xff1a;分析与解决方案 一、引言 在面试过程中&#xff0c;面试官抛出了一个看似简单却又深入的问题&#xff1a;“MySQL的自增ID用完了&#xff0c;怎么办&#xff1f;” 自增ID耗尽可能看似遥远&#xff0c;但在处理大量数据的系统中&#xff0c;…

一文理解Python选择语句

在编程领域中&#xff0c;条件判断和选择是非常基础而且重要的一个部分。Python 作为一种被广泛应用的编程语言&#xff0c;提供了多种选择语句来满足不同的条件判断需求。本文将深入探讨 Python 中的选择语句&#xff0c;包括 if 语句、elif 语句、else 语句、简写的条件表达式…

有什么提高编程能力的书籍推荐吗?

数据密集型应用系统设计 原文完整版PDF&#xff1a;https://pan.quark.cn/s/d5a34151fee9 这本书的作者是少有的从工业界干到学术界的牛人&#xff0c;知识面广得惊人&#xff0c;也善于举一反三&#xff0c;知识之间互相关联&#xff0c;比如有个地方把读路径比作programming …

翻译: Anaconda 与 miniconda的区别

Anaconda 和 miniconda 是广泛用于数据科学的软件发行版&#xff0c;用于简化包管理和部署。 1. 主要有两个区别&#xff1a; packages包数量&#xff1a; Anaconda 附带了 150 多个数据科学包&#xff0c;而 miniconda 只有少数几个。Interface接口&#xff1a;Anaconda 有…

基于USRP的Python开发

安装UHD和Python API 下面的终端命令应该构建和安装最新版本的UHD&#xff0c;包括Python API&#xff1a; sudo apt-get install git cmake libboost-all-dev libusb-1.0-0-dev python3-docutils python3-mako python3-numpy python3-requests python3-ruamel.yaml python3-…

优先级队列(堆) PriorityQueue

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 1.优先级队列 2.优先级队列的模拟实现 2.1 堆的概念 2.2 堆的创建 2.3 堆的插入和删除 2.…

MySQL(视图,存储函数,存储过程)

作业1&#xff1a; 作业实现&#xff1a; 首先创建学生表&#xff0c;课程表&#xff0c;以及学生选课表。 CREATE TABLE Student (Sno INT PRIMARY KEY,Sname VARCHAR(20) NOT NULL,Ssex CHAR(1) CHECK (Ssex IN (男, 女)),Sage INT,SDept VARCHAR(20) DEFAULT 计算机 );CRE…

CoverM contig mean 和 trim_mean 方法原理

由于 CoverM 存储库更新, 记录的代码可能与最新代码稍有不同 Contig 分析 mean 方法 contig 方法的入口位于 src/bin/coverm::main 的 “contig” 分支中, 忽略帮助等参数, 假设已有 bam 文件, 不设置 reads 的额外 filter_params, 则函数主体简写如下:fn main() {let mut ap…

4. seaborn-线性关系可视化

Seaborn本身并不是为了统计分析而生的&#xff0c;seaborn中的回归图主要用于添加视觉指南&#xff0c;以帮助在探索性数据分析EDA中强调存在于数据集的模式。 import numpy as np import matplotlib.pyplot as plt import seaborn as sns import warningssns.set(stylewhiteg…

JDK 版本切换工具 JEnv

1. 下载 JEnv 包 下载地址&#xff1a; JEnv-for-Windows 下载 JEnv.zip 然后解压缩&#xff0c;放到一个目录下&#xff0c;我这里放到了目录&#xff1a;D:\Program Files\JEnv 2. 将 JEnv 添加到环境变量 首先先在自己的电脑上去下载 JAVA 的各个版本&#xff0c;我这里…

二、简单控件

二、简单控件 #mermaid-svg-TR8KwIeb54zOjfmt {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-TR8KwIeb54zOjfmt .error-icon{fill:#552222;}#mermaid-svg-TR8KwIeb54zOjfmt .error-text{fill:#552222;stroke:#55222…

正反转控制电路图

1、倒顺开关正、反转控制电路图 倒顺开关直接接在主电路中&#xff0c;不适合用作大容量的电动机控制&#xff0c;一般用在额定电流10A、功率3kW以下的小容量电动机控制电路中。 2、接触器联锁正、反转控制电路图 接触器联锁正、反转控制电路的主电路中连接了两个接触器KM1和…

从零开始c++精讲:第四篇——模板初阶

文章目录 一、泛型编程二、函数模板2.1函数模板概念2.2函数模板格式2.3函数模板原理2.4函数模板实例化2.5函数模板匹配原则 三、类模板3.1类模板的定义格式3.2类模板的实例化 一、泛型编程 如何实现一个通用的交换函数呢&#xff1f; void Swap(int& left, int& righ…