登高望远,一文解答 2023 年你最关心的前端热点问题

动手点关注

干货不迷路

本文预计阅读 25 min,建议先收藏后观看~

一、刀光剑影的 2022

时光荏苒,这绝不平淡的 2022 年已经走上历史的黄页,新的一年也逐渐看不到故人回首的光影。感谢你对前端技术领域持续关注,我们一直在这里等你。

① 2022 年前端人偏爱什么?

登高望远,一文解答 2023 年你最关心的前端热点问题_第1张图片

数据来源 bestofjs (https://risingstars.js.org/2022/en)

  • 可爱的小包子 Bun 夺得头筹Bun 是类似 Node 、Deno 的 JavaScript 运行时。仅一个月内,就在 GitHub 上获得了超过两万颗 Star。Bun 试图让解释器本身更快。它是用 Zig 编写的,并且使用 Apple 的 JavaScriptCore,类似于 Node 使用 V8 的方式。Zig 是一种新兴的低级语言,出现在 C++ 占主导地位的领域。Bun 虽然现在还不能接入生产(缺乏 Windows 支持),但是无限的潜力让人不禁感叹一句未来可期。

  • 如果你要试试跨端技术, Tauri 是个不错的选择, 这是一个由 Rust 编写的项目,利用 Web 技术创建跨平台的桌面应用程序。在 2021 年的榜单中它还排在第五位,一颗冉冉上升的新星即将被越来越多的开发者所熟知,期待跨端技术为我们带来更多的效率提升。

  • React 前端从业者绕不过去的高峰, 2022 年前端生态圈的丰富度依旧保持 React > Vue > Angular

  • 10月发布的 Next.js 13 利用了 2020 年 React 17 推出的 React Server Components。这是一个非常富有魅力的方案设计,不仅如此 ,你还可以使用比现有打包工具快数倍的 Turbopack。

  • Vite “快”是它的核心, 它主要解决的核心痛点就是项目启动缓慢, 作为下一代前端开发与构建工具,极速的服务启动将带来最佳的开发体验。

② 你也许会有同样的疑问?

团队的新项目要不要试试用 Svelte 来构建?但不清楚好用吗?性能怎么样?

RSC(React Server Components)SSR 傻傻分不清楚?

项目正在用的测试库(Jest、Cypress)要不要升级到最新版本?

听说了 Turborepo 的强大打包实力,但是我当前在哪里可以体验到,现有项目可以接入吗?

老项目想从 Babel 切换到 SWC ,有没有什么限制?收益大吗?

到底用 Tailwind 还是 styled-components ?团队内部已经吵起来啦!

手上有个业务复杂的大项目,有没有必要迁移成微前端架构?

Github Actions 是什么?我们可以跨团队共建可复用的 CI 节点吗?

ChatGPT 可以帮我写代码吗?什么是 web3.0跨端方案选什么?

如何搞点炫酷的Web 3D听说 Serverless 是前端开发的福音?

等等等等......问题太多啦,什么时候才能全部搞明白?

③ 往下看,马上给你解答

如果你对上面所叙述问题有同样疑惑的话,请一定要读完本文!相信我们的精心制作一定会给你带来丰富的收获,一起走入跌宕起伏风云变幻的前端世界吧!

“天道酬勤,我们与梦想总是双向奔赴”

二、Web 框架

登高望远,一文解答 2023 年你最关心的前端热点问题_第2张图片

数据来源 star-history (https://star-history.com/#sveltejs/svelte&facebook/react&vuejs/vue&lit/lit&solidjs/solid&Date)

从近年来的数据来看,React 和 Vue 是现如今前端入门必学的两大框架,各大技术论坛上也常常有人为两者孰优孰劣吵得不可开交,从此便可显现出两大框架的布道范围之广泛,但如果仅仅局限于让两个框架一较高下,那格局便小了。Vue 和 React 两者的差别说大也不算大,它们的主体思想都是数据驱动视图,直观表现都是响应式更新,实现载体都是 Virtual DOM(除了 Vue1 )。由于采用了 Virtual DOM ,React 和 Vue 在前端都天生携带一个体积不小的“运行时”,它将根据输入的数据生成 Virtual DOM,并执行调度和渲染流程。

根据 HTTP Archive 报告 (https://httparchive.org/reports/state-of-the-web#bytesTotal) 显示,2015 年网页的中位数大小为 1280 KB ,到 2022 年已增长到了2000+ KB ,庞大的网页会占用大量网络带宽,使页面加载时长更长,一些网络资源不发达的地区更能体会到这种影响。为了改善这种趋势,Svelte 出现了。Svelte 旨在让开发者以最少量的代码,产生最轻量的响应式应用,并且在运行期间产生最小的性能开销。从原理上讲,Svelte 便与 React 和 Vue 两者有一点不同:它不依托 Virtual DOM 技术来实现响应式更新,取而代之的是直接利用自定义的语法规则来实现响应式数据的分析、绑定以及响应式过程代码的实现,大部分场景下最终编译生成的产物大小可以做到和原生实现媲美,且性能不逊色于 Vue 和 React。

Svelte 在 2021 年度 stackoverflow 网站上关于“最受欢迎的 Web 框架” (https://insights.stackoverflow.com/survey/2021#most-loved-dreaded-and-wanted-webframe-love-dread) 调研中位列第一,在 2022 年度的此项调研 (https://survey.stackoverflow.co/2022/#most-loved-dreaded-and-wanted-webframe-love-dread) 也位列第二,从好评比例来看使用者们对这个框架很满意。github stars 的增长速度也说明了 Svelte 是一个在开发者社区中十分有发展潜力的 Web 框架,在生态日趋完善之后,Svelte 很可能是一个比肩 React 和 Vue 的存在。

下面我们将从各方面来看看这个新星框架与 Vue 和 React 相比都有哪些区别,从而让大家对这个框架的潜力和局限性有更多的认识。

① 状态管理和更新机制

Svelte 是一个模版编译器,一个模版文件分为 Script 、CSS 、HTML 三个部分用以描述一个组件:demo (https://codesandbox.io/s/frosty-worker-o66p2f?file=/App.svelte), HTML 部分采用 Mustache 模版引擎的语法动态地描述 DOM 树。Script 分为 Module Script 和 Instance Script ,分别用于外部库的引入组件状态的维护。编译器工作流程大概分为四个步骤:生成 AST 、封装 Component(收集上下文数据)、渲染 Component(拼装代码)、生成最终代码(链接 runtime 库)。Svelte 通过 AST 的方式对代码进行静态分析,可以实现数据和视图的绑定,还可以根据上下文和配置文件,实现剪枝和依赖的按需引入,尽最大的努力优化产物大小和性能。Svelte 为了避免不必要的 DOM 操作,为产物实现了一套原理十分简单的基于 Dirty Mask 以及守卫判断的 DOM 更新机制,实现了细粒度的更新。

Virtual DOM 类的技术,则是在运行期间实现数据和视图的绑定,当组件递归式地执行渲染时,组件内部的状态便被动态地注册,当组件更新状态时,运行时将调用用户定义的渲染函数,重新计算 Virtual DOM ,并利用 DOM Diff 算法来决定哪些 DOM 需要更新,用户如果想优化 Virtual DOM 的计算流程,避免不必要的计算,则需要自行调用运行时提供的函数来实现剪枝操作。

② SSR渲染

Svelte 天生自带了 SSR 渲染的能力,用户如果有相关需求,便可通过简单的配置实现 SSR 产物的生成;Vue 如果要生成 SSR 产物则需要借助 Nuxt 、Quasar 等专门的呈现框架库的支持,React 与之对应的库则是 Next 、Remix 等。

③ 跨平台

React 、 Vue Svelte 都具有良好的跨平台能力。由于 Virtual DOM 把渲染过程高度抽象化,Virtual DOM 不单单可以描述浏览器的 DOM 结构,还可以适配其他如 Android Layout 等渲染目标,抹平了浏览器应用和客户端应用的差异。

④ 产物大小

Svelte 最大的卖点之一便是其小而精的产物体积。Svelte 由于可以根据源代码上下文只编译出对功能实现有用的代码,并且对 Runtime 包的依赖做按需引入,另外其 Runtime 包的实现十分原子化和扁平化,编译器很容易对产物做剪枝处理,在这些机制的共同作用下保证了 Svelte 以最低的空间成本实现最终产物。不过由于需要实现组件的状态和生命周期管理等功能,单个组件的源码-产物大小转换放大倍数可不小,和 React 这种可以以一个函数直接描述一个组件的形式相比,Svelte 产物体积随源码体积增长的斜率要比 React 大。有人创建了一个项目尝试以图表的形式直观地表现出了这个效应。

登高望远,一文解答 2023 年你最关心的前端热点问题_第3张图片

数据来源 github (https://github.com/halfnelson/svelte-it-will-scale)

将两条体积增长线放一起可以直观地看出,当源码大概达到120 KB 规模时, Svelte 相较于 React 将不存在产物体积优势。 不过这种规模的项目在现实世界中很难达到,对于使用者来说,完全可以认为 Svelte 是一个轻量级的框架。

⑤ 性能

Svelte 的响应式更新机制较为简单,它会使用状态更新的 update 函数,这个函数内部只做了两件事:比较并更新 component 上下文信息、标记脏数据掩码(make_dirty) 。Svelte 的这套响应式更新机制远没有 React 和 Vue 的调度更新复杂,实现的更新粒度也十分细,不过在某些场景下这种机制存在弊端。

由于是基于静态代码分析, Svelte 难以从视图中收集到十分详细的订阅信息,这导致了 Svelte 对于对象引用的赋值操作可能会存在无用更新

在这个 demo (https://codesandbox.io/s/lingering-resonance-rjz5gh?file=/App.svelte) 中,虽然对于 person 状态视图中只订阅了其 name 引用,但是对于另一个引用 age 的修改操作,仍然会触发更新操作的执行。

这种情况在 Vue 的实现中并不会发生,Vue 状态的依赖是在运行时收集,因此可以实现在状态修改时更精准地判断视图是否需要执行更新操作,从这个 demo (https://codesandbox.io/s/musing-dhawan-k8n2wn?file=/src/App.vue) 中我们可以得到验证。

Svelte 的性能表现和 Vue 、React 等框架相比究竟如何,我们可以通过一个项目来有更直观的认知(https://github.com/krausest/js-framework-benchmark)

这个项目对大量的前端框架实现了表格数据的增加、删除、换位等操作,并通过无头浏览器测试各种操作的性能,我们可以通过跑分结果大概了解各种框架数据更新操作的性能,这里筛选了原生、Vue 、Svelte 、React 的结果。

登高望远,一文解答 2023 年你最关心的前端热点问题_第4张图片

从结果来看,Svelte 的性能与 Vue 不相上下,它们都比较接近原生实现的性能,并且大部分操作性能都优于 React 。不过,实际上在很多情况下,一个系统整体的性能并不取决于选择的框架,而是取决于开发者功能实现是否合理,Svelte 在很大程度上已经帮助其使用者完成一部分优化工作,这可以说是它的魅力所在

三、呈现框架(Rendering Frameworks)

作为一名优秀的前端工程师,当你做好了技术选型并确定了某个 Web 框架准备施展拳脚时,会发现要从头构建一个完整的 Web 应用程序还需要考虑许多重要的细节。

  • 使用打包构建工具(例如 Webpack、Rollup)打包代码。配置 css 预处理器、并使用 Babel 等编译器进行代码转换

  • 应用的路由设计

  • 针对生产环境进行优化,例如代码拆分

  • 提高页面性能和 SEO,考虑服务端渲染 (SSR)

Web 框架如 React、Vue 为开发者提供了官方的脚手架,让我们无需深入学习配置构建工具的情况下就可以快速创建一个 Web 应用,使我们专注于编码,不用操心构建工具。

通过脚手架创建的项目可以解决部分工程化的问题,然而脚手架不是万能的。当我们想搭建一个 SSR Web 站点就需要用到更高阶的框架能力、更高级的构建配置、更复杂的项目部署。

呈现框架为开发者提供了更多便利,下图是近年来相关框架的使用度排名:

登高望远,一文解答 2023 年你最关心的前端热点问题_第5张图片

数据来源 stateofjs 

(https://2022.stateofjs.com/zh-Hans/libraries/rendering-frameworks/)

① Next.js

Next.js 是一个灵活的 React 框架。 它每周有超过 300 多万次 npm 下载和 9 万多个 GitHub Star,足以说明了它是构建 Web 最流行的框架之一。2022 年10月 发布了 Next.js 13 ,带来了一个全新的版本:

  • 引入了全新的构建工具

  • 改进路由和布局体验:更简单、更快、更少的客户端 JS

Webpack 已被下载超过 30 亿次,它已然成为构建 Web 不可或缺的一部分。然而它也已经达到了使用基于 JavaScript 的工具可能达到的最大性能的极限。 所以 Next.js 另辟蹊径,选择了 Turbopack,它的架构吸取了 Turborepo 和 Google 的 Bazel 等工具的经验教训,这两个工具都专注于使用缓存来避免重复执行相同的工作

  • 函数级缓存: 通过缓存函数调用的结果而不是重做以前完成的工作将节省大量时间。

  • 按需编译: 如果浏览器请求 HTML,将只编译 HTML——而不是 HTML 引用的任何内容。

Next.js 13 也引入了一个新的基于文件系统的路由器,该路由器构建在 React Server Components 之上,支持布局、嵌套路由、加载状态、错误处理等。

React Server Components

RSC 出现的背景

主要原因是因为大量的 React 组件依赖数据请求之后才能做渲染。如果是这样,那么每个组件自己去请求数据的话会出现子组件要等父组件数据请求完成,到渲染子组件的时候才会开始去请求子组件的数据,也就是官方所谓的 WaterFall 数据请求队列的问题。而将数据请求放在一起又非常不便于维护,出现了一个两难的问题。

RSC 是如何解决组件依赖数据渲染的问题?

既然组件是依赖数据做渲染的,那为什么接口不直接返回渲染后的组件呢?所以他们提出了 Server Components 的解决方案。方案的大体是将 React 组件拆分成 Server 组件(.server.tsx)和 Client 组件(.client.tsx)两种类型。 其中 Server 组件会在服务端直接渲染并返回。

SSR 的区别是什么?

  • SSR 是在服务端拼接好 HTML,返回给客户端;而 RSC 是在客户端渲染的,服务端输出的是 chunks

  • SSR 的请求响应是 HTML,是无状态的;而 RSC 在渲染的时候,不影响 Client Components 的状态

SSR 和 RSC 可以结合使用,SSR 目前大部分被用在首屏加载的场景,之后的页面交互可以选择用 RSC

RSC 有哪些优势?

  • 在服务端获取数据通常更紧密,比在浏览器中请求速度更快

  • Zero-Bundle-Size:RSC 不会打包到端的 bundle 中,依赖的 npm 包也不会,减少了发送到 客户端 JavaScript 数量

  • 使用大型库时 RSC 开销更小,举例:项目中使用 Markdown 转换 HTML 的 npm 包,在服务端不需要反复下载安装,而在浏览器中的每次请求都需要获取。

登高望远,一文解答 2023 年你最关心的前端热点问题_第6张图片

大家可以通过 React 官方的演讲和实例 (https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html) 来了解 RSC 的更多内容。React Server Components 仍在研发中, 如果自己在项目使用 RSC 的成本还是很大的,所以推荐在 Next.js 中使用 RSC ,这样会轻松很多。

同时,如果使用 Next.js 中的 RSC 和 嵌套布局 (https://beta.nextjs.org/docs/routing/pages-and-layouts) 可以立即呈现页面中不需要特定数据的部分,并显示正在获取数据的页面部分的加载状态 (https://beta.nextjs.org/docs/routing/loading-ui)  使用这种方法,用户不必等待整个页面加载完毕就可以开始与之交互。

登高望远,一文解答 2023 年你最关心的前端热点问题_第7张图片

也可以与 React Suspense (https://beta.reactjs.org/apis/react/Suspense) 结合使用,可以获得以下优势:

  • Streaming Server Rendering - 从服务器到客户端逐步渲染 HTML。

  • Selective Hydration - React 根据用户交互优先考虑哪些组件首先进行交互。

② Nuxt.js

Nuxt.js (https://nuxt.com/) 是一个构建于 Vue 生态系统之上的呈现框架,它为编写 Vue SSR 应用提供了丝滑的开发体验。

2022年11月,官方发布了 Nuxt 3.0 稳定版,Nuxt 3 是基于Vite (https://vitejs.dev/) Vue3 (https://vuejs.org/) 和 Nitro (https://nitro.unjs.io/) 的重写版本,具有一流的 Typescript 支持。

开发者可以基于它初始化新项目的基础结构代码,或者在已有 Node.js 项目中使用 Nuxt.js。

③ 对比

Next.js、Nuxt.js 这两个框架的重心都在 Web 部分,对 UI 呈现部分的代码组织方式、服务器端渲染功能等提供了完善的支持,让开发者开箱即用。

  • 在路由结构设计上,两者都采用了文件结构即路由的设计方式。

    • 默认以 pages 文件夹为入口,生成对应的路由结构,文件夹内的所有文件都会被当做路由入口文件,支持多层级,会根据层级生成路由地址。

  • 两者都支持动态路由访问,命名规则不同:

    • Next.js 中括号命名 /pages/foo/[id].js -> /pages/foo/123

    • Nuxt.js 下划线命名 /pages/foo/_id.js -> /pages/foo/123

  • 两者都内建提供了 link 类型组件(LinkNuxtLink)当路由跳转时,组件会检测链接是否命中路由,命中组件出现后会触发对应路由的 js 资源的加载。(前端路由跳转,不会重新加载页面)

  • 两者都提供了数据预取的方法

    • asyncData:组件可导出 asyncData 方法,返回值会和页面路由组件的 data 合并,用于后续渲染,只在页面路由组件可用。

    • fetch:在 2.12.x 中增加,利用了 Vue SSR 的 serverPrefetch,在每个组件都可用,且会在服务器端和客户端同时被调用。

    • 渲染过程的最后,页面数据与页面信息写在 window.NUXT 中,同样会在客户端被读取。

    • 渲染过程的最后,会生成页面数据与页面构建信息,这些内容会写在

你可能感兴趣的:(前端)