vue3學習(一)之20200421前端圈尤雨溪直播vue3新特性

終端用戶感知明顯的是

  • 性能優化

  • Tree-Shaking (搖枝算法)

我摘抄了PPT,看PPT就很詳細

Performance(性能優化)

  • Rewritten virtual dom implementation

    • 考慮兼容性

    • 對於庫作者,模板之外,脫離模板,實現邏輯複雜的渲染表達

  • Complier-informed fast paths

  • More effcient component initalization

  • 1.3 - 2x better update performance

  • 2 - 3x faster SSR*

all those thing based on benchmarks simulates typical scenarios ,may vary based on actual application

Tree-Shaking support

https://vue-next-template-explorer.netlify.app/

以上vue3最新的master commit 代碼來玩的玩具

如何使用vue-next-template-explorer

import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"
​
export function render(_ctx, _cache) {
  return (_openBlock(), _createBlock("div", null, [
    _createVNode("span", null, "static"),
    _createVNode("span", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)//1 patchflag flag是編譯時生成的一個配置,只有帶patchflag的Node(節點)會被追蹤,比較text的文字變動
      
  ]))
}
<div>
  <span>static</span>
  <span>
    {{msg}}
  </span> 
</div>

舉例vue2渲染Dom的算法diff例子和vue3渲染Dom的例子

Vue2

<div>
  <span>static</span>
  <span>static</span>
  <span>static</span>
  <span>
    {{msg}}
  </span> 
  <span>static</span>
  <span>static</span>
  <span>static</span>
  <span>static</span>
</div>

默認渲染VirtualDom的diff算法是將整棵樹的style遍歷一次,每一個style的舊Props跟新的Props有什麼變化,js快,但是應用大了之後,消耗性能0

而vue3的diff算法是隻需檢查帶有patchflag的節點過一遍就是了

Vue3

<div>
  <span>static</span>
  <span>static</span>
  <span>static</span>
  <span>
    <span>{{msg}}</span>
  </span> 
  <span>static</span>
  <span>static</span>
  <span>static</span>
  <span>static</span>
</div>

哪怕這個span是經過嵌套的,vue3仍然不需要遍歷,因爲加入patchflag的節點會和block(div)節點綁定在一起,所以進入第一句(_openBlock(), _createBlock("div", null,之後就會找到綁定的節點,不需要遍歷其他

靜態ID綁定

  <div>
  <span id='helloId'>
    {{msg}}
  </span> 
  </div>
    _createVNode("div", null, [
      _createVNode("span", { id: "helloId" }, _toDisplayString(_ctx.msg), 1 /* TEXT */)
    ]),

靜態ID的綁定與雙向綁定text的方式無變化

動態ID綁定

  <div>
  <span :id='helloId'>
    {{msg}}
  </span> 
  </div>
    _createVNode("div", null, [
      _createVNode("span", { id: _ctx.helloId }, _toDisplayString(_ctx.msg), 9 /* TEXT, PROPS */, ["id"])
    ]),

此時,patchflag產生變化,告訴我們不僅有text文字的變化還有屬性props的變化,並且向我們指明是屬性id動態變化,目的是讓動態更新的時候關注真正變化的東西

Cache Handlers(事件偵聽器的緩存)

  <div>
  <span :id='helloId' @click='OnClick'>
    {{msg}}
  </span> 
  </div>
//如果不選擇  Cache Handlers
_createVNode("div", null, [
      _createVNode("span", {
        id: _ctx.helloId,
        onClick: _ctx.OnClick
      }, _toDisplayString(_ctx.msg), 9 /* TEXT, PROPS */, ["id", "onClick"])
    ]),
//使用Cache Handlers
    _createVNode("div", null, [
      _createVNode("span", {
        id: _ctx.helloId,
        onClick: _cache[1] || (_cache[1] = $event => (_ctx.OnClick($event)))
      }, _toDisplayString(_ctx.msg), 9 /* TEXT, PROPS */, ["id"])
    ]),

onClick: cache[1] || (cache[1] = $event => (_ctx.OnClick($event)))

如果當前緩存沒有,代表需要從$event傳遞進來,如果有緩存,直接找到緩存

支持手寫內聯函數

內聯函數也可以緩存進來,當然vue3這邊有做分析,至於如何分析,暫時不知道,尤雨溪有講,如果是在jsx裏面這樣寫,學過jsx之後,去和react做對比

  <div>
  <span :id='helloId' @click='()=>foo()'>
    {{msg}}
  </span> 
  </div>
    _createVNode("div", null, [
      _createVNode("span", {
        id: _ctx.helloId,
        onClick: _cache[1] || (_cache[1] = ()=>_ctx.foo())
      }, _toDisplayString(_ctx.msg), 9 /* TEXT, PROPS */, ["id"])
    ]),

Server Side Rendering

創建靜態的標籤直接使用字符串式,push進buffer流內,而不用一個一個去createElement

<div>Hello World!</div>
<div>Hello World!</div>
<div>Hello World!</div>
<span>{{msg}}</span>
<div>Hello World!</div>
<div>Hello World!</div>
import { ssrInterpolate as _ssrInterpolate } from "@vue/server-renderer"

export function ssrRender(_ctx, _push, _parent) {
  _push(`<!--[--><div>Hello World!</div><div>Hello World!</div><div>Hello World!</div><span>${_ssrInterpolate(_ctx.msg)}</span><div>Hello World!</div><div>Hello World!</div><!--]-->`)
}

而當你的靜態節點嵌套得特別深入,也會創建出一個staticNode去優化

Tree-shaking

  • Most Optional features(e.g v-model,<transition>) are now tree-shakable

  • Bare-bone Hello World size:13.5kb;

    • 11.75kb will only Composition API support;

  • All runtime features included:22.5kb;

    • More features but still lighter than Vue2 (開關去掉對2.0的支持)

treeshaking是通過編譯器去實現的,

Composition

尤雨溪並未講解,如有需求,可去https://composition-api.vuejs.org/網站查看,尤雨溪提及API Reference 中 Reactivity APIs的6個API纔是核心API

Fragment

對於模板用戶來說,肯定是無感知的。

模板只有一個根節點,在vue3裏面無需擁有根節點,可以多行文字,多個節點,而vue3會自動變成一個碎片。而如果用戶使用渲染函數,也可以直接在渲染函數中返回一個數組,自動變爲碎片

  • No Longer limited to a single root node in templates

  • Manual render functions can simply return Arrays

  • Just works

Teleport

接受一個disbaled參數,將本來應該傳送出去的東西駁斥回來,放在原來的渲染函數裏面,disalbed 用於響應式的設計,比如寬的屏幕展示出來,窄的屏幕拉回來。

多個Teleport 可以添加內容到同一個Compare裏面

  • Previously known as <Portal> React.Portal

  • More details to be shared by @Linusborg

Suspense

suspense 如何用在異步的請求裏面。可感知的性能提升是很低的,不作調度的情況下,也能做suspense

它可以在嵌套的組件樹渲染到屏幕上之前,可以在內存裏面進行渲染,可以檢測整顆樹裏面的異步依賴,只有當將整顆樹的異步依賴都渲染完成之後,也就是resolve之後,纔會將組件樹渲染到屏幕上去。

之前vue的做法並不是這樣,vue的組件嵌套是不會在乎你是否渲染完畢

vue3可以將async setup作爲異步原語,本身就是這樣來做,只要組件內部有一個async的setup函數就會認爲該組件是異步組件,也可以不跟suspense綁定

suspense主要是管理一些異步組件的加載也可以

  • Wait on nested async dependecies in a nested tree

  • Works with async setup()

  • Works with Async Components

Better Typescript support

  • Codebase written in TS w/auto-generated type defintions

  • API is the same in JS and TS

    • In fact ,code will also be largely the same

  • TSX support

  • Class components is still supported(vue-class-component@next) is currentty in alpha

針對vscode有插件

Custom Renderer API

vite

地址:github.com/vuejs/vite

一個簡易的http服務器,無需webpack編譯打包,根據請求的Vue文件,直接發回渲染,且支持熱更新(非常快)

之後就講了一些插件的作者和他們聯動更新,2.x如何兼容3.0 ,問題不大

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章