One of the most striking events in the world of the Frontend this year was the publication of the Vue next repository – part of the functionality of the third version of VueJS. This article provides an overview of the new features of VueJS. At the time of publication of the article, the repository was in Pre-Alpha status.

Background

In February 2018, Evan You, the creator of Vue.js, shared his plans for version 3 of the popular framework:

  • Break functionality into packages to isolate scope
  • TypeScript appears in the codebase
  • Vue 3 will be backward compatible with version 2 (i.e. it won’t break the old code)
  • Observers in version 3.0 are based on Proxy, which will increase rendering speed and remove a number of restrictions imposed by Object.defineProperty
  • You will be able to debug using the new renderTracked and renderTriggered hooks.
  • Thanks to the introduction of tree shaking (excluding unused directives from the build), the size of the framework will be less than 10kb in compressed form
  • Slot Optimization
  • Performance in vue 3 will improve in 100%

Features such as built-in components and directive runtime helpers (v-model) are now imported on-demand and tree-shakable

Evan you

The compiler will track the existence of directives and include them in the build at the compilation stage.

In the process of working on Vue 3, Evan refused to rewrite components to classes and instead implemented a functional API.

Since the new version will use proxies that are not supported in IE, Evan plans to create a separate build for IE11. In total, 4 phases are promised:

  • Alpha Phase – stage of finalization of the compiler and ssr-rendering
  • Beta Phase – stage of finalization of the main libraries (Vue Router, Vuex, Vue CLI, Vue DevTools)
  • RC Phase – Prerelease Stage Including Vue 2.0
  • IE11 build
  • Final release

Evan has planned a final release for 2019, but the project is still in pre-alpha stage.

Vue 3 will be faster

Thanks to a number of innovations, Vue 3 will become 2 times faster than the previous version.

Proxy-based Observation and Reactivity

One of the major innovations was the change in the mechanism for monitoring objects from getters and setters of Object.defineProperty to Proxy. Now Vue can track the removal and addition of properties of reactive objects without using Vue.set and Vue.delete. The innovation increased the speed of rendering and scripting and reduced memory consumption by 2 times!

Performance comparison of Vue 2 (left) and Vue 3 (pre-alpha stage, right)

Thanks to proxies, reactivity will not be lost when changing object manipulations that are not tracked in Vue 2. Now Vue will not recursively traverse the properties of an object to calculate the changes.

What is made of the promises:

  • Descendants and parents are redrawn independently
  • Vue 3 size decreased from 20kb to 10kb in compressed form
  • TypeScript Added

Other optimizations:

  • Vue 3 will remember static content and patch only dynamic data
  • Static props go up the scope
  • For ease of development, Vue 3 code is devided into modular packages.
  • The runtime-core package is made cross-platform
  • Instead of classes, Evan added a setup function and hooks that make the code clean, organized, and reusable *
  • Time Slicing *. JS code execution is cut into pieces without blocking user interaction with the application
  • Asterisks indicate the experimental API.

Update: Later, Evan decided to abandon time sliсing.

Inspired by the HOC of React Evan implemented setup functions with reusable logic and custom hooks. Unlike mixins, lifecycle hooks do not overwrite each other.

Enhanced VDom Patch

Static Content Joystick

Static content is moved outside the VDom patch when compiling the template. To this, the Vue team was inspired by Svelte:

<div> Hello, {{name}} </div>

Here, the changed object and context are passed. If changed contains a reactive variable, then it is updated in context.

p (changed, ctx) {

    if (changed.name) {

        set_data (t1, ctx.name);

    }

}

In the previous implementation, the Vue compiler went through all the nodes, including static ones:

function render () {

    const children = [];

    for (let i = 0; i <5; i ++) {

        children.push (h (‘p’, {

            class: ‘text’

        }, i === 2? this.message: ‘Lorem upsum’))

    }

    return h (‘div’, {id: ‘content’}, children)

}

New template compilation strategy

In the new version, the template is divided into blocks:

  • The template is divided into blocks
  • The structure of the nodes inside each block is completely static.
  • To track dynamic values ​​in a block, only 1 flat array is required, where they are placed

With the new strategy, performance directly depends on the amount of dynamic content instead of the size of the template.

Vue 3 will be better adapted to large projects

Large projects face the following problems when using Vue:

  • Not perfect TypeScript support
  • Massive, hard-to-support components
  • Lack of a simple pattern to reuse code

Initially, it was planned to add classes to support TS. But the Vue team ran into problems:

  • Mixing props and other attributes with this is problematic
  • Decorators for ES6 classes in TC39 are unstable

Evan’s team requested help from TC39 experts and found out that a similar implementation could conflict with plugins that mix various props and attributes into the Vue context.

Potentially, these problems could be solved by decorators, but they are under development.

Composition API

The Vue team was inspired by the React hooks and decided to create a similar API. It is optional and is under development and discussion, so some names may change.

The main concept of this change is to organize the component code more logically, breaking it into semantic blocks.

An example of using Vue 3. A component is divided into logical functions, inside of which you can use reactivity and life cycle hooks.

Import the new hooks from the composition API:

import {reactive, computed, onMounted} from ‘@ vue / composition-api’;

export default {

  setup () {

    const {state} = countAnimal (“rabbit”)

    const {getType, anotherState} = anotherCount ()

    return {

      state

      getType,

      anotherState

    }

  }

}

The countAnimal function has reactive properties count, animal, and the increment method. With an odd counter, the name of the animal changes. The counter starts when the component is mounted.

function countAnimal (name) {

  const state = reactive ({

    count: 0,

    animal: computed (() => state.count% 2? name: ‘bear’)

  })

  function increment () {

    setTimeout (() => {

      state.count ++;

      increment ()

    }, 1000)

  }

  onMounted (() => {

    increment ()

  })

  return {

    state

  }

}

We create another function anotherCount, which also contains the increment and state method with the counter and the name of the animal. The getType method passes the name of the animal from the template.

function anotherCount () {

  const anotherState = reactive ({

    count: 0,

    animal: ‘fox’

  })

  function getType (name) {

    return name == ‘bear’? ‘slow’: ‘fast’

  }

  function increment () {

    setTimeout (() => {

      anotherState.count + = 10;

      increment ()

    }, 1000)

  }

  onMounted (() => {

    increment ()

  })

  return {

    getType,

    anotherState

  }

}

The template displays 2 counters and 2 animal names. The type of run varies depending on the name of the animal.

<template>

  <div>

    <div> Count {{state.animal}}: {{state.count}} </div>

    <div> {{state.animal}} runs {{getType (state.animal)}} </div>

    <div> Another:

    Count {{anotherState.animal}}: {{anotherState.count}} </div>

  </div>

</template>

New hooks are used inside setup without breaking the old API. Note that onMounted refers to a single component lifecycle hook.

This api has several advantages:

  • Lifecycle hooks don’t disturb each other
  • Clear source of properties
  • No additional component instances are created

Conclusion

The most important changes in Vue 3 are listed above. Most of the improvements will be hidden under the hood of the code generated by the compiler.

Major improvements:

  • The generated code is optimal for the JS compiler
  • Generated bundle is more lightweight
  • Parent / child components are redrawing thanks to improved patching algorithm

Vue managed to establish itself as one of the fastest and most optimal frameworks. The new version will become even faster and easier. Vue 3 is great for today’s mobile and performance-oriented web.