Share
Embed
Transcript
52 slides
-
Vapor Revolution Unleashing Vue evolution and Potential with Vapor Mode
JSConf JP 2024 2024/11/23 @kazupon -
PLAID, inc. Vue.js Core Team Nuxt Ecosystem Team Vue I18n
& Intlify author Vue Fes Japan Organizer Vue.js Japan User Group Organizer @kazu_pon kazupon kazupon -
• New alternative compilation strategy of Vue.js • Inspired from
SolidJS • Goal: Maximizing performance • Vapor mean has … • Just like steam • lighter, faster, and more flexible • Opt-in What’s Vapor Mode? -
Again, What’s Vue.js? • Progressive framework for UI Building •
SFC: Single File Components • Features: • Composition API • Reactivity • SSR, and … more! • To work on the browser, need compile SFCs -
Key tech elements of Vue • Compiler • Reactivity System
• Virtual DOM -
Compiler • Compile script block and template block to JS
Compile to JavaScript -
• Fine-grained reactivity based on dependency tracking Reactivity System Reactivity
System Dependencies full last fi rst -
• Rendering with Diff & Patch & Reactive lifecycle Virtual
DOM https://vuejs.org/guide/extras/rendering-mechanism.html#render-pipeline Tamplate compiled into Render Function Component Reactivity State Virtual DOM Tree Actual DOM returns diff / patch trigger re-render track dependencies <template> <div id=“hello"> ... </div> </template> function render() { return h(‘div', { id: "hello" }, [/* more childs */] ) } const vnode = { type: 'div', props: { id: 'hello' }, children: [ /* more vnodes */ ] } <html> <body> <div id=“app”> <div id=“hello"> ... </div> </div> </body> </html> -
Virtual DOM Tamplate compiled into Render Function Component Reactivity State
Virtual DOM Tree Actual DOM returns diff / patch track dependencies <template> <div id=“hello"> ... </div> </template> function render() { return h(‘div', { id: "hello" }, [/* more childs */] ) } const vnode = { type: 'div', props: { id: 'hello' }, children: [ /* more vnodes */ ] } <html> <body> <div id=“app”> <div id=“hello"> ... </div> </div> </body> </html> • First rendering -
Virtual DOM Tamplate compiled into Render Function Component Reactivity State
Virtual DOM Tree Actual DOM returns diff / patch trigger re-render <template> <div id=“hello"> ... </div> </template> function render() { return h(‘div', { id: "hello" }, [/* more childs */] ) } const vnode = { type: 'div', props: { id: 'hello' }, children: [ /* more vnodes */ ] } <html> <body> <div id=“app”> <div id=“hello"> ... </div> </div> </body> </html> • Re-rending -
Rendering mechanism • Drop Virtual DOM, use Native DOM API
Tamplate compiled into Render Function Component Reactivity State Framgments (DOM Nodes) Actual DOM returns mount update track dependencies <template> <buttton @click=“count++"> {{ count }} </buttton> </template> <html> <body> <div id=“app”> <buttton>0</buttton> </div> </body> </html> const t0 = template("<button></button>") delegateEvents("click") function render(ctx) { const n0 = t0() delegate(n0, “click", () => $event => (ctx.count++)) renderEffect( () => setText(n0, ctx.count)) return n0 } <buttton>0</buttton> Reactive Effect trigger effect register <html> <body> <div id=“app”> <buttton>1</buttton> </div> </body> </html> -
Rendering mechanism Tamplate compiled into Render Function Component Reactivity State
Framgments (DOM Nodes) Actual DOM returns mount update track dependencies <template> <buttton @click=“count++"> {{ count }} </buttton> </template> <html> <body> <div id=“app”> <buttton>0</buttton> </div> </body> </html> const t0 = template("<button></button>") delegateEvents("click") function render(ctx) { const n0 = t0() delegate(n0, “click", () => $event => (ctx.count++)) renderEffect( () => setText(n0, ctx.count)) return n0 } <buttton>0</buttton> Reactive Effect trigger effect register <html> <body> <div id=“app”> <buttton>1</buttton> </div> </body> </html> • First rendering -
Rendering mechanism Tamplate compiled into Render Function Component Reactivity State
Framgments (DOM Nodes) Actual DOM returns mount update track dependencies <template> <buttton @click=“count++"> {{ count }} </buttton> </template> <html> <body> <div id=“app”> <buttton>0</buttton> </div> </body> </html> const t0 = template("<button></button>") delegateEvents("click") function render(ctx) { const n0 = t0() delegate(n0, “click", () => $event => (ctx.count++)) renderEffect( () => setText(n0, ctx.count)) return n0 } <buttton>0</buttton> Reactive Effect trigger effect register <html> <body> <div id=“app”> <buttton>1</buttton> </div> </body> </html> • Re-rendering -
• IR (Intermediate Representation) Architecture Compiler Optimized Vue AST generate
transform JS Code Vue AST Tamplate parse Virutal DOM Mode (Currently) -
• IR (Intermediate Representation) Architecture Compiler Vapor IR generate transform
JS Code Vue AST Tamplate parse Optimized Vue AST generate transform JS Code Vue AST Tamplate parse vDOM Mode (Currently) Vapor Mode -
Runtime • Virtual DOM is no longer necessary ! •
LESS codes ! SMALL size! runtime-vapor is over 50% smaller than runtime-dom! -
Bene fi ts with Vapor Mode • Performance • Compatibility
• Interoperability -
Compatibility • Vapor Mode is a subset of vDOM Mode
• vDOM Mode • Composition API • Options API, and etc … • Vapor Mode • Composition API • <script setup> Vapor Mode vDOM Mode -
Interoperability • Mixin Vapor Mode and vDOM Mode components in
App App.vue vDOM vDOM vDOM Vapor Vapor Vapor -
@vue/compiler-vapor [compile] Compilation Architecture [parse] [transform] [generate] @vue/compiler-sfc [compileTemplate] @vitejs/plugin-vue
[transform] Figure inspired from Kevin Deng & Rizume Ayaka, Thanks! SFC -
@vue/compiler-vapor [compile] Compilation Architecture [parse] Vue Template → Vue AST
[transform] Vue AST → Vapor IR [generate] Vapor IR → JS Code @vue/compiler-sfc [compileTemplate] @vitejs/plugin-vue [transform] SFC Figure inspired from Kevin Deng & Rizume Ayaka, Thanks! -
What’s IR? • IR (Intermediate Representation) • Data strcture or
code internally used by compiler or virtual machine to represent source code • Usages • Cross Platform • Optimization • Translation Compile / Transform IR Source Code Generate Target Executable Code / Binary -
• Representation of template structure and template operations, Tree nodes
like AST Vapor IR Block Root If SetText CreateText Node InsertNode Create Component Block Block CreateText Node Prepend Node export interface IfIRNode extends BaseIRNode { type: IRNodeTypes.IF id: number condition: SimpleExpressionNode positive: BlockIRNode negative?: BlockIRNode | IfIRNode once?: boolean } -
Vapor IR Node Types • 20 Vapor IR node types
• Block node has operations • Block node is able to register 18 Vapor IR types as operations • Operations of render function • e.g. DOM manupluration, Set Props / Attrs, Event bindings, and … • If & For node has block node export enum IRNodeTypes { ROOT, BLOCK, SET_PROP, SET_DYNAMIC_PROPS, SET_TEXT, SET_EVENT, SET_DYNAMIC_EVENTS, SET_HTML, SET_TEMPLATE_REF, SET_MODEL_VALUE, SET_INHERIT_ATTRS, INSERT_NODE, PREPEND_NODE, CREATE_TEXT_NODE, CREATE_COMPONENT_NODE, SLOT_OUTLET_NODE, WITH_DIRECTIVE, DECLARE_OLD_REF, IF, FOR, } -
e.g. Vapor IR Tree • Counter component, which has condition
Block Root If SetEvent Block InsertNode <div> <button @click="count++">count: {{ count }}</button> <p v-if="count > 10">Count over 10</p> </div> -
Is it possible to transform it to Vapor IR using
non-Vue template? -
Support Vue JSX! @vue/compiler-vapor [compile] [parse] Vue Template → Vue
AST [transform] Vue AST → Vapor IR [generate] Vapor IR → JS Code @vue/compiler-sfc [compileTemplate] @vitejs/plugin-vue [transform] SFC unplugin-vue-jsx-vapor [transform] compiler [compile] [parse] Vue JSX → JSX AST [transform] JSX AST → Vapor IR Vue JSX -
inclusion-vapor • Open-source project • Component interoperability based on Vapor
• Repository: https://github.com/kazupon/inclusion-vapor -
Fusion of components coming? • Just `import` only! Vue Vapor
Vue Vapor React Vapor React Vapor Svelte Vapor Svelte Vapor Vue Vapor -
Vapor future plan • Support platform-agnostic • currently, browser only
• native mobile app • More improvements and generalization? • Release with Vue 3.6 as experimental -
Recap • Vapor Mode • Vapor is an alternative compilation
strategy & new begenning for Vue • Potential with Vapor Mode • Vapor is support IR architecture • Vapor will have better Vue JSX support • If we follow the Vapor conventions & I/F, we can also support non-Vue templates -
Vapor Team, Thanks! Evan You Kevin Deng Rizumu Ayaka Ubugeeei
Doctor Wu zhiyuanzmj -
Join us! • Vapor Project : https://github.com/vuejs/vue-vapor • Lean about
Vapor : https://github.com/ubugeeei/reading-vuejs-core-vapor • Component interoperability OSS Project : inclusion-vapor 🫶 https://github.com/kazupon/inclusion-vapor