Slide 1

Slide 1 text

Next Vue.js 2.0 Gotanda.js #4 2016-06-03 @kazupon

Slide 2

Slide 2 text

Who? • GitHub: kazupon • Twitter: kazu_pon • Company: CUUSOO SYSTEM • Position: CTO (Full-Stack)

Slide 3

Slide 3 text

OSS Contributions • Vue.js core team member • Vue.js official site for Japanese • Maintenance and Translate Vue.js official repositories

Slide 4

Slide 4 text

Introduction • 2016 Apl 27 Announce Vue.js 2.0 https://medium.com/the-vue-point/announcing-vue-js-2-0-8af1bde7ab9#.7acpkrkhh

Slide 5

Slide 5 text

To Speak Today • Today, I speak about the Vue.js 2.0

Slide 6

Slide 6 text

2.0 Architecture

Slide 7

Slide 7 text

Adopt virtual-dom • snabbdom based
 https://github.com/paldepind/snabbdom • Customize for Vue.js
 (component, directive, hydration)

Slide 8

Slide 8 text

1.x rendering flow

{{a.b}}

{{a.b}}

compile template document fragment

Slide 9

Slide 9 text

1.x rendering flow

{{a.b}}

{{a.b}}

{ a: { b: "hello" } } watcher a.b compile observe getter setter dep/observer a dep/observer b collect dependencies data template document fragment

Slide 10

Slide 10 text

1.x rendering flow

{{a.b}}

{{a.b}}

{ a: { b: "hello" } } watcher a.b compile observe render getter setter dep/observer a dep/observer b …

hello

collect dependencies append to target element data template document fragment target element

Slide 11

Slide 11 text

1.x rendering flow vm.a.b = 'world' { a: { b: "world" } } update dep/observer a getter setter dep/observer a dep/observer b

Slide 12

Slide 12 text

1.x rendering flow vm.a.b = 'world' { a: { b: "world" } } update notify dep/observer a watcher a.b getter setter dep/observer a dep/observer b batcher notify euqueue

Slide 13

Slide 13 text

1.x rendering flow vm.a.b = 'world' { a: { b: "world" } } update notify re- render dep/observer a …

world

watcher a.b getter setter dep/observer a dep/observer b batcher directive v-text="a.b" notify euqueue run callback update notify

Slide 14

Slide 14 text

2.0 rendering flow

{{a.b}}

{render:function(){with(this){ return _h(_e('p'),[(_s(a.b))])} }}, staticRenderFns:[] } compile template render functions AST {type:1,tag:"p",attrsList:[], attrsMap:{},children:[{type: 2,expression:"_s(a.b)" }],plain:true} parse optimize & to function

Slide 15

Slide 15 text

2.0 rendering flow

{{a.b}}

{render:function(){with(this){ return _h(_e('p'),[(_s(a.b))])} }}, staticRenderFns:[] } compile observe template render functions AST {type:1,tag:"p",attrsList:[], attrsMap:{},children:[{type: 2,expression:"_s(a.b)" }],plain:true} parse optimize & to function { a: { b: "hello" } } watcher ()=>{vm._update( vm._render())} getter setter dep/observer a dep/observer b collect dependencies data

Slide 16

Slide 16 text

2.0 rendering flow

{{a.b}}

{render:function(){with(this){ return _h(_e('p'),[(_s(a.b))])} }}, staticRenderFns:[] } compile observe render template render functions AST {type:1,tag:"p",attrsList:[], attrsMap:{},children:[{type: 2,expression:"_s(a.b)" }],plain:true} parse optimize & to function { a: { b: "hello" } } watcher ()=>{vm._update( vm._render())} getter setter dep/observer a dep/observer b collect dependencies data patch …

hello

target element call exec vnode render _vnode = vnode text p

Slide 17

Slide 17 text

2.0 rendering flow update vm.a.b = 'world' { a: { b: "world" } } getter setter dep/observer a dep/observer b

Slide 18

Slide 18 text

2.0 rendering flow update patch watcher ()=>{vm._update( vm._render())} patch exec vnode vm.a.b = 'world' { a: { b: "world" } } getter setter dep/observer a dep/observer b notify render functions text p text p _vnode {render:function(){with(this){ return _h(_e('p'),[(_s(a.b))])} }}, staticRenderFns:[] } scheduler euqueue run callback

Slide 19

Slide 19 text

2.0 rendering flow update patch re- render …

world

target element set $el _vnode = vnode watcher ()=>{vm._update( vm._render())} patch exec vnode vm.a.b = 'world' { a: { b: "world" } } getter setter dep/observer a dep/observer b notify render functions text p text p _vnode {render:function(){with(this){ return _h(_e('p'),[(_s(a.b))])} }}, staticRenderFns:[] } scheduler euqueue run callback

Slide 20

Slide 20 text

rendering performance • Improves initial rendering speed and memory consumption by up to 2~4x in most scenarios • benchmark
 Try to run the below URL
 https://github.com/vuejs/vue/tree/next/benchmarks

Slide 21

Slide 21 text

Support Server-Side-Rendering

Slide 22

Slide 22 text

support SSR • Without third vendor library, be able to server-side rendering • In server-side, render by using the blow the APIs • renderToString • renderToStream

Slide 23

Slide 23 text

renderToString • Usage: with use compiler import Vue from '../../dist/vue.common.js' import { compileToFunctions } from '../../dist/compiler.js' import createRenderer from '../../dist/server-renderer.js' const { renderToString } = createRenderer() // define template compilation let compileTemplate = (options) => { const res = compileToFunctions(options.template, { preserveWhitespace: false }) Object.assign(options, res) console.assert(typeof options.render === 'function') delete options.template return options } // render console.log(renderToString(new Vue(compileTemplate({ template: '
{{ foo }} side {{ bar }}
' data: { foo: 'server', bar: 'rendering' } })))) // output: //
server side rendering

Slide 24

Slide 24 text

renderToString • Usage: with use ‘render’ option import Vue from '../../dist/vue.common.js' import createRenderer from '../../dist/server-renderer.js' const { renderToString } = createRenderer() // render console.log(renderToString(new Vue({ data: { foo: 'server', bar: 'rendering' }, render () { const h = this.$createElement return h('div', { attrs: { id: 'foo' } }, [`${this.foo} side ${this.bar}`]) } }))) // output: //
server side rendering

Slide 25

Slide 25 text

renderToString • component const child = Vue.extend(compileTemplate({ template: '
{{msg}} {{name}}
’, props: ['msg'], data () { return { name: 'bar' } } })) // render console.log(renderToString(new Vue(compileTemplate({ template: '', data: { msg: 'hello' }, components: { child } })))) // output: //
hello bar

Slide 26

Slide 26 text

renderToString • hooks const child = Vue.extend(compileTemplate({ template: '
{{msg}} {{name}}: {{count}}
’, props: [‘msg'], data () { return { name: ‘bar’, count: 0 } }, init () { this.count++ }, created () { this.count++ } })) // render console.log(renderToString(new Vue(compileTemplate({ template: '', data: { msg: 'hello' }, components: { child } })))) // output: //
hello bar: 2

Slide 27

Slide 27 text

renderToStream • renderToString issues • Sync rendering !! • Blocking the event loop !! • renderToStream support the async rendering • Improve the performance by using the Node.js Stream

Slide 28

Slide 28 text

renderToStream • Usage: basic // … imports
 const { renderToStream } = createRenderer() // import!! // define template compilation let compileTemplate = (options) => { // ... } // render stream const stream = renderToStream(new Vue(compileTemplate({ template: '
{{ foo }} side {{ bar }}
' data: { foo: 'server', bar: 'rendering' } })))) let res = '' stream.on('data', chunk => { res += chunk }) stream.on('end', () => { console.log(res) // output: //
server side rendering
})

Slide 29

Slide 29 text

renderToStream • Usage: Pipe const http from ‘http' // ... const server = http.createServer((req, res) => { // ...
 
 // render stream const stream = renderToStream(new Vue(compileTemplate({ template: '
{{ foo }} side {{ bar }}
' data: { foo: 'server', bar: 'rendering' } })))) 
 // pipe!! stream.pipe(res) }) server.listen(8000)

Slide 30

Slide 30 text

SSR benchmark • Try to run the below command
 
 $ npm run bench:ssr

Slide 31

Slide 31 text

hydration • When render at server-side, marke with ”server-rendered” to HTML • After that, In client-side, run the hydrate function at the patch • guard duplication rendering • skip the diffing, and DOM building

Slide 32

Slide 32 text

Rendering
 Optimization

Slide 33

Slide 33 text

It just works • No need the below from vue.js compiler to optimize the rendering • `shouldComponentUpdate` • Immutable data structures

Slide 34

Slide 34 text

Optimization • Static attributes and classes skip the diffing in the patch template virtual-dom (vnode) { tag: "div", data: { staticClass: "image-box" }, children: [{ tag: "h1", children: [...], ... }, { tag: "a", data: { attrs: { href: url }, staticAttrs: { target: "_blank" } }, children: [{ tag: "img", data: { attrs: { src: resource, alt: hint }, staticClass: "image" } }, ... }], ... }], ... }

{{title}}

Slide 35

Slide 35 text

• Static subtree skip the diffing in patch Optimization
header

{{a.b}}

footer
{ render: function(){with(this){ return _h(_e('div', {class:class1}), [_m(0), _h(_e('p'), [(_s(a.b))]), _m(1)]) }}, staticRenderFns: [function(){with(this){ // _m(0) return _h(_e('header'), [_t("logo")])} }, function(){with(this){ // _m(1) return _h(_e('footer', [_t("foo")])} }] } template render functions compile When first rendering completed, results of staticRenderFns is cached in Vue instance. in later, use the this cached in the patch header div p footer text text text

Slide 36

Slide 36 text

Control
 of rendering

Slide 37

Slide 37 text

render tag / render option • Provide the feature that control of rendering with JavaScript • Cannot get no satisfaction to vue.js compiler • Cannot get no satisfaction to template DSL syntax • However, need to understand about the virtual-dom

Slide 38

Slide 38 text

render tag • Example import Vue from 'vue' const vm = new Vue({ template: `
`, data: { message: 'hello world' }, methods: { onRender (args) { const h = this.$createElement return h('div', { class: 'message' }, [ h('p', {}, [args]) ]) } } }).$mount()

Slide 39

Slide 39 text

render option • Example import Vue from 'vue' const vm = new Vue({ data: { message: 'hello world' }, render () { const h = this.$createElement return h('div', { class: 'message' }, [ h('p', {}, [this.message]) ]) } }).$mount()

Slide 40

Slide 40 text

More leaner

Slide 41

Slide 41 text

Re-implementaion • Re-design from zero-base, and full-scrach • Split the below files where to dist • compiler (dist/compiler.js) • runtime (dist/vue-common.js) • compiler + runtime (dist/vue.js) • server-render (dist/server-renderer.js)

Slide 42

Slide 42 text

Remove the unneccessary codes • Build-in filters • Not used APIs and bad practice APIs • Unnecessary 1.x codes

Slide 43

Slide 43 text

Comparing dist files • 1.x
 25.79K (min+zip) • 2.0 • runtime only: 12.81K (min+zip) • runtime + compiler: 19.09K (min+zip)

Slide 44

Slide 44 text

Breaking changes

Slide 45

Slide 45 text

Breaking changes • Some deprecated APIs
 ($dispatch, $broadcast, … etc) • Custom directive API I/F • Filter System • Transition System
 
 … and others
 see more detail the below URL https://github.com/vuejs/vue/issues/2873

Slide 46

Slide 46 text

Development environments

Slide 47

Slide 47 text

Added type checking with Flow NEW!!

Slide 48

Slide 48 text

Roadmap

Slide 49

Slide 49 text

2.0 • Current: pre-alphe • Achieved test coverage 100% • Alpha or beta: soon? • Release • Documentation • Major plugin compatiblity
 (vue-router, vuex, vue-loader, vuerify, … etc)

Slide 50

Slide 50 text

1.x LTS (long-term support) • Security updates (9-months) • Critical bug fixes (6-months)

Slide 51

Slide 51 text

Conclusion

Slide 52

Slide 52 text

Conclusion • Adopt virtual-dom • The below has become possible • Improve rendering performance • SSR • Rendering optimization • Control of rendering • More learner

Slide 53

Slide 53 text

“Progressive Framework” adaptable to different complexity levels

Slide 54

Slide 54 text

vuejs-jp slack • Direct URL Access
 https://vuejs-jp-slackin.herokuapp.com • Vuejs official site for japanese
 http://jp.vuejs.org
 


Slide 55

Slide 55 text

Thanks!!