时间流转,来到了9102年的末尾,距离es6正式发布已经过去了4年半。在前端发展的时间长河中,我们送别了YUI,ie(也许),jQuery,现在,是时候送别es5了。
收益在哪
程序员在进行技术决策的时候,通常的目的是为了kpi,升值加薪,这个技术很流行,不,当然是为了对业务产生价值。
不难发现,直接部署es6代码可以带来的好处包括:
- 代码体积减小
- 性能提升
- 缩短构建时间
代码体积减小
首先,es6带来了新的语法和特性,这可以让代码更简洁,使得代码量减少。其次,babel转译之后,会产生一些helper
,引入一些polyfill
,而且有一些语法特性无法在运行时进行处理,必须在转译过程中修改源代码,这也会导致代码量增加。当然,部署es6代码也需要babel转译一部分更新的语法,并不是说完全不使用babel。
一个Google工程师的试验结果,es6代码的bundle size比es5代码减少了50%。而我自己的实践的结果没有这么夸张,是25%左右。
version | bundle size | Gzipped |
---|---|---|
es5 | 221kb | 39kb |
es6 | 170kb | 29kb |
之所以我和他的测试结果差异较大,是因为最终的结果跟每个人的代码风格和代码内容有很大的关系。我用来进行测试的代码是一个线上项目的代码,我个人的代码风格是大量使用es6/7/8语法,不过项目本身大量是在写业务逻辑,并且项目使用了Vue,其实很多js代码是模板编译之后生成的渲染函数。
所以,大概的结论是es6的代码会比es5的代码体积减少15% ~ 50%,具体能减少多少,取决于代码风格以及代码内容。代码风格越现代,代码中"生成的代码"越少,收益越高。
性能提升
es6代码相对于es5代码,性能更高的原因我认为有2个
- 代码量减少带来的解析时间减少,这个正比于代码体积的减少
- 运行性能的提高
对于第一点,浏览器解析代码时间的减少应该占比较小,通过chrome的Performance
面板可以看到,解析一个200kb的js文件Compile Script耗时为10ms(测试机器为台式机,i7/16G)。
对于第二点,运行时性能。在es6刚刚发布的时候,很多新特性的性能是比较低的,因为js引擎没有足够的时间去进行优化,相比较而言,es5以及更老的代码经过了浏览器的长时间优化,在es6刚出来的时候,很对人也对es6的性能有很大的担忧。
Github上有一个仓库,专门对es6和es5进行了性能对比。
从对比结果可以看出来,在chrome 72版本上,es6代码的性能优于babel转译成的es5代码,和手写的es5代码比起来各有千秋,基本算是55开。
而且,浏览器对于es6的性能优化是持续性的,最近V8就会因为React hooks
而改进数组解构的性能。
针对运行时的es6代码和es5代码的性能对比,我也用一个线上项目进行了实验。实验方式如下
- 利用
performance API
在打包后的app.js文件开头记下时间戳,在js文件末尾减去开始的时间,得到一个时间,众所周知,打包之后的app.js是一个立即执行函数,所以这个时间包含了app.js文件中部分代码的运行时间 - 利用chrome 的
Performance
面板,可以直接得到一段js的执行时间Evaluate Script
实验结果如下(20次的平均值)
version | 记录的运行时间 | Performance面板的Evaluate Script |
---|---|---|
es5 | 258.88ms | 295.29ms |
es6 | 206.28ms | 241.59ms |
测试条件下,es6的代码取得了20%左右的运行性能提升
风险在哪儿
js的运行环境非常复杂,桌面端、移动端、各种小程序、各种webview、node.js,能否部署es6代码只能依靠自己判断。
就我个人的经验而言,大部分的中后台项目都具备直接部署es6代码的条件,而且我们在具体的实施中肯定会有降级方案,让不支持es6的情况下运行es5的代码。
如何实施
Vue用户可以通过Vue cli的 --modern
直接开启现代模式
非Vue使用者,可以通过这篇文章提到的方案来进行。大概就是利用script
标签的type=module
作为浏览器是否全面支持es6的检测,并通过type=nomodule
来进行降级处理。
// 不支持module的浏览器,下载但不会执行
<script type="module" src="es6.js"></script>
// 支持module的浏览器,不会下载
<script nomodule src="es5.js"></script>
一个需要注意的点是safari 10不支持nomodule,所以需要针对它解决重复下载并执行的问题。(ps: safari浏览器是新时代的毒瘤)
虽然,一个降级的方案可以保证我们的代码可以在只支持es5的浏览器上也可以执行,但是同时这些老的浏览器会下载2份代码,带来的损失非常大,因为老设备通常也意味着低性能和低网速,它们更不能承受性能损失。所以我认为,如果你的业务需要兼容es5的用户达到了20%以上,我就不赞同采用这个方案。
如果可以确定完全不需要兼容es5的用户,可以直接修改browserlist
到全面支持es6的浏览器版本,并且不用考虑降级方案,此时还会带来构建速度提升这一额外的好处。
browserslist示例
Chrome >= 60
Safari >= 10.1
iOS >= 10.3
Firefox >= 54
Edge >= 15
结语
时间带走一切,es5也不例外。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。