Blake Newman

Frontend Engineer @ Attest
Vue.js Core Team Member

Twitter: @blakenewman

Github: @blake-newman

Agenda:

Background of Vue.js

 

Inbuilt features of Vue.js

 

Reactivity Systems

 

Templates, are they bad?

 

The future of Vue's internals

So, Vue.

Where did vue come from?

DOB: ~ July 2013

Birthname: Seed

Father: Evan You 

@youyuxi

> 25 team members

> 12 languages

~ 65 repos/plugins

> 350 backers

> $18,000 monthly

Plus much more from alternative avenues

Financially viable OSS

> 163k  in organisation

http://git-awards.com/users

3rd most starred organisation

http://git-awards.com/users

6th most starred repository

Vue.js (core)

https://github.com/search?q=stars%3A%3E1&s=stars&type=Repositories

The
JavaScript Framework

Progressive

Declaritive Rendering

Component

System

Core

Routing

vue-router

State management

vuex

Build system

vue-loader

vue-cli

SSR / Native / Extensions

Ecosystem

Like JQuery?




  

(ish)


    <body>
      



    
     







    </body>


    <body>
      <div id="app">

      </div>










    </body>

    <body>
      <div id="app">

      </div>

      <script src="https://unpkg.com/vue"></script>
      <script>
        new Vue({




        });
      </script>
    </body>

    <body>
      <div id="app">

      </div>
    
      <script src="https://unpkg.com/vue"></script>
      <script>
        new Vue({
          el: '#app',
          data: {
            message: 'Hello Vue!'
          }
        });
      </script>
    </body>


    <body>
      <div id="app">

      </div>

      <script src="https://unpkg.com/vue"></script>








    </body>

    <body>
      <div id="app">

      </div>
    
      <script src="https://unpkg.com/vue"></script>
      <script>
        new Vue({
          el: '#app'



        });
      </script>
    </body>

    <body>
      <div id="app">
        {{ message }}
      </div>
    
      <script src="https://unpkg.com/vue"></script>
      <script>
        new Vue({
          el: '#app',
          data: {
            message: 'Hello Vue!'
          }
        });
      </script>
    </body>

Reactivity

Single File Components

Asynchronous Components

Dynamic Components

Hot Reloading

vue-router

Vuex

Virtual DOM

SSR

Devtools

Ava.js

Jest

Nuxt.js

Streaming

Pre-processors

JSX

Caching

Render Functions

Weex

Scoped CSS

CSS Modules

Beautiful Documenation

Transition Effects

Template Engine

Slots

Scoped Slots

Functional Components

TypeScript

Critical CSS

Provide & Inject

PWA

Single File Component

   
   
    <template>
      <p class="red">
        {{ message }}
      </p>
    </template>
   
    <template>
      <p class="red">
        {{ message }}
      </p>
    </template>
    
    <script>
      export default {
        data() {
          return {
            message: 'Hello world!'
          };
        }
      };
    </script>
   
    <template>
      <p class="red">
        {{ message }}
      </p>
    </template>
    
    <script>
      export default {
        data() {
          return {
            message: 'Hello world!'
          };
        }
      };
    </script>

    <style>
      .red {
        colour: red;
      }
    </style>

Pre-Processing

   
    <template lang="pug">
      p.red {{ message }}
    </template>
    
    <script lang="ts">
      import Vue from 'vue'
      import Component from 'vue-class-component'

      @Component
      export default class MyComponent extends Vue {
         message: string = 'Hello world!'
      }
    </script>

    <style lang="styl">
      .red
        colour red
    </style>

Scoped CSS

   
    <template>
      <p class="red"></p>
    </template>
    
    <style>
      .red {
        colour: red;
      }
    </style>
    
    <p class="red" data-v-f3f3eg9></p>

    <style>
      .red[data-v-f3f3eg9] {
        color: red;
      }
    </style>
   
    <template>
      <p class="red"></p>
    </template>
    
    <style scoped>
      .red {
        colour: red;
      }
    </style>

CSS Modules

   
    <template>
      <p :class="$style.red"></p>
    </template>
    
    <style>
      .red {
        colour: red;
      }
    </style>
    
    <div class="_1VyoJ-uZOjlOxP7jWUy19_0"></div>

    <style>
      ._1VyoJ-uZOjlOxP7jWUy19_0 {
        color: red;
      }
    </style>
   
    <template>
      <p :class="$style.red"></p>
    </template>
    
    <style module>
      .red {
        colour: red;
      }
    </style>

HMR (Hot Module Replacement)

Compiler

HMR Server

Bundle Server

Compile

Change

code

HMR runtime

bundle

View

HMR (Hot Module Replacement)

Reactivity

   
    class Child {
      props = ['message', 'enabled'],
    
      render() {
        <div>{
          this.enabled ? this.message : 'I am disabled'
        }</div>
      }
    }
    
    class Parent {
      message = 'Hello world!'
      enabled = false
    
      render() {
        return (
          <div>
            <Child message={this.message} enabled={!!this.message} />
            <Child message={this.message} enabled={this.enabled} />
          </div>
        )
      }
    }
    
    
    const vm = new Parent()
    
    vm.message = ''

Pull Reactivity system

Pull

Explicit pull signal from developer

 

Manual optimisation hints from developer

 

Simplified with immutable data

   
    class Child {
      props = ['message', 'enabled'],
    
      render() {
        <div>{
          this.enabled ? this.message : 'I am disabled'
        }</div>
      }
    }
    
    class Parent {
      message = 'Hello world!'
      enabled = false
    
      render() {
        return (
          <div>
            <Child message={this.message} enabled={!!this.message} />
            <Child message={this.message} enabled={this.enabled} />
          </div>
        )
      }
    }
    
    
    const vm = new Parent()
    
    vm.message = ''

Push Reactivity system

Push

Memory overhead, proportional to dataset size

 

Asynchronous and batches updates

 

Improved by skipping observation of immutable data

 

Improved by reducing computation granularity

   
    class Child {
      props = ['message', 'enabled'],
    
      render() {
        <div>{
          this.enabled ? this.message : 'I am disabled'
        }</div>
      }
    }
    
    class Parent {
      message = 'Hello world!'
      enabled = false
    
      render() {
        return (
          <div>
            <Child message={this.message} enabled={!!this.message} />
            <Child message={this.message} enabled={this.enabled} />
          </div>
        )
      }
    }
    
    
    const vm = new Parent()
    
    vm.message = ''

Pull

Explicit pull signal from developer

 

Manual optimisation hints from developer

 

Simplified with immutable data

Push

Memory overhead, proportional to dataset size

 

Asynchronous and batches updates

 

Improved by skipping observation of immutable data

 

Improved by reducing computation granularity

Frameworks

Silver bullet

 

Angular 5 - onPush with Observables
 

React + MobX


Vue 2 + Immutable data

Templates

 

Render Functions (JSX)

   
    <template>
      <p>{{ message }}</p>
    </template>
    
    function render() {
      var _vm = this
      var _h = _vm.$createElement
      var _c = _vm._self._c || _h
      return _c('p', [
       _vm._v(_vm._s(_vm.message))
      ])
    }

Representation


    function render() {
      return (
        <div>{ this.message }</div>
      )
    }

    {
      class: {
        foo: true,
        bar: false
      },
    
      style: {
        color: 'red',
        fontSize: '14px'
      },
    
      attrs: {
        id: 'foo'
      },
    
      props: {
        myProp: 'bar'
      },
    
      on: {
        click: this.clickHandler
      },
      
      // ...
    }

Virtual DOM Node

    
    function render() {
      return React.createElement(
        "div",
        null,
        this.items.map(function (item) {
          return React.createElement("p", null, item);
        }),
        React.createElement("p", null, this.message)
      )
    }

Normalisation


   function render() {
     return (
       <div>
         { this.items.map(item => <p>{ item }</p>) }
         <p>{ this.message }</p>
       </div>
     )
   }

    [node, [node, ...], node]
   
    <template>
      <div>
        <p v-for="item in items">{{ item }}</p>
        <p>{{ message }}</p>
      </div>
    </template>
    
    function render() {
      var _vm = this
      var _h = _vm.$createElement
      var _c = _vm._self._c || _h
      return _c('div', [_vm._l((_vm.items), function(item) {
        return _c('p', [_vm._v(_vm._s(item))])
      }), _c('p', [_vm._v(_vm._s(_vm.message))])], 2)
    }
   
    <template>
      <div>
        <span>Static content</span>
        <span>More static content</span>
      </div>
    </template>

Static nodes


    function render() {
      return (
        <div>
          <h2>Static content</h2>
          <p>More static content</p>
        </div>
      )
    }

    function render() {
      var _vm = this
      var _h = _vm.$createElement
      var _c = _vm._self._c || _h
      return _vm._m(0)
    }

    function render() {
      return React.createElement(
        "div",
        null,
        React.createElement("span", null, "Static content"),
        React.createElement("span", null, "More static content")
      )
    }

Further Optimisations

Render (JSX)

Templates

Declarative with JSX

Presentational

Logical

HTML + small DSL

Child normalization

Declarative

Power of JavaScript

No DSL?

Static node hoisting

Progressive code updates

Closer to compiler

The future of Vue internals

Vue.js 2.6

Various updates and improvements

  - error handling

  - functional components

  - SSR

Possible support for Native Map & Set types to be supported for reactivity
 

Vue.js 2.x-next

Will be targeting evergreen browsers only in order to leverage native ES2015 features
 

Reactivity system will be rewritten with Proxies with various improvements
 

No major breaking changes; will be maintained in parallel to 2.x with feature parity

Proxies?

The Proxy object is used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc).

Vue.js currently has a few caveat when tracking changes

  - Array length change detection
  - New property detection
  - Delete property detection

 

Proxies allow us to detect all these type of mutations


 

Internal core moving to Typescript

Planned to move the internals of Vue.js to TypeScript:
 

- Heavily risen in popularity
- Improved code readability
- Stricter Typing
- Ensures code is as monophonic as possible
- Helps us produce better Typescript support as standard

 

Twitter: @blakenewman

Github: @blake-newman

 

Feedback: goo.gl/1aDnfY
Slides: slides.com/blakenewman

Q&A

Made with Slides.com