当前位置: 首页 > Web前端 > vue.js

vue3--关于新特性和优点(注释)

时间:2023-03-31 22:58:25 vue.js

vue3performancetree-shakingsupporton-demandpackagingcompositionAPIFragment,Teleport,SuspenseBetterTyperScriptsupport(更好的TyperScript支持)CustomRenderAPI(自定义渲染API)PerformanceRewrittenvirtualdom实现(虚拟dom重构)传统虚拟dom的性能瓶颈:(1)vue虽然可以保证触发更新的组件最小化,但是在单个组件内部还是需要遍历组件的整个虚拟dom树。(2)传统虚拟dom的性能与模板大小正相关,与动态节点数量无关。在整个模板中只有少量动态节点的某些组件的情况下,这些遍历是一种性能浪费。(3)JSX和手写渲染函数是完全动态的,transition的灵活性导致运行时优化的信息不足。为什么不放弃虚拟世界?(1)在高级场景下,手写渲染函数表现力更强;(2)生成的代码更简洁(3)兼容2.x,2.x部分用户可以手写render函数,甚至使用JSXvue特点是底层是VirtualDOM,上层图层包含带有大量静态信息的模板。为了兼容手写render函数,最大限度的利用模板静态信息,vue3.0采用动静结合的方案,降低虚拟dom操作的粒度,每次触发更新不再以组件为单位进行遍历。Vue3利用编译器的特性,通过分析模板,在模板编译时进行一定的分析优化,生成更优化的虚拟dom渲染函数,可以大大减少编译时生成的javascript中留下的优化提示。vue3.0虚拟dom的主要变化:(1)模板根据动态节点指令划分为嵌套块。每个区块的内部节点结构是固定的,每个区块只需要用一个Array来追踪自身包含的动态。节点使得每个触发器更新都与动态内容的数量相关。(2)虚拟dom提供了模板以外的逻辑表达能力,更好更灵活的逻辑表达能力(对于类库和高级工具的作者来说,可以脱离模板,做一些相对复杂的渲染逻辑表达)。Compiler-informedfastpaths编译优化,Runtime性能可大幅提升。(1)虚拟dom的优化(2)proxy的使用Vue2.0中创建组件实例的开销比较大。每次创建一个实例,需要在this上暴露很多东西,在this上暴露的每一个属性都是用Object.defineProperty定义的,这个操作其实是相当耗时的(层层递归的自定义属性描述符是required),基于proxy的前提下,直接丢弃属性定义的过程,然后暴露给渲染函数的this,其实就是一个proxy。当你去代理拿东西的时候,你必须动态地决定返回什么。例如,vue2.0定义了一对方法,computed,data和props,所有这些都必须从this中暴露出来。之前的方法是一个一个的获取Object.defineProperty。现在相当于说拿到一个属性后,我们代理拦截你,然后根据我们之前已经知道你的属性是prop什么的,直接从prop返回给你。更高效的组件初始化vue3中的组件初始化创建也进行了专门的优化。1.3~2x更好的更新性能与vue2相比,有1.3~2倍的性能优势。2~3xfasterSSR服务端渲染也完全重写,从模板编译到服务端渲染生成完全不同的渲染函数,可以比vue2快2~3倍。模板解析diff时跳过静态节点。静态节点被提升到渲染函数的外部。在渲染的时候,我们传入这些静态内容,这使得我们只需要在第一次创建这些节点的时候就生成这些节点。在后续的更新中,只需要传入这些节点,就不需要重复创建节点了。即:这些静态节点只需要创建一次,运行更新时不需要创建新的和销毁旧的,这样内存也得到了优化。同时在更新的时候,直接跳转到对应的DOM更新,只关注一些动态属性,这样就不需要diff每一个DOM,不管多深的层级,直接到达DOM改变状态,从而提高性能。这样既突破了虚拟dom更新的性能瓶颈,又保留了手写render函数的灵活性。事件监听器的cachecashehandlers对onclick进行缓存处理。第一次渲染时,因为_cache[1]不存在,Vue会自动生成一个内联函数,将_cache[赋值给cache[1]1]=(...args)=>(_ctx.a(...args),这样我们就可以在组件上自动调用最新的onclick,在后续的更新中,我们只需要从缓存中读取_cache[1]读取同一个函数即可,既然是同一个函数,就没有需要更新,所以@click也会被当成static,click里面手写的内联函数也可以套现,用JSX写这个会导致span每次都生成一个新的函数,这个函数会重新绑定对这个元素,Vue中启用了Cashehandlers,甚至把写好的内联函数都当成静态的,这种优化在给组件传递一个函数时尤为明显,如果不使用事件监听缓存,子组件会当父组件更新时被更新。并通过事件监听缓存m机制,我们传递给子组件函数,它会在调用时动态的寻找组件中最新的函数,不需要更新子组件。SSR渲染优化会在服务端尽可能将静态部分处理成字符串,并在SSR渲染时返回。如果有动态节点,可以放在字符串中,将动态数据编译成模板字符串推送。Tree-shaking大多数可选功能(例如v-model、)现在是tree-shakableBare-baneHelloWorld大小:13.5kb11.75kb仅支持组合API包括所有运行时功能:22.5kbhanstill更多功能,但tVue2(1)启用更多可选内容进行tree-shaking,例如v-model和现在可以进行tree-shaking,不用时不会将package放入项目中;(2)当模板中只包含一个简单的HelloWorld时,框架带来的工程体积只增加了13.5kb。如果使用CompositionAPI来支持其他选项API的替换,大小将变为11.75kb。在vue3.0中,为了兼容之前的版本,optionsAPI默认不会被移除,但是会有开关提供移除这些API的选项;(3)即使vue3.0的所有东西都放在,它只有22.5kb(包括所有新功能)。这个体积比vue2.x小,但是功能更多。webpack有tree-shaking的功能,但是TreeShaking的前提是要写ESModule(import...)。vue3在浏览器中还是有一个全局的vue对象,但是在使用webpack的时候,没有默认的导出,不能导入vue,而把vue作为对象本身来操作,所有的api都要导入。这样,一些不会用到的函数就不会被引用。compositionAPIhttps://composition-api.vuejs.org/(1)可以和optionsAPI一起使用compositionapi可以看作是新增的api,不影响已有api的使用,甚至可以一起使用使用现有的api。(2)灵活的逻辑组合和复用在vue2.x中,我们可能会使用mixin来提取逻辑。尝试使用compositionapi来提取逻辑。如果你是逻辑库的作者,在提供可复用逻辑时,尽量使用compositionapi来提供。(3)几个主要的APIvue2:数据传给Vue,Vue把它变成响应式的。Vue3:给它一个对象,然后让这个对象响应。然后,Vue跟踪它在需要时使用的响应式依赖项,并在依赖项更改时重新渲染。(reactive)vue3中暴露了一个新的API叫做watchEffect,effect是一个副作用。例如:打印一个数字,这个数字是从responsive对象中取出来的,当第一个pass被执行并取出这个数字时,这个数字被作为一个依赖并在当前的副作用函数中被跟踪,每当这个依赖发生变化时,这个副作用函数会再次运行。而不能被对象响应的数据,比如一些原生的数据结构,比如数字,布尔值等,那么布尔值就需要用一些东西(ref)包裹起来。使用对象的时候,不需要去封装它,但是如果一定要传递非对象的数据,就得用ref来封装了。核心:reactive\ref\watchEffect\others是这三者的组合。Fragment、Teleport、SuspenseFragment不再局限于模板中的单个根节点手动渲染函数可以简单地返回数组“Justworks”vue2模板只有一个根节点。Vue3:文本,多个节点,甚至一个v-for都会自动变成片段。如果使用渲染函数,也可以在渲染函数中直接返回一个数组自动成为片段。Teleport以前称为更多细节待分享@LinusborgReactPortal可以接收一个disable的参数,将原本传输的东西移回原来的渲染树中。Disabled用于一些响应式设计。当屏幕很宽时,可以拉出瞬移。当屏幕变窄时,可以放回原来的树形布局。多个传送可以将内容添加到同一组件。SuspenseWaitonnestedasyncdependenciseinanestedtreeWorkswithasyncsetup()WorkswithAsyncComponents在页面数据到达之前,可以先呈现其他东西以优化用户体验。与react相比,走的是轻量级路线。在将嵌套的组件树渲染到屏幕上之前,先将其渲染到内存中。在渲染过程中,所有具有异步依赖的组件都会被记录下来。当所有嵌套的异步依赖都被解析时,将整个树渲染到dom中,异步依赖组合API,并使用asyncsetup()选项。在你的组件中,如果你有一个asyncsetup函数,这个组件就会被认为是一个异步组件,这个悬念会等待所有的asyncsetup和promiseresolve,然后渲染整个数,实现了一定程度的嵌套异步派遣。Suspense本身可以使用低级异步原语来实现更高级的功能。比如Vue3的异步组件,内部是通过suspense和asyncsetup来实现的。默认情况下,它不能与悬念绑定。如果想使用suspense来管理一些嵌套的异步组件之间的加载,也可以加上。BetterTypeScriptSupportCodebasewritteninTSw/auto-generatedtypedefinitionsAPI在JS和TS中是相同的事实上,代码也将大体相同TSXsupportClass组件仍然被支持vue-class-component@next目前处于alpha(1)vue3是用TS改写的,但不是写TS的意思。在vscode中安装插件后,连用的JS都会补全并提示参数。当然,使用TS会使用更好的静态检查;(2)js中的API和ts中的一样,其实代码基本一样;(3)多伦多证券交易所支持;(4)类组件会继续支持,但需要引入vue-class-component@next,目前处于alpha阶段,不推荐使用;CustomeRenderAPINativeScriptVue集成正在进行中@rigor789Users已经在试验可以与普通Vue应用程序一起使用的WebGL自定义渲染器(Vugel)(1)正在进行的NativeScriptVue集成;(2)用户你已经可以尝试使用WebGL自定义渲染器,它可以与普通的Vue应用程序一起使用;customrendererapi,vue2也可以,之前weex,nativescriptvue都是通过vue2的一个非暴露的api,去实现这个功能。但是vue2引入了一些依赖同步问题。Vue3是一个内置的API。最后:router和vuex都是专注于对vue3的兼容,目前不会有大的变化。参考文章(非常感谢知识分享):https://zhuanlan.zhihu.com/p/92143274https://blog.csdn.net/zemprogram/article/details/105726956