Plans for the next version of Vue.js
Last week at Vue.js London, I told you what would happen in the next major version of Vue. This post contains a detailed overview of the plan.
Why the new major version?
Vue 3.0 aims to use these new language features to make the Vue kernel smaller, faster and more powerful. Vue 3.0 is currently in the prototyping stage, and we have already implemented a runtime environment close to version 2.x. Many of the elements listed below are either already implemented or it is confirmed that this is possible. Items that have not yet been implemented or are still at the planning stage are marked with (*).
Top Level API Changes
TL; DR: Everything except the render function API and scoped slots syntax will either remain the same, or it may be compatible with version 2.x via the compatibility build.
Since this is a major version, some changes will take place. However, we are serious about backward compatibility, so we want to publish a list of these changes as soon as possible.
Here are the current planned public API changes:
- The syntax of the templates will remain 99% the same. There may be slight changes in the syntax of scoped slots, but other than that we do not plan to change anything for the templates.
- 3.0 will support class-based components initially, with the goal of providing an API that is nice to use in native ES2015, without requiring any means of transfiguration or stage-x functionality. Most of the current parameters will have a reasonable mapping in the class-based API. Stage-x functions, such as class fields and decorators, can still be used additionally. In addition, the API is designed with TypeScript. The 3.x codebase itself will be written in TypeScript and will provide improved TypeScript support. (However, the use of TypeScript in the application is still completely optional).
- Components based on objects 2.x will still be supported by an internal conversion of the object to the appropriate class.
- Mixin will still be supported. *
- The top-level API is likely to receive changes to avoid global intervention in the Vue prototype when installing plug-ins. Instead, the plugins will be applied and tied to the component tree. This will make it easier to check components that depend on certain plugins, and also allow you to mount multiple Vue applications on the same page with different plugins, but using the same Vue runtime environment. *
- Functional components can finally be simple functions — in any case, asynchronous components should now be explicitly created using an auxiliary function.
- The part that receives the most changes is the Virtual DOM used in the rendering functions. We are currently collecting feedback from the main authors of the libraries and will share more detailed information, since we are confident in the changes, but as long as you do not rely heavily on samopisny (not JSX) rendering functions in your application, it should be a fairly simple process.
Source code architecture
TL; DR: improved separate internal modules, TypeScript and code base to which it is easier to contribute.
We are rewriting Vue from scratch for a cleaner and more convenient architecture, in particular, trying to make work easier. We break some internal functions in separate packages to isolate the amount of complexity. For example, the observer module will become its own package, with its own public API and tests. Please note that this does not affect the framework level API: you do not have to manually import individual modules from multiple packages to use Vue. Instead, the last Vue package is built using these internal packages.
The codebase is also now written in TypeScript. Although this will make TypeScript knowledge a prerequisite for contributing to a new code base, we believe that type information and IDE support will actually make it easier for the maintainer to make a meaningful contribution.
Separating the observer and scheduler into separate packages also makes it easy to experiment with alternative implementations of these parts. For example, we can implement an observer pattern that is compatible with IE11, with the same API or alternative scheduler that it uses
requestIdleCallbackfor output to the browser during idle times. *
TL; DR: more comprehensive, accurate, efficient, and debugging reactivity tracking and an API for creating observable objects.
Vue 3.0 will be shipped with a proxy based observer implementation that monitors reactivity. This eliminates a number of limitations of the current implementation of Vue 2 based on
- Add / remove property detection
- Array / .length index mutation detection
- Map, Set, WeakMap and WeakSet support
The new observer also has the following advantages:
- Open API for creating watched objects. This implies a simple solution for managing multiple components for smaller scenarios.
- Lazy observation by default. In 2.x, any reactive data, no matter how large, will be monitored at launch. This can cause noticeable overhead when starting the application if you have a large set of reactive data. In 3.x, you will only need to track the data that is used to render the initially visible part of your application, not to mention the fact that the observation itself is also much faster.
- More accurate change notification. Example: in 2.x, the forced addition of a new property using
Vue.setwill result in any observer depending on the object to be re-evaluated. In 3.x, only observers who rely on this particular property will be notified.
- Immutable observable objects: we can create an "immutable" version of an object that prevents mutations even with nested properties, unless the system temporarily unlocks it inside. This mechanism can be used to freeze prokined properties (props) or Vuex state trees outside mutations.
- Improved debugging capabilities: we can accurately track when and why a component is being redrawn or new handlers are started
TL; DR: smaller, faster, tree-shaking friendly, fragments and portals, Render API.
- Smaller: the new codebase is designed from scratch as tree-shaking friendly . Functions such as built-in components (
<keep-alive>) and helpline directives (
v-model) are now imported on demand. The size of the new runtime library <10kb in gzip. We can also offer more built-in functions in the future without resorting to weighting the payload for users who do not use them.
- Fragments and portals: despite the reduction in size, 3.0 comes with built-in support for fragments (a component that returns several root nodes) and portals (rendering a subtree in another part of the DOM, and not inside the component).
- Improved slot mechanism: all slots created by the compiler are now functions and are called during the render call of the child component. This ensures that the dependencies in the slots are collected as dependencies for the child element instead of the parent. It means that:
- When the contents of the slot change, only the child component is redrawn.
- When the parent component is redrawn, the child should not, if its slot content has not changed. This change offers even more accurate detection of changes at the component tree level, so fewer unnecessary re-renderings!
- Render API: The new ES class API will simplify rendering for projects such as Weex and NativeScript Vue . It will also simplify the creation of custom render functions for various purposes.
Compiler improvements *
TL; DR: tree-shaking friendly output, AOT optimization, a parser with better error information and source map support.
- When using links to tree-specific binding components, templates that use additional functions will generate code that imports these functions using the syntax of ES modules. Thus, unused optional functions are removed from the bundle.
- Due to improvements in the new Virtual DOM implementation, we can also perform more efficient compile optimizations, such as static tree lifting, static properties lifting, compiler hints, to skip child element normalization, faster ways to create VNode, etc.
- We plan to rewrite the parser to improve information about template compilation errors. This should also lead to the support of source maps, and the new parser can serve as the basis for the integration of third-party tools, such as the
IE11 * support
TL; DR: it will be supported, but in a separate assembly with the same limitations on reactivity Vue 2.x.
The new code base is currently intended only for evergreen browsers and assumes basic support for ES2015. But, alas, we know that many of our users still need to support IE11 for the foreseeable future. Most of the features used in ES2015 can be rewritten / copied for IE11, with the exception of Proxies. Our plan is to implement an alternative observer implementation with the same API, but using the old
Object.definePropertyAPI. A separate build of Vue 3.x will be available using this implementation. However, this build will be subject to the same changes as Vue 2.x, and thus not fully compatible with the “modern” build 3.x. We recognize that this imposes some inconvenience to library authors, since they need to know about compatibility for two different builds, but we will definitely provide clear recommendations on this issue when we reach this stage.
How are we going to do this?
First of all, even though we announce this today, we do not yet have a final action plan. At the moment we know what steps we will take:
1. Internal feedback
This is the phase in which we are now. Currently, we already have a prototype, which includes a new observer implementation, Virtual DOM and component implementation. We invited a group of authors of influential community projects to provide feedback for internal changes and would like them to be happy with the changes before moving forward. We want to ensure that important libraries in the ecosystem are ready at the same time as we release 3.0, so that users who rely on these projects can be easily updated.
2. Public RFC Feedback
As soon as we gain a certain level of confidence in the new design, for each change we will open a special RFC problem, which includes:
- Scale change
- Based on changes: what we get and what compromises are made
- Update path: can it be presented in a completely backward compatible way and with what?
We will expect feedback from the wider community to help us translate these ideas.
3. Entering Compatible Features in 2.x and 2.x-next
We do not forget about 2.x! In fact, we plan to use 2.x to gradually accustom users to new changes. We are gradually introducing confirmed API changes to 2.x via adapters
opt-in, and 2.x-next will allow users to try out a new proxy-based observer implementation.
The latest minor version in 2.x will become LTS and will continue to receive bug fixes and bug fixes for 18 months when Vue 3.0 is released.
4. Alpha phase
We will finish the compiler and server part 3.0 and begin to create alpha releases. Basically it will be for testing stability in small applications.
5. Beta phase
In the beta phase, our main task is to update support libraries and tools such as Vue Router, Vuex, Vue CLI, Vue DevTools and make sure that they work properly with the new kernel. We will also work with major library authors from the community to help them prepare for version 3.0.
6. RC phase
After we achieve the stability of the API and the code base, we will enter the RC phase with the freezing of the API. At this stage, we will also work on the "compat build" build: build 3.0, which includes compatibility levels for API 2.x. This build will also come with a flag that you can enable to issue outdated warnings for using API 2.x in your application. Mapping builds can be used as a guide for upgrading your application to version 3.0.
7. IE11 build
The final task before the final version will be an assembly compatible with IE11, as mentioned above.
8. Final Release
Honestly, we don’t know when it will happen yet, but probably in 2019. Again, we care more about delivering something that is reliable and stable, rather than promising specific dates. There is a lot of work to be done, but we are excited about what will happen next!