作者 | Loraine Lawson
编译 | 言征
“JavaScript太重了。”虽然JS在全球开发语言中属于巨无霸的存在,但从过去到现在,吐槽JS的声音一直不绝于耳。
比如,要系统的学JavaScript,有一大套工具链,而且是非官方的工具链。许多新手一看到VS Code,NodeJS,Babel,Webpack,Jest,Gulp, TypeScript...顿时就被劝退。
再比如,语法特性也是乱成一团。弱类型,又可以面向对象,又可以函数式编程,还可以面向过程,还有this关键字,这些全部混着用。谁也不想接受这样的屎山代码!
就连Solid.js框架的创建者Ryan Carniato,也在近日发声:是时候在Web中减少JS代码了!
一、采用 0 Kb JavaScript?做不到!
Carniato目前在Web开发平台Netlify任职,近期他在“International JavaScript”会议的主题演讲中向前端开发人员提出了一个问题:“你未来会采用 0kb JavaScript 吗?”
当然,Carniato提出的这个问题更多是是一个假设性问题,因为 0kb 并不是真正的目标。更重要的是前端需要减少其JavaScript的占用空间。
“如果我们回顾过去和现在,就会发现关于降低 JavaScript 成本的讨论一直在进行,而且证据充分确凿。”
首先,他给开发人员展示了一组统计图数据,图中显示了按内容类型划分的网页权重的中位数,很明显,除了意料之中的图片之外,让网页变得十分“沉重”的罪魁祸首便是JavaScript。
按内容类型划分的页面权重显示了 JavaScript 在增加页面重量方面的影响。
如何让网页变轻?“首先,如何优化图像是众所周知的,但 JavaScript 有点棘手,而且它恰好是所提供的最昂贵的资产之一,”他说。
同时,Carniato指出,这种情况在移动设备上则是一个更大的问题,根据设备和网络的不同,要代价可能“非常高”。
他展示了一个 JavaScript 大小为 170 KB 的示例。JavaScript的处理时间要比图像更“漫长”。
“在一台低端设备上,处理时间,即解析、执行、运行 JavaScript 代码的时间,几乎是3秒半,而图像大约是 100 毫秒左右。”
不同高端低端设备的多核跑分
而且,高端设备和低端设备之间处理能力的差异,也存在越来越明显的差距。2022 年的低端设备市场在处理能力方面与 2014 年的高级设备类似,因此 iPhone 6s 本质上就像拥有 Moto E 30。
这里,Carniato提到了尤其会对电商公司 eBay 造成不小的影响,因为在电子商务领域,页面加载至关重要。
“加载时间和购买率之间存在相关性,这已经不是什么秘密了,”他说。“问题的真相在于水合(Hydration),而大型 JavaScript 有效负载也是我们架构责任的一部分。”
名词解释:1.水合作用的实质是水分子整体进入矿物晶格,从而使矿物体积增大的作用。这里是指 Web开发中的一种交互性技术。
在web开发中,水合(Hydration)是一种为服务器渲染的HTML添加交互性的技术。这是一种客户端JavaScript通过将事件处理程序附加到HTML元素,将静态HTML网页转换为动态网页的技术。
近年来,水合开始被视为一个消耗内存并减慢启动速度的黑客,尤其是在移动设备上。
二、前端开发者该为JavaScript瘦身了!
Carniato 给出了为Web中 JavaScript 代码“瘦身”的几种策略。
1.代码分割/延迟加载
Carniato 说,代码分割和延迟加载可以显着减轻重量。“现在使用的几乎所有元框架或工具几乎都会在路线级别自动为您完成此操作,”他说。“所以你应该已经这样做了。”
关于框架如何水合需要了解的一件事是,服务器渲染的任何内容都需要水合,就好像它在页面上可见一样,这就是开发人员显示其他内容并将其交换的原因。确实需要一些手动操作才能完成这项工作,他补充道,因为如果某些东西确实存在于投降 DOM 中并且它应该是交互式的,那么它就会水合。
“延迟加载并不能阻止它。这就是这些框架的工作方式,因为它们基本上需要运行整个应用程序,”他补充道。
2.使用更小/更快的框架
Carniato 采用了一种有趣的方法来比较框架。他在开始时查看了它们的大小,然后随着更多组件添加到框架中。结果令人惊讶,因为快速框架不一定保持快速。
JavaScript 框架速度
“是的,你的基线 [...] 开始较小,但实际上一旦编写代码情况就变了,”他说。“因此,在某个时刻,这些组件会构成更大的一块。”
有些框架一开始很小,但随着组件的添加,框架开始相互接近。他以 Svelte 为例。“例如,Svelte 从最小的开始;当你拥有 80 个独特的组件时,它实际上比 React 和其他所有组件都大,”他说。
“所以大多数框架实际上在规模上非常相似,事实上,你可以看到最上面的那条线,那就是在开头的React——它有相同的斜率。”
3.渐进式增强
渐进式增强基于这样的理念:Web是建立在anchors 和表单之上的;他解释说,因此,如果 JavaScript 不存在,开发人员可以依靠平台中已经内置的内容。
“渐进式增强确实得到了很大的推动,特别是在 Remix 和 SvelteKit 这样的框架中,”他说。“只要将所有交互编写为anchors 和表单,那么它们无需 JavaScript 即可运行。我认为这是一件很棒的事情。”
不过,Carniato 认为,它不一定能替代其他减少JS代码的方法,但它的确创造了一种非常不同的体验。
“我之前提到的那个可怜的用户,他使用的手机需要3秒半的时间来加载解析——假设总共需要7秒才能进行交互——他们点击链接可见3秒的链接,已经过去6秒,”他说。“你猜怎么着?JavaScript 还没有加载。”
因此,现在他们必须重新加载整个页面并再次等待七秒钟,而不是使用一些可供性进行客户端导航,他补充道。
“这当然OK,但这实际上并不是完全的胜利,它并不能解决问题,”
4.渐进式水合(Progressive Hydration)
他说,渐进式水合背后的想法是,页面根据需要进行水合。当有人点击文档时,开发人员可以提前将一些事件处理程序附加到文档,然后用它来做一些聪明的事情。他补充说,有时这被称为选择性水合。
渐进式补水合 绘制:Dan Abramov
Twitter上一位专家Dan Abramov为 Carniato 绘制了上图,试图展示如果 React 还没有完全水合,并且有人点击不同的分支(可能不是 React当前正在加载或水合的分支)会发生什么,那么它就会足够聪明地摆脱它正在做的事情,然后优先考虑被点击的那个分支。
“它仍然必须从父节点到子节点,但你可以给中间节点做水合,而不是绕过去;对我来说,无阻塞在这种情况下非常好,”Carniato 说道。
但事情也不是绝对的,你可能不会注意到,有时这也会导致总时间更长,另外,你会发现,后台中的CPU会嘎嘎作响,可能会在一定程度上影响体验。
此外,Carniato 还给出了其他几种 JavaScript 瘦身的办法,后续我们会跟踪报道,也欢迎诸位在评论区探讨交流。
最后想说一句,有人认为抛开JavaScript的庞大生态,去吐槽JavaScript太臃肿,有点耍赖皮,谁让现在基本所有的Web都在用它呢!
参考链接
https://thenewstack.io/solid-js-creator-outlines-options-to-reduce-javascript-code/
https://www.zhihu.com/question/550421589/answer/2710011944