乐趣区

关于javascript:新一波-JavaScript-Web-框架

本文来自 InfoQ 中文站,原作者 FrontEndMastery,译者 Sambodhi,策动 Tina

太过激进很难在 Javascript 生态系统中放弃与时俱进。对于那些刚进入这个行业的人来说,要在新的库、框架、概念和无力的意见中关注正在产生的事件,很有挑战性。这是个很好的揭示,默认状况下,应用“无聊”的技术,你所相熟的技术,并且成为早期采纳者,通常是个不错的抉择。
闲话少叙,本文将带读者理解 Javascript 中生态系统中的最新进展,通过钻研过来在构建大规模 Web 利用时的痛点来理解以后的状况。
不要把注意力集中在快速增长的解决方案上,而是从潜在问题动手。每一种架构都会有不同的答案,并且会有不同的衡量。到本文完结时,咱们会列出风行框架的高级模型,如 React、Svelte、Vue、Solid、Astro、Marko、Fresh、Next、Remix、Qwik,以及适宜当今环境的“元框架”。
鉴往知来。让咱们回首来时路,再看看将来的趋势。这次,咱们将专一于大型项目中的问题,这些问题激发了其余办法和思维形式。

网页简史

Web 最后由动态文档链接在一起组成。那时候,人们能够提前准备一份文件,并把它放在电脑上。而当初最酷的就是,人人都能够拜访它,无需亲临其境。
不知从何时起,咱们感觉,让这些文件变成动静,会十分酷。于是咱们有了像 ​​CGI​​​ 这样的技术,使咱们可能依据申请提供不同的内容。而后,咱们有了像 ​​Perl​​ 这样的表达式语言来编写这些脚本。它对最后针对 Web 开发的 ​​​PHP​​​ 产生了影响。PHP 的翻新之处在于将 HTML 间接连贯到后端代码。这使得以编程形式创立嵌入动静值的文件变得容易了。

Web 最重要的冲破之一来自于此:

<html>  <body>    This document has been prepared ahead of time.    Regards.  </body></html>

具备易于嵌入的动静值:

<html>  <body>    Y2K? <?php echo time(); ?>  </body></html>

框架时代拉开大幕

这些动静页面很受欢迎。咱们能够很轻松地对发送给用户的内容进行定制,包含启用会话的 cookies。在与数据库交互的语言生态系统中,曾经有了基于服务器的模板框架。通过这些框架,咱们能够轻松地从动态页面开始,而后扩大到动静页面。
Web 的倒退日新月异,咱们想要更多的互动体验。为了这个目标,咱们应用了 ​​Flash​​​ 这样的浏览器插件。在其余方面,咱们会在后端提供的 HTML 上“撒上”Javascript 片段。
像 jQuery 和 Prototype 这样的工具呈现了,它们暗藏了 Web API 的复杂度,打消了浏览器之间的差别。
光阴荏苒,科技公司的规模在不断扩大,并且因为我的项目和开发团队的增长,在模板中退出更多的业务逻辑是十分广泛的。
编写的服务器代码,将解决后的数据传输到服务器模板语言中。模板经常调演变成业务逻辑的“混合体”来拜访全局变量。因为像 SQL 注入这样的攻打曾经司空见惯,因而平安问题也越来越突出。
最终,论文《Ajax:Web 利用的新办法》(Ajax: A New Approach to Web Applications)为咱们带来了 Ajax 技术。当初你用 Ajax 技术能够做的新事件就是用异步形式更新页面,而不再是以同步的形式来更新页面。这种模式被第一批大型客户端应用程序所推广,如谷歌地图和谷歌文档。起初,咱们开始看到 Web 散发对桌面格调的软件的影响力。与在商店里购买光盘的软件相比,这是一个重大的提高。

JavaScript 壮大

当 node 呈现的时候,它所带来的新个性,就是用与前端雷同的语言来编写你的后端。所有这些都是开发人员所相熟的异步优先模式。这已经令人无奈抗拒,当然当初也是。随着越来越多的企业上线,竞争劣势在于是否疾速交付和迭代。
Node 的生态系统强调重复使用小型的单用处包,你能够利用现成的去实现工作。

前端与后端拆散

咱们更渴求可能与桌面、挪动设施相媲美的 Web。当初,咱们曾经有了一系列可重用的“小部件”库和工具,如 jQuery UI、Dojo、Mootools、ExtJs 和 YUI 等。
咱们对这些小玩意儿的关注水平一劳永逸,并且在前端的工作也越来越多。这往往导致了前端和后端的模板反复。像 Backbone 和 Knockout 以及许多其余的框架呈现了。它们通过 MVC、MVVM 等架构为前端减少了关注点的拆散,并且,架构能够兼容咱们收集到的所有小部件和 JQuery 插件。增加构造有助于扩大所有这些前端代码。并且能够减速从后端传送模板。
咱们依然编写微调的 DOM 操作来更新页面并放弃组件的同步。这个问题非同小可,而且与数据同步相干的谬误也很常见。
在谷歌的反对下,Angular 退场了。它通过加强 HTML 的动态性,促成了生产力的进步。它装备了双向数据绑定,以及一个受电子表格启发的反馈性零碎。这些申明式的双向绑定打消了许多必须更新的模板。这是坏事,能够让咱们的工作效率更高。
随着规模的扩充,跟踪变动越来越艰难,经常会造成性能降落。更新的周期会产生,并占据主线程(明天像 Svelte 这样的库能够在升高其缺点的状况下放弃双向绑定)。除了挪动设施的衰亡之外,这些进步生产力的框架也减速了前端和后端的拆散。这为摸索强调这种解耦的不同架构铺平了路线。
这是 JAMstack 理念的一个次要局部,强调提前预生成 HTML,并从 CDN 提供服务。在过后,这是对提供动态文档服务的一种倒退。但当初,咱们有了基于 git 的工作流,有了弱小的 CDN 基础设施,有了能够与独立 API 互动的解耦前端,就无需依附远在天边的地方服务器。与经营服务器相比,将动态资产搁置到 CDN 上要便宜很多。
明天,像 Gatsby、Next 和很多的其余工具都利用了这些想法。

React 崛起

快步流星地进入大科技时代。咱们正试图追风逐电,一改故辙。对于那些进入这个行业的人来说,Javascript 很大,而构建一个由独立后端反对的解耦 SPA 曾经成为事实。
在 Facebook,React 的诞生面临着几个挑战。

  1. 数据频繁变动时的一致性:放弃许多小部件之间的同步,依然是一项重大的挑战。因为数据流不足可预测性,这在规模上是个问题。
  2. 组织上的扩大:优先思考进入市场的工夫和速度。对于新开发人员来说,是否疾速上手,并且富有成效,这一点至关重要。
    ​​React ​​诞生了,你能做得很酷的新事件就是申明性地编写前端代码。
    前端关注点的拆散是驰名的反思,以前的 ​​MVC 框架无奈扩大​​​。人们并不喜爱从模板向 Javascript 驱动的 JSX 过渡。然而咱们大多数人都承受了。
    组件模型容许解耦独立的前端团队,他们能够更容易地在独立组件上并行工作。作为一个架构,它容许组件的分层。从共享的原语到形成页面根目录的“有机体”。单向的数据流使数据流更易于了解、跟踪和调试。这就进步了之前难以企及的可预见性。虚构 DOM 就是咱们能够编写函数,返回用户界面的阐明,让 React 去解决这些难点。这样能够防止在数据频繁变动时呈现的一致性问题,并且使得模板的组成更加人性化。

规模化的 React 已达到 CPU 和网络的极限

React 十分风行,曾经成为了业界的规范,即便是那些不想要其个性的网站来说也是如此。在规模的远端,咱们开始看到一些限度。

CPU 遭逢很大阻力

DOM 是 ​​React 模型​​的一个问题。浏览器并不是为了在间断的渲染周期中一直创立和销毁 DOM 节点而构建的。就像任何能够通过引入一个新的间接级别来解决的问题一样,React 把它形象到了虚构 DOM 前面。
人们只有在 100 毫秒以内感知到反馈,才会感到晦涩。而在做像滚动页面这样的事件时则要低得多。在与单线程环境相结合的状况下,这种优化曾经成为高度交互式利用的新瓶颈。当虚构 DOM 和实在 DOM 之间产生协调时,大型交互式应用程序会对用户的输出失去响应。像“长工作”这样的术语开始呈现了。
这导致了 React 在 2017 年被从新编写,为并发模式奠定了根底。

运行时成本增加

与此同时,更快的挪动意味着传输更多的代码。浏览器在运行大量 Javascript 时,启动速度慢就成为一个问题。咱们开始留神到所有隐含的运行时老本,不仅是 HTML 和虚构 DOM,还有咱们编写 CSS 的形式。
组件模型简化了咱们在 CSS 方面的教训。咱们能够将款式与组件放在一起,这进步了可删除性。对于那些以前不敢删除 CSS 代码的人来说,这是一个十分好的属性。咱们始终在解决的级联和所有的特殊性问题都被 JavaScript 库中的 CSS 抽象化了。
这些第一波的库往往伴有隐含的运行时老本。咱们须要等到组件被渲染后,再将这些款式注入到页面中,这就造成了 JavaScript 包中的款式问题。从规模上来说,蹩脚的性能往往是千夫所指,而咱们也留神到了这些老本。这导致 JavaScript 库中呈现了新的 CSS,它通过应用智能预编译器来提取样式表,这些库专一于没有运行时的开销。

效率低下的网络和渲染碰壁的组件

当浏览器渲染 HTML 时,像 CSS 或脚本这样的渲染阻碍资源会阻止 HTML 的其余局部显示进去。在一个组件的层次结构中,父组件往往会成为子组件的渲染阻碍。
在实践中,许多组件依赖于数据库的数据和 CDN 的代码(通过代码宰割)。这常常会造成瀑布式的网络申请阻塞。在渲染之后,组件会获取数据,解锁异步子组件。接着,它们将会获取它们所需的数据,并反复这一过程。常常能够看到“下拉列表的天堂”或累积布局偏移,这些变动是在加载 UI 时呈现在屏幕上的。
React 起初公布了 Suspense,以使页面的加载阶段更加顺畅。然而,默认状况下,这并不能避免继续的网络瀑布问题。Suspense 反对“在获取数据时渲染”的模式。

Facebook 如何解决这些问题

咱们将持续绕行,理解 React 的一些衡量如何在规模上失去缓解。这将有助于构建新框架中的模式。
• 优化运行时老本
在 React 中,​​虚构 DOM 的运行时老本是无奈防止的​​​。并发模式是一个解决问题的办法,它能够让你在高度互动的体验中放弃对事件做出响应。
在 JavaScript 中的 CSS 畛域,应用了一个名为 Stylex 的外部库。当成千上万的组件被渲染时,这能够维持人性化的开发人员体验,而无需运行时的老本。
• 优化网络
Facebook 用 Relay 来防止程序性的网络瀑布问题。对于一个给定的入口点,动态剖析能够准确地确定要加载的代码和数据。这就意味着代码和数据都能够在一个优化的 graphQL 查问中并行加载。
这比初始加载和 SPA 转换的程序网络瀑布要快得多。
• 优化 Javascript 包
其中一个根本问题就是传递 JavaScript,这些 JavaScript 与具体的用户无关。
如果有 A/B 测试,个性标记的经验,以及针对特定类型和群组的用户的代码时,那就很艰难了。还有语言和地区设置。当代码有许多分支时,动态依赖关系图不能看到在实践中为特定用户群一起应用的模块。
Facebook 应用了一个由人工智能驱动的动静包零碎。这利用其严密的客户 - 服务器集成,在运行时依据申请计算出最佳的依赖图。这与一个依据优先级分阶段加载包的框架相结合。

生态系统的其余局部呢?

Facebook 领有简单的基础设施和多年来构建的外部库。如果你是一家大型科技公司,你能够投入大量的资金和资源来优化这些大规模的衡量。
这为前端产品开发人员发明了一个胜利的深渊,能够让他们在实现工作的同时放弃性能。
咱们中的大多数人都不会像 Facebook 那样的规模上构建一套利用。然而,对于许多大型企业来说,性能是个话题。咱们能够从这些模式中学习,例如:尽可能多地获取数据,并行化网络,以及应用内联需要等等。
大型科技公司常常在外部推出本人的利用框架。在不同的用户资源库中,遗留了大量的解决方案。这导致了许多 Javascript 生态系统疲劳和框架倦怠。

JavaScript 的世界:群龙无首

还跟咱们在一起?咱们正处于 SPA 的时代。这就是目前从事这一行的人所面临的现状。
React 是无可争议的冠军,然而,咱们看到了大规模的取舍。
React 提供了一个层。它将其余必要的层留给了生态系统,在路由、状态治理、数据获取等各个重要方面造成了凌乱,每个层都有本人的概念和 API。
不可变与可变,带有类的 OOP 与函数式的 OOP,争执和库都热火朝天。
现在,很多开发人员都被不确定的事件所困扰,他们不晓得应该怎么去做,也不晓得该怎么去构建。

起来,起来,React 替代品!

组件是有黏性的。但运行时老本、Javascript 驱动的 JSX 以及复杂性都有待探讨。很多不是来自大型科技公司的草根代替计划,曾经取得了宽泛的认同。让咱们对这些计划做一个总论:

Vue
当人们在评估迁徙到 Angular 2 或 React 时,Vue 填补了入门门槛低的空白。你不用为简单的 webpack 配置而放心。你能够从 CDN 上下载并开始应用对许多开发人员来说很直观的模板来构建组件。
外围团队能够应用路由和款式等外围组件,缩小决策疲劳。它还通过对模板进行动态剖析,缓解了 React 和谐算法的某些方面,以实现优化,放慢运行时。这被称为编译器告诉的虚构 DOM。

Svelte
Svelte 创始了预编译办法的先河,打消了咱们在运行时看到的复杂性和开销。
咱们的想法是要有一个能够自行编译的框架,并简化输入最小的一般 JavaScript。所有这些都是基于申明式组件和相熟的可变 Javascript 格调来放弃古代的创作体验。Svelte 完全避免了应用虚构 DOM,因而不会受到编写 Javascript 的不可变格调的束缚,这种格调能够用来做更新状态之类的事件。对于许多人来说,这是一个更简略、更理智地在 Web 上构建货色的模型。

Solid
Solid 有一个间接的和可预测的反馈性模型,其灵感来自 Knockout。像 React 一样,它也防止了应用模板来简化函数的可组合性。
而 React 采取的是一直从新渲染世界的办法。Solid 只渲染一次,并在不减少虚构 DOM 开销的状况下,应用精简的反馈性零碎进行细粒度的更新。Solid 看起来就像咱们许多 React 开发人员想要应用钩子的新代码那样。它的 API 兴许更人性化,并且在许多方面十分顺利,例如钩子的依赖数组,其重点是细粒度的反馈性和可组合的原语。

交换互鉴

对于每个框架,还有许多可说的。每个人都会在本人的基本模式和爱好上作出不同的衡量。
在事实中,进化往往是由人类的意志决定的。尝试不同的解决方案来解决以后的痛点,每个框架都从彼此中学习。其中一个重要的主题就是精简和简化。把事件从运行时移到编译时是这些主题之一,它激发了“React forget”,这是一个无望可能打消记忆化需要的个性。它们的共同点是解决了文件的交互局部。正如咱们所看到的,这是一个具备挑战性的方面,要以一种容易扩大的形式来解决。
同时,咱们看到了纯客户端渲染的衡量。当加载一个页面时,那个空白的白屏须要更长的工夫。在挪动设施和网络上,这真是一场劫难。对于很多网站来说,网页关上速度更快,且性能不升高,成为一个次要的竞争劣势。
咱们迈出了这一步,正在摸索通过首先在服务器上渲染内容来放慢渲染速度的办法(起初才发现这是一种衡量)。这个最后的倒退引发了许多“元”框架和 HTML 优先前端框架的新浪潮。

新一波的 JavaScript Web 框架

咱们不会进行摸索。咱们所有摸索的起点就是咱们开始的中央。也是第一次晓得这个中央。
受 PHP 的启发,Next 开始简化创立动态页面推送到 CDN 的过程。它还解决了在 React 应用程序中应用 SSR 的辣手问题。
它还提供了一些对于应用基于文件的路由来构建应用程序的意见,这很受欢迎。还有其余一些不错的特点。从那时起,又有一波“元”框架被创立。对于 Vue,咱们在 Nuxt 中有一个相似的框架。Svelte 的 Sveltekit,以及行将推出的 SolidStart。
这些都是服务器优先,旨在整合 Web 框架的所有局部和人体工程学。这并不仅仅是人们长久以来所关怀的互动元素。
对话的出发点是改良用户的教训和开发人员的教训,而非一种替换。

MPA 的出击

多页面架构从服务器上提供 HTML,其中导航是全页面刷新。疾速启动对于很多站点来说都是至关重要的,尤其是那些没有登录的站点。它间接关系到诸如搜寻排名和跳出率之类的事件。对于许多互动性低的网站和应用程序来说,应用像 React 这样的客户端渲染库,就过于夸大了。
对许多人来说,这意味着翻转脚本。做到 HTML 优先而不是 Javascript 优先,MPA 优于 SPA,并默认为零 Javascript。
像 Marko、Astro、Fresh、Rocket 和 Enhance 等框架都采纳了这种办法。与一些元框架相比,路由器停留在服务器上,而不是让客户端的路由器在第一次加载后接管。在 Javascript 生态系统中,这是对 Node 之后不久的基于服务器的模板制作的一种倒退。
这一轮的 MPA 与前几代不同。“Sprinkles”是在一个基于组件的模型中编写的,通常应用 island 模式。在前端和后端代码中应用雷同的语言。往往在同一个文件中共存。这就打消了在增加一些交互性时前端和后端结构不同的反复模板代码的问题。

渐进加强的回归

Remix 在 React 生态系统中带来了渐进加强的回归。
从技术角度来看,Remix 是 React Router 的编译器,和其余新兴的元框架一样,是一个边缘兼容运行时。它通过嵌套布局和数据获取 API,解决了 Facebook 通过 Relay 大规模解决的雷同挑战。
这容许晚期的代码和数据的并行获取。这是用 Suspense 实现“边渲染边获取”模式的一个良好前提条件。对渐进加强的强调意味着它的 API 基于 Web 规范,数据变异的故事基于 HTML 表单。
而不是通过连贯事件处理程序来进行必要的获取申请。你渲染表单,将数据提交给在服务器上解决它们的动作函数(通常在同一个文件中)。受到 PHP 的启发。
与 Next 相似,应用程序能够放大规模,像传统的服务器渲染的 MPA 那样在没有 Javascript 的状况下工作,或者按每页的规模扩大到交互式 React 应用程序。
Remix 还提供了许多 API 和模式,用于解决诸如乐观的 UI 更新、动态条件的解决以及优雅的进化之类的事件,这些都是你心愿一个专一于终端用户体验的三思而行的框架所提供的。

混合的将来

不要与 Quic 协定相混同。Qwik 这个框架是对于尽量减少不必要的 Javascript。尽管它的 API 看起来像 React,但它的办法与其余元框架不同,因为它专一于水化过程。
就像你能够暂停一台虚拟机并将其挪动到不同的物理机上。Qwik 把这个想法带到了服务器和浏览器之间产生的工作。它的“可复原”水化的想法意味着你能够在服务器上启动一些货色,而后在客户端上复原,而不须要任何从新工作。这与局部水化造成比照,后者在水化工作产生时进行挪动,而 Qwik 则试图在一开始就防止这样做。
这是一套乏味的想法,它利用了服务器和客户端紧密结合的力量,容许这种动静捆绑和服务。
这些概念开始含糊了 MPA 和 SPA 之间的界线,一个应用程序能够从 MPA 开始,动静地过渡到 SPA。有时(用更风行的话来说)被称为“过渡性应用程序”。

边缘的生存

同时,后端基础设施和托管也在不断改进。CDN 的边缘使咱们的 SPA 的动态资产服务变得简略而疾速。当初将运行时和数据转移到边缘也变得可行了。这是在浏览器之外创立一个新的运行时层,但依然尽可能地靠近用户。这使得将目前在浏览器中实现的许多事件移回服务器变得更加容易。同时在肯定水平上加重了这样做所带来的网络提早的取舍。
像 React 服务器组件这样的想法正在摸索将服务器组件的输入从这一层流向浏览器的概念。像 Deno 和 Bun 这样的新的 Javascript 运行时正在呈现,以简化和精简 Javascript 生态系统,并为这个边缘运行时的新世界而构建,为速度和疾速启动工夫而优化。
这也导致了利用框架采纳规范的网络 API 来在这一层运行。随着无服务器性能和流媒体架构被摸索进去。
流(Streaming)是这里的一个大主题。它容许提前刷新 HTML,因而浏览器能够在接管到它时逐渐进行渲染。在后端同时获取任何数据时,开始解决任何妨碍渲染的资源,如 CSS 和 JS。这有助于并行化许多其余程序往返行程。

概括

本文讲了那么多,但实际上只是涉及皮毛而已。对于本文中提到的最佳框架、架构或模式,以及咱们没有提到的有数其它框架、架构和模式,并没有一个通用的答案。它始终是对特定指标的衡量。而要晓得如何衡量,取决于你正在构建的货色、你的用户是谁、他们的应用模式,以及围绕要害用户体验的任何其余要求(如性能估算)的设定。
对于咱们中的大多数人来说,假相在某个两头的中央。新一波框架和翻新的平凡之处在于,它们提供了依据须要扩充和放大规模的杠杆。对于那些进入这个行业的人和那些经验丰富的人来说,投资于基本面总是一个不错的抉择。
框架的演变缓缓地将原生 Web 推向了更远的中央,打消了以前对框架的需要,并加重了之前的取舍,使咱们可能越来越多地采纳其原生个性。

原文链接:
​​https://frontendmastery.com/p…​​

退出移动版