• unocss 究竟比 tailwindcss 快多少?


    unocss 究竟比 tailwindcss 快多少?

    前言

    我们知道 unocss 很快,也许是目前最快的原子化 CSS 引擎 (没有之一)。

    unocss 解释它为什么这么快的原因,是因为它不用去解析 CSS 抽象语法树,直接在 content 里面通过正则表达式从内容中提取 token,然后生成样式。

    这点从 unocss 官方提供目前最新的测试结果可以看到(2023-08-11 版本):

    11/8/2023, 3:53:41 PM
    1656 utilities | x200 runs (75% build time)
    
    none                             33.99 ms / delta.      0.00 ms
    unocss       v0.57.2            359.46 ms / delta.    325.47 ms (x1.00)
    tailwindcss  v3.3.5            1238.25 ms / delta.   1204.26 ms (x3.70)
    windicss     v3.5.6            1742.45 ms / delta.   1708.46 ms (x5.25)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以看到 unocsstailwindcss3.7 倍左右。

    其中官方的 unocss 测试素材,使用的是 vite + @unocss/vitetailwindcss 测试素材则是 vite + postcss + tailwindcss

    可是假如我们以 vite / webpack 插件的方式去使用 unocss 的话,默认是不支持 tailwindcss 那些 @apply, @screen, theme() 这些 CSS 指令的。

    这时候我们就需要额外去安装 @unocss/transformer-directives 这个包,并在 uno.config.ts 文件中注册来支持这些功能。

    可是,当我们查看这个包的依赖的时候,发现它其实也是去使用一个 CSS AST 工具:css-tree 去解析操作抽象语法树的。

    也就是说,unocssvite/webpack 插件的方式,去实现的那些在 tailwindcss 内置的 css 指令不免也要解析成 AST

    那么这种时候,它又能比 tailwindcss 快多少呢?

    开始测试

    这里我做了一个基准测试,unocss 只加载 @unocss/preset-uno@unocss/transformer-directivestailwindcss 为默认注册安装。

    测试素材以及代码 forkunocss 官方 bench,和官方 bench 不同的是,我为了同时为了模拟平常的开发场景,我还加入了等量的 @apply 指令,这样它们都免不了要去解析 CSS 抽象语法树。属于是给 2 者增加负重了。

    测试设备都为 Mac Book M1 (2021), 跑 200 次,取 75%

    源代码链接

    运行后,测试结果如下所示:

    2024/3/5 00:19:14
    1656 utilities | x200 runs (75% build time)
    
    none                             19.92 ms / delta.      0.00 ms 
    unocss       v0.58.5            328.39 ms / delta.    308.47 ms (x1.00)
    tailwindcss  v3.4.1             798.42 ms / delta.    778.49 ms (x2.52)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    可以看到在 1656 utilities 个工具类提取 + @apply 的场景,作为 vite 插件使用的 unocss 速度差不多是 tailwindcss2.52 倍左右。

    相比 unocss 原先的测试结果,对比 tailwindcss 的速度从 3.7 倍 降低到了 2.52 倍。

    可见 CSS 抽象语法树的解析,还是显著的降低了 unocss 的速度,不过成绩依然是可喜的,非常厉害。

    postcss 方式

    当然,想要支持 tailwindcss@apply , @screen , theme() 这些 CSS 指令,不止上面这一条路。

    我们也可以使用 @unocss/postcss 这个 postcss 插件去达成这样的目的。

    另外我也做了一个同样基于 postcss 插件的基准测试,unocss 只加载 @unocss/preset-uno,测试环境也和上一个一样。

    源代码链接

    测试结果如下:

    2024/3/5 00:08:25
    1656 utilities | x200 runs (75% build time)
    
    none                             16.75 ms / delta.      0.00 ms 
    unocss       v0.58.5            679.51 ms / delta.    662.77 ms (x1.00)
    tailwindcss  v3.4.1             712.55 ms / delta.    695.80 ms (x1.05)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    不出所料,果然在都需要在解析抽象语法树情况下,它们的性能差距是非常小的。因为大家操纵 CSS AST 的方式和手段都是差不多的,这点上不会有什么差距。

    而相差的那 30ms 左右,其实关键点就在于,双方引擎中,正则表达式匹配的数量和质量了。但是,相差这点时间其实已经没有意义了,毕竟我们都知道,正则写的越多,越复杂,执行就越慢。

    在我看来 @unocss/postcss 其实就是一个更加自由,可自定义的 tailwindcss 版本,你可以自定义里面匹配和生成 CSS 的规则。

    2 个库,其实实现思路其实还是比较相似的,但是这个世界上,并没有必要存在 2tailwindcss

    unocss vs tailwindcss

    就像我一向的观点,unocss 在帮助我们探索原子化 CSS 更多的上限。

    unocss 在各个方面相比来说都更加的进取,而使用 @unocss/postcss 这种方式,相比它推荐的其他使用方式来说,有一点点失去了它的一部分灵魂,你知道我指的是哪一部分(笑~)。

    tailwindcssunocss 都可以通过 plugin / preset 去添加更多的匹配规则。

    所以最终决定用什么的,还是取决于自己项目的需求,以及具体技术的生态吧,也就是中国的那句古话:前人栽树,后人吃瓜

    结尾

    这个测试其实也变相的提供了一个 unocss 的最佳实践,即只要尽可能少的解析 CSS ASTunocss 提取 token 的速度绝对比 tailwindcss 快很多。

    然而,最近我看 X 看到 tailwindcss@4.x 版本也快出了,官方放出了一张图片:

    Image

    X上链接

    感觉性能相当 Ok,属于是用 rust 实现了一波弯道超车?狠狠地期待一波:

    最后,期待 unocsstailwindcss 它们之间相互卷起来,未来给我们开发者带来更多的惊喜!

  • 相关阅读:
    Layui + Flask | 表单组件(组件篇)(07)
    pango logos 双启动
    免改造密码方案入选工信部“首届全国商用密码应用优秀案例”
    发挥数字化平台优势,电子元器件采购商城系统助力企业改变固有低效流程
    人工智能的数学基础------- 矩阵迹与相似矩阵的本质
    在Python中寻找数据异常值的三种方法
    Vue2.0新手入门-模板语法-计算属性与监听属性的介绍和差异
    Day24.1:抽象类的详解
    主变10kv 220kV、容量63MVA的风电场设计
    Java ElasticSearch-Linux面试题
  • 原文地址:https://blog.csdn.net/qq_33020601/article/details/136487888