- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章探讨Esbuild 为什么那么快由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
。
Esbuild 是一个非常新的模块打包工具,它提供了与 Webpack、Rollup、Parcel 等工具「相似」的资源打包能力,却有着高的离谱的性能优势:
从上到下,耗时逐步上升达到数百倍的差异,这个巨大的性能优势使得 Esbuild 在一众基于 Node 的构建工具中迅速蹿红,特别是 Vite 2.0 宣布使用 Esbuild 预构建依赖后,前端社区关于它的讨论热度迅速上升.
那么问题来了,这是怎么做到的?我翻阅了很多资料后,总结了一些关键因素:
下面展开一一细讲.
。
语言优势 。
大多数前端打包工具都是基于 JavaScript 实现的,而 Esbuild 则选择使用 Go 语言编写,两种语言各自有其擅长的场景,但是在资源打包这种 CPU 密集场景下,Go 更具性能优势,差距有多大呢?比如计算 50 次斐波那契数列,JS 版本:
。
Go 版本:
。
JavaScript 版本执行耗时大约为 「332.58s」,Go 版本执行耗时大约为 「147.08s」,两者相差约 「1.25」 倍,这个简单实验并不能精确定量两种语言的性能差别,但感官上还是能明显感知 Go 语言在 CPU 密集场景下会有更好的性能表现.
归根到底,虽然现代 JS 引擎与10年前相比有巨大的提升,但 JavaScript 本质上依然是一门解释型语言,JavaScript 程序每次执行都需要先由解释器一边将源码翻译成机器语言,一边调度执行;而 Go 是一种编译型语言,在编译阶段就已经将源码转译为机器码,启动时只需要直接执行这些机器码即可.
这种语言层面的差异在打包场景下特别突出,说的夸张一点,JavaScript 运行时还在解释代码的时候,Esbuild 已经在解析用户代码;JavaScript 运行时解释完代码刚准备启动的时候,Esbuild 可能已经打包完毕,退出进程了.
所以在编译运行层面,Go 前置了源码编译过程,相对 JavaScript 边解释边运行的方式有更高的执行性能.
多线程优势 。
Go 天生具有多线程运行能力,而 JavaScript 本质上是一门单线程语言,直到引入 WebWorker 规范之后才有可能在浏览器、Node 中实现多线程操作.
我曾经研读过 Rollup、Webpack 的代码,就我熟知的范围内两者均未使用 WebWorker 提供的多线程能力。反观 Esbuild,它最核心的卖点就是性能,它的实现算法经过非常精心的设计,尽可能饱和地使用各个 CPU 核,特别是打包过程的解析、代码生成阶段已经实现完全并行处理.
除了 CPU 指令运行层面的并行外,Go 语言多个线程之间还能共享相同的内存空间,而 JavaScript 的每个线程都有自己独有的内存堆。这意味着 Go 中多个处理单元,例如解析资源 A 的线程,可以直接读取资源 B 线程的运行结果,而在 JavaScript 中相同的操作需要调用通讯接口 woker.postMessage 在线程间复制数据.
所以在运行时层面,Go 拥有天然的多线程能力,更高效的内存使用率,也就意味着更高的运行性能.
节制 。
对,没错,节制.
Esbuild 并不是另一个 Webpack,它仅仅提供了构建一个现代 Web 应用所需的最小功能集合,未来也不会大规模加入我们业已熟悉的各类构建特性。最新版本 Esbuild 的主要功能特性有:
可以看到,这份列表中支持的资源类型、工程化特性非常少,甚至并不足以支撑一个大型项目的开发需求。在这之外,官网明确声明未来没有计划支持如下特性:
而且,Esbuild 所设计的插件系统也无意覆盖以上这些场景,这就意味着第三方开发者无法通过「插件」这种无侵入的方式实现上述功能,emmm,可以预见未来可能会出现很多魔改版本.
Esbuild 只解决一部分问题,所以它的架构复杂度相对较小,相对地编码复杂度也会小很多,相对于 Webpack、Rollup 等大一统的工具,也自然更容易把性能做到极致。节制的功能设计还能带来另外一个好处:完全为性能定制的各种附加工具.
定制 。
回顾一下,在 Webpack、Rollup 这类工具中,我们不得不使用很多额外的第三方插件来解决各种工程需求,比如:
我们已经完全习惯了这种方式,甚至觉得事情就应该是这样的,大多数人可能根本没有意识到事情可以有另一种解决方案。Esbuild 起了个头,选择完全!完全重写整套编译流程所需要用到的所有工具!这意味着它需要重写 js、ts、jsx、json 等资源文件的加载、解析、链接、代码生成逻辑.
开发成本很高,而且可能被动陷入封闭的风险,但收益也是巨大的,它可以一路贯彻原则,以性能为最高优先级定制编译的各个阶段,比如说:
这种深度定制一方面降低了设计成本,能够保持编译链条的架构一致性;一方面能够贯彻性能第一的原则,确保每个环节以及环节之间交互性能的最优。虽然伴随着功能、可读性、可维护性层面的的牺牲,但在编译性能方面几乎做到了极致.
结构一致性 。
上一节我们讲到 Esbuild 选择重写包括 js、ts、jsx、css 等语言在内的转译工具,所以它更能保证源代码在编译步骤之间的结构一致性,比如在 Webpack 中使用 babel-loader 处理 JavaScript 代码时,可能需要经过多次数据转换:
源码需要经历 string => AST => AST => string => AST => string ,在字符串与 AST 之间反复横跳.
而 Esbuild 重写大多数转译工具之后,能够在多个编译阶段共用相似的 AST 结构,尽可能减少字符串到 AST 的结构转换,提升内存使用效率.
。
单纯从编译性能的维度看,Esbuild 确实完胜世面上所有打包框架,差距甚至能在百倍之大:
但这是有代价的,刨除语言层面的天然优势外,在功能层面它直接放弃对 less、stylus、sass、vue、angular 等资源的支持,放弃 MF、HMR、TS 类型检查等功能,正如作者所说:
❝This will involve saying "no" to requests for adding major features to esbuild itself. I don't think esbuild should become an all-in-one solution for all frontend needs!❞ 。
在我看来,Esbuild 当下与未来都不能替代 Webpack,它不适合直接用于生产环境,而更适合作为一种偏底层的模块打包工具,需要在它的基础上二次封装,扩展出一套既兼顾性能又有完备工程化能力的工具链,例如 Snowpack, Vite, SvelteKit, Remix Run 等.
总的来说,Esbuild 提供了一种新的设计思路,值得学习了解,但对大多数业务场景还不适合直接投入生产使用.
原文链接:https://mp.weixin.qq.com/s/BCL1Cm64mps4cZe_V26Wtw 。
最后此篇关于探讨Esbuild 为什么那么快的文章就讲到这里了,如果你想了解更多关于探讨Esbuild 为什么那么快的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
默认情况下,Android系统在超过N分钟没操作,会自动关屏并进入休眠状态。 实际上,有些项目要求超时不休眠,如果只是针对单个应用程序,我们可以通过电源管理设置状态来实现, 而如果要设置所有应用的超
1、分析 1、最简单的布局:只有一个listview 如果整个页面只有一个listview的话,那么由于listview本身带有滚动效果,所以当加载的数据超过页面显示的范围时,可以通过上下滑动
一个Bug 前几日出现这样一个Bug是一个RuntimeException,详细信息是这样子的: 复制代码 代码如下: java.lang.IllegalArgumentExcept
已知两个链表list1和list,2,各自非降序排列,将它们合并成另外一个链表list3,并且依然有序,要求保留所有节点。 实现过程中,list1中的节点和list2中的节点都转移到了list3中,
php在做后台服务器的时候,经常会遇到这种情况,需要解析来自前台的xml文件,并将数据以xml格式返回,在这种情况下,xml与php中关联数组的转化是非常频繁的事情。比如flex和其他客户端程序与服
命令行方式: 在phpDocumentor所在目录下,输入phpdoc –h会得到一个详细的参数表,其中几个重要的参数如下: -f 要进行分析的文件名,多个文件用逗号隔开 -d 要分析的目录,多
用C/C++扩展PHP的优缺点: 优点: 效率,还是效率 减少PHP脚本的复杂度, 极端情况下, 你只需要在PHP脚本中,简单的调用一个扩展实现的函数,然后你所有的功能都就被扩展实现了 而缺点也是显
Memcached有个stats命令,通过它可以查看Memcached服务的许多状态信息。使用方法如下: 先在命令行直接输入telnet 主机名端口号,连接到memcached服务器,然后再连接成功
通过status命令,查看Slow queries这一项,如果值长时间>0,说明有查询执行时间过长 复制代码代码如下: 以下为引用的内容: mysql> status;
myisam 存储数据有三个文件.MYD,.MYI ,.FRM 数据文件和索引文件分开存储 innodb存储数据有.FRM存放表定义,.ibd(独享表空间),.ibdata(共享表空间).innod
Oracle数据库查看一个进程是如何执行相关的实际SQL语句 复制代码代码如下: SELECT b.sql_text, sid, serial#, osuser, machine &
答案: 在内建数据类型的情况下,效率没有区别; 在自定义数据类型的情况下,++i效率更高! 分析: (自定义数据类型的情况下) ++i返回对象的引用; i++总是要创建一个临时对象,在退
函数 返回值 和 返回引用 是不同的 函数返回值时会产生一个临时变量作为函数返回值的副本,而返回引用时不会产生值的副本,既然是引用,那引用谁呢?这个问题必须清楚,否则将无法理解返回引用到底是个什么概
两年前从网上看到一道面试题:用两个栈(Stack)实现一个队列(Queue)。觉得不错,就经常拿来面试,几年下来,做此题的应该有几十人了。通过对面试者的表现和反应,有一些统计和感受,在此做个小结。
网站提供上存功能,是很多站点经常会有功能,商城,论坛还有常见一些网盘站点。常见互联网上面,我们也是经常听说,某某站点出现上存漏洞,某某开源项目有上存漏洞。 从互联网开始出现动态程序,上存漏洞像幽灵一
概念:XML序列化是将公共字段和属性转化为序列格式(这里指XML),以便存储或传输的过程。反序列化则是从XML中重新创建原始状态的对象. 复制代码 代码如下: &nbs
1、查看實例名時可用 1、服务—SQL Server(实例名),默认实例为(MSSQLSERVER) 或在连接企业管理时-查看本地实例 2、通過注冊表 HKEY_LOCAL_MACHINE/
一 应用规划: ※ 确定功能。 ※ 必须的界面及界面跳转的流程。 ※ 需要的数据及
parse_url (PHP 4, PHP 5) parse_url — 解析 URL,返回其组成部分 说明 array parse_url ( string $url ) 本函数解析一个 URL
自 PHP 5 起,可以很容易地通过在 $value 之前加上 & 来修改数组的元素。此方法将以引用赋值而不是拷贝一个值。 复制代码 代码如下: <?php $arr = arr
我是一名优秀的程序员,十分优秀!