网站标题替换,iis 网站乱码,嵌入式培训推荐,高中信息技术课网站怎么做文章目录前言开发范式底层框架方面趋势基于依赖追踪范式基于依赖追踪范式—共同点基于编译的响应式系统统一模型的优势和代价基于编译的运行是优化Vue Vapor Mode#xff08;input#xff09;工具链原生语言在前端工具链中的使用工具链的抽象层次基于 Vite 的上层框架上…
文章目录前言开发范式底层框架方面趋势基于依赖追踪范式基于依赖追踪范式—共同点基于编译的响应式系统统一模型的优势和代价基于编译的运行是优化Vue Vapor Modeinput工具链原生语言在前端工具链中的使用工具链的抽象层次基于 Vite 的上层框架上层框架 Meta FrameworksJS全栈的意义是什么 数据的前后端打通类型的前后端打通JS全栈的代价社区探索的方向写在最后前言
7/22 尤大大在直播中就 2022 Web前端生态趋势 做了分享本博主作为尤大大的忠实粉丝也决定将这些干货通过文字形式呈现出来传播给更多前端爱好者、从事者 随着主持人的一句“欢迎尤雨溪先生“ 尤大大又一次以线上的方式与大家见面。 尤大大从下面的三个前端领域的不同层次来展开了介绍
开发范式底层框架注大家比较熟悉的Vue、React这些框架层面工具链注像webpack这样的构建工具上层框架注例如Next.js、Nuxt.js
正式分享之前尤大大提出声明“本分享只代表讲着个人观点因为自己是框架和构建工具的作者肯定会包含利益相关和个人的偏见但是分享中会尽可能做客观的看法大家多多多包涵”下面就让我们饱享这顿“美味”吧 下面的内容是本博主根据尤大大的分享进行了一定的抽离和少许的个人总结如果内容出现歧义可以在评论区留言指点
开发范式底层框架方面趋势
过去几年中影响最大的开发范式层面的变化肯定就是我们的 React Hooks 随着他的推出可以说是启发了很多组件逻辑表达和逻辑复用的新范式在 React 生态中彻底取代了 Class Components 包括现在其实很少能够在 React 中看到 Class Components 了不仅如此其实在其他的框架中 React Hooks 也产生了很大的影响比如说我们 Vue 推出的 Vue Composition API 组合式API还包括受到 React Hooks 的启发的 Svelte3 更有 SolidJS 他是语法上相似于 React Hooks 实现上更相似于 Vue Composition API 。 随着 React Hooks 的推广和开发者对其的广泛使用他开发中的一些体验问题也逐渐被正视这里不可回避的一些体验问题的根本原因有以下几点
Hooks 执行原理和原生JS的心智模型的差异因为 React Hooks 是通过把组件的代码每一次更新都进行重复调用来模拟一些行为从而导致反直觉的一些限制不可以条件式的调用 React force Stale Closure 的心智负担如果你不传正确的依赖数组那么就会产生过期闭包必须手动声明 use Effect 依赖如何‘正确’使用 use Effect 是个复杂的问题需要 useMemo/useCallback 等手动优化否则的话就会不知不觉的导致一些性能问题
尤大大表示作为竞争框架的作者对 React Hooks 框架的看法可能相对更直接一些但这些也并非尤大大一个人的看法而是近年来 React 社区和 React 团队也已经意识到的问题当然 React 团队针对这些问题也在做改善的努力据代表性的改善从下三个方面 基于依赖追踪范式
在上面的这些改进之前其实很多 React 的社区成员也包括一些本身就不适用 React 的用户来说虽然 React Hooks 产生了重大的影响但是大家也意识到了他的一些问题反而是一些跟 React Hooks 相似的一些逻辑组合能力另一方面基于依赖追踪的范式开始重新得到了重视比如在 React 内部的 Recoil 当然在社区之外就有更多了比如 我们可以看一下就基于依赖追踪的范式而言上面三个方案的代码
SolidJS
//状态
const [count,setCount] createSignal(0)
//副作用
createEffect(() console.log(${count()}
//状态更新
setCount(count() 1)能够看出其实 SolidJS 和 React Hooks 非常相似
-副作用中的 createEffect 跟 React 中的 use Effect 其实是类似的但是 createEffect 并不需要去声明依赖在调用 count 函数的时候其实帮你收集了依赖
-状态更新的时候我们也并不需要用到 useCallback 这种额外的方式去创造函数来去传递给我们的事件侦听器这些都是非常符合直觉的
Vue Composition API
//状态
const count ref(0)
//副作用
watchEffect(() console.log(count.value))
//状态更新
count.value其实 Vue 中使用的 Composition API 跟 SolidJS 本质上的内部实现几乎是一样的只不过 SolidJS 看起来更像是 React 而 Vue 是通过一个 ref 对象对象上的 value 机可以读也可以写在读和写之中就会自动的追踪和更新依赖。
Ember Starbeam
//状态
const count Cell(0)
//副作用
DEBUG_RENDERER.render({
render: () console.log(count.current)
})
//状态更新
count.set(prev prev 1)Ember Starbeam 中的这个 Cell 其实就和 Vue 中的 ref api 几乎是一样的暴露出 count 为当前的值和 set 方法来进行状态的更新
基于依赖追踪范式—共同点
上面提到的三种基于依赖追踪的范式他们的共同点有什么呢 同时以依赖追踪为一等功名概念的框架中本身组件的设计肯定也是跟依赖追踪有紧密的结合所以组件的更新渲染也会有自动的依赖追踪也就是说组件的更新会更精确而不再依赖于一个状态从父组件到子组件一层层传递下去而是每一个即使是深层嵌套的组件也可以自发的更新整体上的性能会更好。
在 react 生态中的 Recoil 这样的方案虽然也提供了依赖自动的依赖追踪和一定程度的逐渐的更新优化但是因为他们仍然是需要在 React Hooks 的这个大的体系中使用的所以在很多其他的方面依然会受制于 hooks 的问题那么 Hooks 本身在这些方案之外还是会存在过期闭包等等 user fact 这些问题。
React Hooks 确实是启发了一个新范式的时代但是慢慢的我们也发现他自己自身存在的一些问题当然 React 团队正在试图解决这些问题同时在 React 体系之外开始有一些其他的具有同等的逻辑组合能力但同时避免了 React Hooks 这些问题的这些方案存在也渐渐的收到了前端社区的重视。
基于编译的响应式系统 不过即使是基于依赖追踪的方案我们也可以进行一些基于编译时的这个优化那这里首当其冲的就是 Svelte3
Svelte Svelte3 从一开始就是一个编译时优化方案上面就是 Svelte 组件中的一个使用状态的代码我们看到他跟他的状态就是这个 javaScript 的这个 let 这样声明一个变量就是一个响应式的状态那么你要更新这个状态就直接去操作这个变量就可以副作用是用一个神奇的编译式的魔法也就是这个 $ 这个 $ 的一个label这其实是 javaScript 的一个label语法来声明 $ 之后的这个语句会自动去追踪count这个变量的变化当count变化的时候这个语句就会自动重新执行那么我们可以看到这个跟我们之前的这个几个代码范例他所达成的目标其实是一致的只是他使用编译的手段使代码变的更加简洁但也正是因为简洁所以存在下面的限制 Vue Reactivity Transform
也正是受到上方的限制的启发Vue 在3.2的时候引入了一个实现性的功能 Vue Reactivity Transform 响应式转换 下面就是 Vue 转化后的一段代码 还是一个简单的变量声明但是我们用一个 $ref 这样的一个函数这个函数其实是一个编译时的一个宏的概念这个函数并不是真实存在的只是给编译一个提示那编译器通过编译之后就会把它转化成我们之前看到的基于真实的 ref 的代码。但是在使用时候体验就变成了只是声明一个函数然后使用这个变量和更新这个变量就跟使用一个普通 javaScript 变量没有区别。同时这个语法因为在声明的时候会显式的声明说哪个变量是响应声哪个变量不是响应式。所以这个语法可以在嵌套的函数中使用也可以在 TS/JS 文件中使用他并不限制于 Vue 文件所以这是一个更加朴实的编译响应式模型。
Solid -labels 在 Solid 的生态中其实也受启发于 Vue Reactivity Transform 他的社区用户做的一个 Solid-label也是基于 Solid 的响应式方案然后再做一层编译式的优化那么可以看到跟 Reactivity Transform 能够达成的效果是非常相似的。那最终的目的就是让大家可以用更简洁的代码去表达组件逻辑同时又不放弃这个逻辑组合像 React Hooks 那样进行自由的逻辑组合的这些能力啊。所以说这也是一个很有意思的探索方向。
统一模型的优势和代价 优势 和Svelte相比Vue的 Reactivity Transform 和 Solid -labels 都属于统一模型也就是他不受限于组件上下文它可以在组建内使用也可以在组建外使用优势就是有利于长期的重构和复用因为很多时候我们的大型项目中的逻辑复用都是在我们一个组件写着写着发现这个组件变得很臃肿很大的时候我们才开始考虑要把逻辑开始重新组织抽取复用那么由于 Svelte 的语法只能在组件内使用就使得把逻辑挪到组件外成为一个代价相当大的一个行为并不是一个简单把文把这个逻辑拷贝复制出去而是需要进行一次彻底的重构因为组件外用的是完全一套不同的系统但是像用 Reactivity Transform 和 Solid -labels 这样的方案呢我们就可以把组件内的这些逻辑原封不动的直接拷贝到组件外然后把它包在一个函数里面抽取就完成了那么这样重构时的这个代价就非常小也就更鼓励团队的这样的优化对于长期的维护性更有帮助。
代价 因为我们需要显示的去声明响应式的变量所以它会有一定程度的底层实现的抽象泄露也就是说用户其实是需要先了解底层的响应式模型的实现然后才能更好地理解这个语法糖是如何运作的而不像 Svelte 组建中的这个语法即使你完全不了解他底层如何运作的也可以几乎可以零成本的上手这就是一个长期的可维护性和一个初期的上手成本之间的一个平衡和取舍。
基于编译的运行是优化 讲完了状态管理我们在还可以聊一聊关于基于编译的运行时优化编译的运行时优化又是三个主要的代表如上图所示那首先我们可以看一下不同的这个策略 Svelte 的这个代码生成策略相对更更繁琐一些而 Solid 是基于先生成一个基本的HTML字符串然后在里面找到对应的 DOM 节点进行绑定而 Svelte 是通过生成一这个命令式的一个一个节点然后把节点拼接的这些 javaScript 代码但这个策略就导致掉同等的这个组件源码之下 Svelte 的每个组件的编译输出会更臃肿所以虽然大家感觉 Svelte 是以轻量出名的但其实我们会发现在相对大型的项目中在项目中组建超过15个之后Svelte 的整体的打包体积优势就已经几乎不存在了那么当组建超过50个甚至是达到100个的时候所有的体积会越来越越来越臃肿。而相对于而言我们可以看到 Vue 和 Solid 的编译这个输出啊整体的这个曲线就平缓很多所以其实在越大型的项目中。反而是 Svelte 的体积优势反而是一个劣势据我所知Svelte 团队也有在想要优化这一方面的可能会在下一个大版本中才能实现那么我们也会拭目以待。
同时尤大大提出 Solid 的编译性能确实是非常的猛其实在我们的 Vue 引入了很多编译时的优化以后我们的性能已经比 Svelte 好了但是离 Solid 还是有一定的距离。
Vue Vapor Modeinput
就上面提及到的编译时性能优化其实我们的 Vue 在早期的时候也做了这方面的探索如还在试验中的一个项目 Vue Vapor Mode 。 那同样的这个只有单文件组件输入我们现在是通过把模板编译成虚拟DOM 的一个渲染函数来进行运行时的实现。但是因为模板是一个编译源所以我们也可以选择在另一个模式下把它编译成不同的输出也就是一个更类似于 Svelte 输出。 这里这个输出的代码只是一个示例代码。并不一定是最终的代码也不是你需要书写的代码它完全是一个编译器的输出啊它的整体的思路就是一次性生成这个模板的静态结构、静态节点然后再去生成命令式的找到动态节点并对把它跟状态进行响应式的绑定的这样一些代码这个策略本质上就是 Solid 所采用的策略那么其实呢这个策略可以被所有的模板引擎所使用我们也在探索某个版本的 Vue 当中会引入一个可选的这样的一个模式把模板编译成这样的性能更优的运行时的这个体积也更小的一个模式当然这不会是一个破坏性更新因为我们的目标是可以让你渐进式的去使用这个功能。
工具链
原生语言在前端工具链中的使用 关于原生语言在前端工具链中的使用尤大大提出下面几个见解 工具链的抽象层次 最早的打包工具包括 brow/webpack/rollup 他们都是专注于打包的他们的抽象层次相对低当你想要用这些工具去做一个真正的应用的时候你需要使用大量第三方插件以及大量的配置来达到一个满足你自己要求的最终的形态。
那么在这个基础上就产生了像 Parcel/Vue-cli/CRA 这样的一些所谓的脚手架更高抽象层次的这些工具这些工具的特点是他们的抽象层的高也就说他们专注于应用专注于解决一个完整的应用方案呢它的相对而言的缺点就是它是一个比较复杂、比较庞大的一个黑盒儿。当你需要去进行自定义的定制的时候你就会不可避免的遇到一些问题比如说你跟他默认的功能产生一些意见上的冲突的时候你就会比较痛苦。
那么我们现在做的这个新项目 Vite 其实可能有一些同学已经在用了其实我们是在思考过这个抽象层次的问题之后才决定的他要走一个怎么样的路线也就是说 Vite 的 CLI 它是专注于应用层次啊它的抽象层次高它有很多的开箱记就是事先帮你寄配置好的功能那么大部分的情况下你开箱即用就可以达到跟 Parcel/Vue-cli/CRA 几乎同等的这些功能啊但是我们的API层面啊这个可能用到的同学会少一些但是它的API层面其实是专注于支持上层框架我们这个抽象层次会更低一点我们只解决一些所有的够 meta framework 都必须要解决的问题但是对于上层框架你用什么我们并不会做过多的限制反而是要做的更尽可能的灵活能够支持任何上层框架的用例所以这也是为什么 Vite 现在几乎成为了下一代的meta framework 共同的一个基底层选择。
基于 Vite 的上层框架 我们看到上面这么多的上层框架都在基于 Vite 说明我们 Vite 走的路线还是相对成功的。
上层框架 Meta Frameworks
JS全栈的意义是什么
如果我们讲到这个 Meta Frameworks也就是最典型的例子也就是NextJS 、NuxtJS、以及现在React社区中的新秀 Remix 等等那么当我们思考这样类型的JS全栈的时候我们做全栈的意义是什么那么相信在国内很多大企业的朋友都知道因为我们可以用同一个语言去做前后的连接我们可以做一些纯前端和纯后端都各自做不到的事情或者说之前需要很复杂的联调才能达成的一些事情那么JS全栈可以更好的去完成一个语言让我们可以把前后打通。那么我们能够打通什么呢
数据的前后端打通 类型的前后端打通 JS全栈的代价 一些新的全栈框架现在在试图去改善的一些问题首先。我们现有的这些前端框架比如说像主流的像 React、Vue 我们在做了服务端渲染之后还需要在前端要进行一次所谓的注水也就是 Hydrate 在追寻的过程中我们要确保在客户端和前端有同样的数据所以其实虽然我们的数据已经用于渲染HTML这些数据理论上在HTML里面已经都用过了但是我们还得再把这个数据再发送一次一起发送到前端让前端去进行 Hydrate 这样一个过程。因为没有这个数据我们在前端就没有办法保证 Hydrate 的正确性啊。
在客户端有些组件它可能在客户端是不需要交互的是静态的但是他在服务端用到了动态的这个数据但这个组件依然会被发到服务端它依然会可能产生这个javascript 运行时的代价啊以及缓慢的这个 Hydrate 会影响页面的交互指标也就是 time to interactive。有一些比较复杂的庞大的项目他可能这个注水的过程会把页面卡顿以至于虽然能看到页面但是没法交互要等个一秒钟才能交互等等会产生这样的问题。
社区探索的方向 社区现在新一代的这些全栈框架都在试图解决这些问题啊比如说像 React 提出了 server only components 其实从这个定义上我们就发现他是没有一个全栈框架围绕一个全栈框架去做其实用户是没有办法简单地使用的一个概念所以 React server only components 其实是一个必须要全站才能做的概念Next 当然也会去做然后其实 Nuxt 最近也开了一个 server only components 的一个提案所以说这个已经就是说 server only components 其实不仅仅是一个 React 独有的概念在很多其他的框架中我们可能慢慢都会出现类似的这个类似的东西。
还有一个方向就是减少注水hydration 的这个成本那么也就是局部的注水或者也叫 island architecture 就像大海中一个小岛只有这些小岛去对他进行注水让他交可交互啊。那么比较代表性的就是 astro、isles 和生态里面的 fresh 这些框架。
然后呢还有一个探索方向就是所谓的 fine-grainedresumabl hydration就是细粒度懒加载这个数据其实是Qwik这个框架所发明的Quick 的作者就是 Misko Hevery也就是 Angular 的原作者离开Google之后现在新开发的这个框架啊那么 Qwik 它主打的就是说它的特点就是不需要再把数据重新发送一遍。他是直接在生成的渲染的html里面嵌入所需的数据从而使得客户端的js可以直接在html里面获得所要的数据甚至是可以跳过一些需要执行的js步骤直接跳到一个已经完成的状态上面去这就是所谓的resumable 也是一个比较值得关注的一个方向。
以及我们的 Vue 生态里面生态里面有一个我们的 VitePress我们其实探索的是一个在我们页面的核心内容其实是静态的MD文件的前提下如何做高效率的 hydration 那么我们做的是所谓的 hydration 就是整个的外部的这个一个框架内容外包着的这一层ui是动态的然后呢在内部静态的里继续进行局部的注水然后这样的话我们依然可以获得一个单页应用的体验但又获得很好的客户端注水的性能。
到这里呢尤大大的分享就结束了本博主总结的内容中如果存在争议大家可以在评论区进行指点希望能够给大家带来一定的收获和成长
写在最后
如果你正在使用Vue进行前端开发或者是你准备学习Vue或者是你对Vue有一定的兴趣邀请你们到CSDN-Vue技能树来打卡https://edu.csdn.net/skill/vue