一个关于网页速度的故事,或者说是扔掉反应

2020-08-24 18:39:52

在过去的某个时候,我碰巧找到了一份编写Backbone.js应用程序的工作。如果你从来没有那样做过,那就别做了。我在向任何愿意听的人抱怨作文方面的困难。当我开始研究前端的替代方案时,我发现了FRP和Flapjax,以及ClojureScript。最后一张让我迷上了Clojure。我甚至在FRP和ClojureScript(Hoplon的前身,称为hlisp)上做了一次成功的演讲。

然后在2013年5月,Reaction发布了。我在我的新工作中支持它,并在以Clojure为主题的hackaton(Clojure Cup 2013)上发现CLJS和Reaction是一对绝佳的组合。不过,反应有什么好处呢?对我来说,它的主要卖点是构图很好。

当您使用jQuery、主干或ANGLE等前身时,经过短短一年的开发,您的代码就会变得一团糟,事件侦听器和触发器乱七八糟。不要让我开始谈论不起眼的JS,使用jQuery是不存在代码局部性的。哪个处理程序被绑定在哪里,它做什么?要想成为一个好的代码库的良好基础太难了!

然后我开始在Kasta工作,那里的Web前端就是那种jQuery式的乱七八糟的东西。没有人愿意触摸结账,因为你可以花几个小时,如果不是几天的话,做最小的改变。那么QA会发现比您想象中更多的无效状态。然后,用户会向我们的呼叫中心报告更多的错误。这简直是你想象不到的可怕。

因此,在进行了一些实验、测试和检查之后,我决定采用Reaction+ClojureScript的方式,在Clojure中完成服务器端呈现。

有一段时间,情况看起来很好。但我们的前端变得越来越大,虽然几乎没有人试图保持它的性能,但最终我们失败了。应用程序变得太大,其启动时间变得太长。

早在2016年,其中一个主要原因是我们的启动时间受到了影响,但反过来,我们没有页面加载,并且拥有一个具有大量交互的丰富的Web应用程序。在一段时间内,这招奏效了!但启动时间变得越来越长,导致谷歌的PageSpeed给出了可耻的5/100的评分。

更重要的是,在执行下面描述的操作时,我们发现反应也会导致一些有问题的实践。比如JS中的悬停(而不是CSS中),JS中的下拉菜单,不会呈现隐藏(在悬停下)文本(Google不会高兴),奇怪的复杂逻辑(因为这是可能的!)等等。你可以有一个没有这些问题的Reaction应用程序,但显然,你必须比我们拥有更好的自控力(没有人是完美的!)。

当然,中间冷却器有一些不同之处,因为它为什么会存在?最值得注意的是不依赖jQuery。它只支持现代浏览器(不支持IE或Opera Mini),但去掉了那个88KB的怪物。

更严格的属性名称约定(我自己的观点,但是ic-get和ic-post激怒了我:不要让我更改密钥!)。

老实说,主要原因是批量,没有继承。继承在这里特别痛苦。在InterCooler中,如果你在身体上声明ic-target,里面的所有标签也会认为它是他们的目标。因此,您在HTML树中的某个位置包含了一个组件,并且树上更高的属性会更改此组件的行为。我的意思是这是一个该死的动态范围,我不想要那个!:)。

有趣的是,在涉足TwinSpark大约一个月之后,InterCooler的作者宣布他正在做一个没有jQuery的现代版本:htmx。:)它有非常好的扩展点,所以也许可以添加批处理…。但遗产仍然存在。:(。

我们需要从两个方面来看:它是否对开发人员有好处,是否对用户有好处。前一种反应很好,后一种反应很糟糕。

TwinSpark方法在大多数情况下对用户来说要好得多:更少的JavaScript,更少的抖动,更常见的类似HTML的行为。在最坏的情况下,我们将为您提供2.5MB的缩小(非gzip)JS和700KB的HTML(其中一半是Reaction的初始数据)作为目录。现在,它是40KB的缩小的非gzip JS(TwinSpark、分析、一些行为、IntersectionViewer PolyFill)和350KB的HTML。两个数量级的差异,甚至HTML都更小!这就像童年的圣诞节!

在开发人员方面,我认为Reaction更好,但是代码的局部性很好,可组合性比jQuery好得多(因为您被迫在有限的简单化模型中工作)。另外,有很多方法可以改善它。

从第一次实验开始,我们花了四个月的时间才发布。不完全是我们开始的时候我想象的时间(“最多应该需要两到三个星期!”),呵呵,但我们并不完全是这样做的。消除代码中的反应性,让我们的应用程序成为服务器端的公民,仍然需要花费大量的时间和精力。它仍然需要一些打磨,但我们决定发布它,尽管如此,只是为了缩短它。