Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Vapor Revolution

kazupon
November 22, 2024

Vapor Revolution

kazupon

November 22, 2024
Tweet

More Decks by kazupon

Other Decks in Programming

Transcript

  1. 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
  2. • 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?
  3. 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
  4. • 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>
  5. 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
  6. 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
  7. 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>
  8. 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
  9. 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
  10. • IR (Intermediate Representation) Architecture Compiler Optimized Vue AST generate

    transform JS Code Vue AST Tamplate parse Virutal DOM Mode (Currently)
  11. • 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
  12. Runtime • Virtual DOM is no longer necessary ! •

    LESS codes ! SMALL size! runtime-vapor is over 50% smaller than runtime-dom!
  13. 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
  14. Interoperability • Mixin Vapor Mode and vDOM Mode components in

    App App.vue vDOM vDOM vDOM Vapor Vapor Vapor
  15. @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!
  16. 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
  17. • 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 }
  18. 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, }
  19. 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>
  20. 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
  21. inclusion-vapor • Open-source project • Component interoperability based on Vapor

    • Repository: https://github.com/kazupon/inclusion-vapor
  22. Fusion of components coming? • Just `import` only! Vue Vapor

    Vue Vapor React Vapor React Vapor Svelte Vapor Svelte Vapor Vue Vapor
  23. Vapor future plan • Support platform-agnostic • currently, browser only

    • native mobile app • More improvements and generalization? • Release with Vue 3.6 as experimental
  24. 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
  25. 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