大约一年前,Nikita Prokopov 发表了有关软件失望的清单文章 。 从积极的反馈来看,开发人员对产品的质量无动于衷。 也许是时候开始演戏了吗?
在本文中,我想谈谈我的开发,我认为这可以解决现代Web的主要性能问题,并使用户更加满意。 这些问题包括:繁重的JS代码, 启动页面(TTI)的大量时间 ,大量的内存和处理器消耗。
在继续阅读之前,请点击链接 。 尝试玩几个游戏。 最好从桌面播放。
一点历史
从一开始,Web浏览器就被认为是Web服务器的瘦客户端。 浏览器显示了从服务器接收到的超文本页面。 简洁大方。 通常,一个好主意面临现实,几年后,浏览器制造商增加了对脚本语言的支持。 最初,它仅用作装饰,直到2000年代中期,它被认为是使网页在没有JS支持的情况下工作的一种很好的形式。
网站开发的一种现代方法是开发用户界面交互性要求的结果。 改善交互性的任务落在编码人员的肩上。 那些通常没有能力和权限来开发“端对端”解决方案。 布局设计师学会了编写JS并成为前端。 逻辑逐渐开始从服务器流向客户端。 对于先行者来说,为浏览器编写代码很方便,而对于后端而言,不用考虑用户也很方便(将我的JSON给您,那么至少草不会增长)。 就在两年前,对无服务器架构的兴趣激增,有人建议JS应用程序可以直接与数据库和事件总线一起使用。
当前,“球形网站处于真空状态”是一个复杂的JS应用程序和一个与之通信的简单API服务器。 主要逻辑在胖客户端上运行,服务器端退化为数据库的简单层。
在客户端上保持逻辑的需求会产生问题。 如果服务“开始”并开始赚钱,那么就生产力而言,它只会变得更糟。 要求将改变。 开发团队将改变。 将会有越来越多的新代码,并且旧代码将不会被清除。 该页面将从依赖关系膨胀,它将加载有关没人记得的目的的JSON,但是删除它很可怕,突然间出现了一些问题。 将出现SetInterval后台任务,每秒钟每秒执行几毫秒,这将导致刹车并加热不幸的用户的iPad ,使他可以在其上煎鸡蛋。 最终,被烧毁的前端将向经理提出建议,要求在新框架上从头开始重写所有内容。 经理将拒绝,前端将开始同时使用两个框架。
科罗廖夫如何运作
那么,如果我们回到报告的重点呢? 有人想出了在不重新加载页面的情况下更新内容的想法,而历史的必然性导致了AJAX? 如果您将所有内容留在服务器上并成为瘦客户机,该怎么办? 最好的站点执行服务器页面预渲染(SSR),以便用户在JS加载和启动之前看到界面。 考虑到当前对交互性的要求,您可以走得更远,仅将负责处理I / O的代码留在客户端上。 关于这一点的想法蔓延到了Korolev项目中 。
它在客户端如何工作? 用户来到页面。 服务器提供生成的HTML和一个小的脚本(〜6 KB,无压缩),该脚本通过Web套接字连接到服务器。 当用户触发事件(例如,单击)时,脚本会将其发送到服务器。 处理完事件后,服务器将生成以下形式的命令列表:“在此添加新的<div>
”,“在此类元素中添加类”,“删除此类元素”。 客户端将命令列表应用于DOM。 这样,就不会使用HTML-脚本可以直接与DOM一起使用,因此不必担心表单的内容或滚动位置将被重置。
服务器上正在发生什么? 当浏览器发出页面请求时,Korolev将创建一个新会话。 对于会话,将创建初始状态,并将其存储在缓存中。 从此状态生成HTML,并将其作为对请求的响应提供给客户端。 另外,服务器在会话中保存“虚拟DOM”。 请求页面后,服务器接受打开Web套接字的请求。 Korolev将打开的Web套接字与会话关联。 来自客户端的每个事件都可以更改与会话关联的状态。 每个状态更改都会导致对render
函数的调用,后者会形成一个新的“虚拟DOM”,并将其与旧版本进行比较。 比较结果是要发送到客户端的命令列表。
开发人员的代码和负责人会发生什么? 上面的内容可能使您想起React,区别在于一切都在服务器上运行。 在开发方法方面,我们也有类似的东西。 因此,如果您使用React或其他“虚拟DOM”,那么Queen的方法将为您所熟悉。 如果您不熟悉React,请想象您有插入模板的数据。 想象一下,根据模板,事件处理程序分散了,可以更改数据(但不能更改DOM)。 您更改数据,页面也会更改。 Korolev自己想出了如何更改DOM的方法。
性能表现
关于Korolev,有两个普遍的问题:“如果延迟很高,会怎样?”和“这将不会加载我的服务器”。 这两个问题都非常合理。 前端程序员习惯于使其程序在用户的本地计算机上运行。 这意味着对它所做的更改将在JS机器完成执行代码并且浏览器开始渲染后立即应用。 我在开始时专门展示了一个使用“以最大速度”的示例。 仅当您来自地球的另一端(服务器位于莫斯科)或通过GPRS上网时,您才能观察到延迟。 好吧,或者我的可怜的虚拟服务器只有一个内核和1 GB的RAM不能承受habr的影响。
关于服务器负载的问题通常由beckenders提出。 变更输出引擎的运行速度非常快:2013年初中的Macbook上有500个节点的两棵任意树,每秒约有1万个结论。 静态渲染也提供了相当不错的效果:每秒高达一百万页。 每个“虚拟DOM”都以特殊的序列化形式存储和处理,并且每个Web页面平均需要128 KB。 输出过程经过专门优化,没有内存和GC开销。
关于发展速度,科罗廖夫在这里具有很大的优势。 无需在数据库和服务器之间编写额外的层。 无需在客户端和服务器之间协商协议。 无需担心前端的模块化-客户端上的JS权重将始终保持不变。 无需对服务器事件进行其他逻辑处理:只需接受队列中的消息并更改会话状态,Korolev就会进行渲染和传递。
价钱
您必须为此付出代价。 一些习惯将不得不放弃,而一些新的习惯要养成。 例如,您必须放弃JS动画,而对CSS动画感到满意。 如果您想为来自不同国家/地区的用户提供高质量的服务,则必须学习如何使基础结构最初在地理上分布。 必须放弃JS并转到Scala。
我有点led愧(实际上不是),我误导了读者,没有立即说Korolev是用Scala编写的,我对此感到as愧。 如果我立即谈到这一点,您会读到这一点吗? 关于女王,我必须克服两个陈规定型观念。 首先是由于以下事实:服务器渲染被认为是缓慢而不是交互的。 第二个原因是Scala有点复杂。 第一种和第二种刻板印象与现实无关。 而且,在Scala上以React风格进行编程比在JS上更为方便。 现代JS倾向于使用函数式编程,Scala则将其开箱即用。 例如,Scala中的任何对象都具有copy()
方法,该方法允许您通过更改某些字段来复制对象。 不可变集合内置在Scala标准库中。
结论
Korolev由数个开发人员开发了三年,并解决了许多“儿童”问题。 该项目文档齐全,所有功能均包含示例。 我建议以小型独立服务开始实施女王。 我希望Korolev帮助减少程序的失望程度。
链接到github上的项目