大家好,我是 anuoua ,我写了个前端框架,叫 Unis,Github 。
前些天我终于把我的框架送上了这个榜单 js-framework-benchmark,相信很多人都知道这个榜单,这是目前前端框架衡量性能最受欢迎的跑分榜单,非常开心能够上榜和其他框架一起掰头!
起因
我写 Unis 已经很久了,在它身上倾注了很多心血和点子,最近我也开始全面拿它开发小项目了,使用体验相当满意。
但是,Unis 一直没人关注,Github 星星寥寥无几。所以在一次偶然的机遇中,我在 Nuxt 核心成员 antfu 的《开源探店》项目中做了个开源项目的自荐推广,在直播当天,antfu 给了我不少建议,其中一个建议,就是让我把自己的框架放入到 js-framework-benchmark 这个榜单,这样可以吸引更多的人。于是我就记下了,总有一天我要把框架放上去!
时机成熟
相信有些人看到过我之前发的文章《我终于可以不依赖 Vue 3 和 React 了!Unis 1.2.0 正式发布!支持 SSR》,这是 Unis 完善的标志,这个版本剥离了 runtime 和 core,可支持跨端,意味着时机终于成熟了!
我可以开始准备这个榜单的 PR 了!
添加到榜单
如何加入这个榜单,具体的可以看项目 README ,这里我简要介绍一下,说白了要加入这个榜单,只需要写一个使用了自己框架的网页,这个网页需要实现指定的功能,还需要使用统一的样式,把每一种操作都实现一遍。
咱们先把项目 clone 下来
git clone https://github.com/krausest/js-framework-benchmark.git
在如下目录中创建子目录,一般都是 keyed 目录,keyed 是指在处理 list.map 的时候使用 key 做优化的框架,个人觉得没必要做区分。
然后创建项目
unis
├── index.html
├── package-lock.json
├── package.json
├── src
│ └── main.jsx
└── webpack.config.js
对于榜单来讲,它只关心两个命令,一个命令用来开发构建(自己调试用),一个命令用来生产构建(跑分用)
// package.json
{
"scripts": {
"build-dev": "webpack --mode development --watch",
"build-prod": "webpack --mode production"
}
}
至于是使用 webpack 还是 vite 构建并不重要,只要最终能构建出符合要求的应用就好,这里需要注意的一点是样式文件要直接使用项目中根目录下 css 文件夹下的样式文件,不要在打包的时候打包进去,不符合规范,还会影响你的加载性能。
测试用例实现
榜单的测试用例分解后只有6个操作,分别是
- 创建 1000 行
- 创建 10000 行
- 添加 1000 行
- 每隔 10 行更新
- 清除所有行
- 交换行
实现后操作区域的效果图
Unis 的实现也就一百多行,但是这里的一些细节其实蛮多的,自己写还是有一点麻烦。想到 Unis 可以很快速的移植 React 代码,我就直接 Copy 了 React 的实现,改成 Unis 的 API,得益于视图部分和 React 的高度兼容,实现瞬间完成,太高效了!
打包编译后只产生一个 main.js 文件,榜单加载的入口是 keyed/unis 目录的 index.html ,用它加载 main.js
unis
├── dist
│ └── main.js
├── index.html // 入口
├── package-lock.json
├── package.json
├── src
│ ├── main.jsx
│ └── pre.js
└── webpack.config.js
跑分
准备就绪了,那就开跑吧!
npm start # 先开启静态服务器 http://localhost:8080
npm run bench -- --framework keyed/unis # 开始跑分
然后它就会使用 puppeteer 打开窗口开始跑测试用例。
等所有的测试用例跑完后,运行 npm run results
,就会在根目录下创建 webdriver-ts-results 文件夹,里面有个 table.html ,这就是跑分结果,直接访问 http://localhost:8080/webdriver-ts-results/table.html 可以查看。
提交 PR
代码搞定了,自测也通过了,那就提交吧!我的 PR 在这里 github.com/krausest/js… ,5 月 10 号正式合入,在 chrome 114 版本出来后成绩正式上线!
跑分结果分析
因为全部框架跑一边时间很久,可能要一天,所以我们就直接看官网的数据吧(它跑的和我不一样,我本地跑分 Unis 会更好),krausest.github.io/js-framewor…
先看第一页,嗯..没找到 Unis。
再看第二页…第三页,终于找到了,在如图位置!
参与测试的框架共有 138 个,Unis 排在第 61 位,居然还可以,可以看到 Vue 3 在前面,性能确实更好,svelte 也是,但是稍逊 Vue 3,Unis 居然击败了 Angular!?
对了,React 在哪里?看了一下,它在稍后一点点位置上!排名 92 (react-hooks)。
从最终结果看 Unis 的性能表现还是可以的,至少也是主流框架水平!
这里有个疑问,为什么 React 会比 Unis 慢,Unis 和 React 核心原理类似,本质上应该是同等级的性能表现,但是为什么 React 会慢一点呢?我们再细看对比一下:
可以发现,React 在不少子项上都是比 Unis 稍快的,但是在交换行,创建大量行 这几个测试项上性能表现就很糟糕,会有几百毫秒的差距,所以综合性能分上 Unis 会比 React 排名高。
至于为啥交换行这个用例 React 表现会这么差,其实很简单,因为 React diff 是单向的,而 Unis 使用的是双端 diff ,在这种用例下有天然的优势。当然 Unis 为了这个也付出了浪费内存的代价,Unis 的内存占用高于 React。
对榜单的一些看法
这个榜单测试的是整体性能(既从框架运行开始,到浏览器绘制结束),并不能区分框架运行耗时和 dom 本身耗时,有些用例 js 部分耗时很低,但是最终耗时没有拉开差距,比如下面这种情况:
创建 10000 行,它的总时间在 577 ms, js 只占了 156 ms,dom 占了416 ms,那么 dom 性能占比远高于框架运行的部分,由于每次跑分都会有波动,这样就导致很难看清框架本身的性能水平,目前项目作者正在开发一个 js-only 模式,可以看这个 Issue,可以做到评估 js 部分的耗时,到那个时候,排行榜将会发生重大的变化!
我的预测,wasm 框架将是独一档,solidjs 这类无虚拟 dom 框架另起一档,其他的都往后稍稍。
最后
很开心自己能够完成之前的目标,登上榜单和全世界框架 PK 是一件很有意义的事情。
如果大家感兴趣,可以关注一下 Unis,www.github.com/anuoua/unis , 谢谢!