原文 : Plans for the Next Iteration of vue.js
On the original
Last week at vue.js London I gave a brief sneak peek of what’s coming in the next major version of Vue.this post provides an in-depth overview of the plan.
Last week, at the Vue.js Conference in London, I gave a glimpse of what the next major release of Vue will bring. This post will provide a detailed introduction to the program.
Why a new major release?
On the original
Vue 2.0 was released exactly two years ago (How time flies!) . During this period, The core has been fully compatible with five minor releases. We’ve been funded by a number of ideas that would bring improvements, but they were held off because they would result in breaking changes. At the same time, the JavaScript ecosystem and the language itself has been evolving rapidly. There are greatly improved tools that could enhance our workflow, and many new language features that could unlock simpler, more complete, And more efficient solutions to the problems Vue is trying to solve. What’s more exciting is that we are seeing ES2015 Support becoming a baseline for all major evergreen browsers. Vue 3.0 aims to leverage these new language features to Make Vue core smaller, faster, and more powerful. Vue 3.0 is currently in prototyping phase, and we have already implemented a runtime close to feature-parity with 2.x. Many of the items listed below are either already implemented, or confirmed to be feasible. Ones that are not yet implemented or still in exploration phase are marked with a
*.
It’s been two years since Vue 2.0 was released (how time flies!). . During this time, Vue released five minor versions that maintained kernel backward compatibility; We have accumulated a lot of ideas that could lead to all kinds of improvements, but these ideas have been put on hold because they bring incompatibility-breaking changes. At the same time, the JavaScript ecosystem and itself is growing rapidly. Many tool enhancements have improved our workflow, and many new language features unlock simpler, more comprehensive, and more efficient solutions to the problems Vue has been trying to solve. Even more exciting, we’ve seen ES2015 support become the benchmark for all major browsers. Vue 3.0 aims to use these new language features to make the Vue kernel smaller, faster, and more powerful.
Vue 3.0 is already in the prototyping stage, and we have implemented a runtime that is nearly equivalent to 2.0 features. Many of the items listed below are either already implemented or confirmed to be implemented. Items that are not yet implemented or are still being explored are marked with an “*”
details
High-level API changes
Except for the rendering API and scoped-slot syntax, everything else will remain unchanged or will be compatible with 2.x by building a separate compatibility package.
On the original
Since it’s a new major, there is going to be some breaking changes. However, we take backwards compatibility seriously, 3. So we want to start communicating these changes as soon as possible. Here’s the currently planned public API changes:
- Template syntax will remain 99% the same. There may be small tweaks in scoped slots syntax, but other than that we have no plans to change anything else for templates.
- 3.0 will support class-based components natively, with the aim to provide an API that is pleasant to use in native ES2015 without requiring any transpilation or stage-x features. Most current options will have a reasonable mapping in the class-based API. Stage-x features such as class fields and decorators can still be used optionally to enhance the authoring experience. In addition, the API is designed with TypeScript type inference in mind. The 3.x codebase will itself be written in TypeScript, and providing improved TypeScript support. (That said, usage of TypeScript in an application is still entirely optional.)
- The 2.x object-based component format will still be supported by internally transforming the object to a corresponding class. Mixins will still be supported. *
- Top level APIs will likely receive an overhaul to avoid globally mutating the Vue runtime when installing plugins. Instead, plugins will be applied and scoped to a component tree. This will make it easier to test components that rely on specific plugins, and also make it possible to mount multiple Vue applications on the same page with different plugins, but using the same Vue runtime. *
- Functional components can finally be plain functions — however, async components will now need to be explicitly created via a helper function.
- The part that will receive the most changes is the Virtual DOM format used in render functions. We are currently collecting feedback from major library authors and will be sharing more details as we are more confident of the changes, but as long as you don’t heavily rely on hand-written (non-JSX) render functions in your app, upgrading should be a reasonably straightforward process.
Since this is a new major release, there will be some compatibility breaking changes. However, we are very serious about backward compatibility, so we hope to start communicating these changes as soon as possible. Here are the public API changes currently planned:
- 99% of the template syntax will remain unchanged. We don’t have any other planned changes to the template other than possible tweaks to the Scoped Slot syntax.
- Version 3.0 will natively support class-based components without any compilation or stage features, providing a good writing experience. Many of the existing configuration items will have appropriate class versions of the API. Various stage features, such as class static fields and decorators, can still be used selectively to enhance the writing experience. In addition, the overall API will be designed with TypeScript’s type inference features in mind. The x code base itself will be written in TypeScript and provide enhanced TypeScript support. (That is, using TypeScript is still entirely optional.)
- 2. The object-based component format of the X series will still be supported, but it will be internally converted to a corresponding class.
- Mixins are still supported. *
- To avoid running time changes to the Vue when the plug-in is installed, the top-level API may undergo a major overhaul. The scope of the plug-in will then be limited to a specific component tree, making it easy to test components that depend on specific plug-ins and making it possible to mount multiple Vue applications that use different plug-ins, but the same Vue runtime, on the same page. *
- Functional components will support pure function writing — however, asynchronous components will need to be explicitly created through an auxiliary function.
- The biggest change will be in the format of the virtual DOM in the render function. We are currently gathering feedback from authors of major third-party libraries, and we will reveal more details as we have more confidence in these changes. It’s a big change, but as long as you don’t heavily use handwritten rendering functions (not JSX) in your application, the upgrade should be easier.
The code architecture
In a word: better internal module decoupling; TypeScript. Easier to contribute to the code base.
On the original
We are re-writing 3.0 from the ground up for a cleaner and more maintainable architecture, in particular trying to make it easier to contribute to. We are breaking some internal functionalities into individual packages in order to isolate the scope of complexity. For example, the observer module will become its own package, With its own public API and tests. Note this does not affect framework-level API – you will not have to manually import individual bits from multiple packages in order to use Vue. Instead, the final Vue package is assembled using these internal packages.
The codebase is also now written in TypeScript. Although this will make proficiency in TypeScript a pre-requisite for contributing to the new codebase, we believe the type information and IDE support will actually make it easier for a new contributor to make meaningful contributions.
Decoupling the observer and scheduler into separate packages also allows us to easily experiment with alternative implementations of these parts. For example, we can implement an IE11 compatible observer implementation with the same API, or an alternative scheduler that leverages requestIdleCallback to yield to the browser during long updates.*
When writing 3.0 from scratch, “achieving a clearer and more maintainable architecture, especially to make it easy for code to contribute” was our goal. To isolate complexity, we split some of the internal functionality into separate packages. For example, the Observer module will become a separate package, with its own external API and its own test cases; Note, however, that this doesn’t affect the frame-level API — you don’t need to manually import many small pieces of modules from multiple packages to use Vue, instead the final package of Vue is pre-assembled with these internal packages.
In addition, the code base is now written in TypeScript; While this makes “TypeScript proficiency” a prerequisite for contributing to a new code base, we believe that having type information in conjunction with IDE support actually makes it easier for a new contributor to contribute meaningfully.
Having decoupled the Observer and scheduler into separate packages, we can also test the two packages with alternative implementations. For example, we could implement an OBSERVER that is IE11 compatible and has the same API. Or implement another scheduler that uses the requestIdleCallback to produce work to the browser in long-running updates.
Monitoring mechanism
In a word: more comprehensive, accurate, efficient; More debugable response tracing; And apis for creating reactive objects.
On the original
3.0 Will ship with a proxy-based observer implementation that provides reactivity tracking with full language coverage. This eliminates a number of limitations of Vue 2’s current implementation based on Object. DefineProperty: eliminates a number of limitations of Vue 2’s current implementation based on Object.
3.0 will bring a proxy-based observer implementation that provides the full range of responsiveness to override languages, eliminating some of the limitations currently in the Vue 2 series based on Object.defineProperty, such as:
- Monitor the addition and deletion of attributes
- Subscription-based changes to arrays, monitoring.length changes
- Support for Map, Set, WeakMap and WeakSet
On the original
– Exposed API for creating observables. This offers a light-weight, dead simple cross-component state management solution for small to medium scale scenarios. – Lazy observation by default. In 2.x, any reactive data, regardless of how big it is, will be observed on startup. This can cause a noticeable overhead on app startup if your dataset is huge. In 3.x, only data used to render the initially visible part of your app will need to be observed, not to mention the observation itself is also much faster. – More precise change notification. An example: in 2.x, force adding a new property using Vue.set will cause any watcher that depends on the object to re-evaluate. In 3.x, only watchers that relies on that specific property will be notified. – Immutable observables: We can create “immutable” versions of a value that prevents mutations even on desktop properties, except when the system temporarily unlocks it internally. This mechanism can be used to freeze passed-down props or Vuex state trees outside mutations. Better debugging capabilities: we can precisely trace when and why a component re-render is tracked or triggered using the new renderTracked and renderTriggered hooks:
In addition, the new Observer has the following features:
- A exposed API for creating observables. This provides a lightweight, extremely simple solution for managing state across components for small to medium-sized applications. Before we do that, we can go through another
new Vue({data : {... }})
To create what’s called an Observable; In addition, vuex is actually implemented in this way.) - The default is Lazy Observation. In 2.x, any responsive data, regardless of its size, is monitored at startup time. If you have a lot of data, this can lead to a significant performance drain at startup. In version 3.x, only the data used in the initial visible part of the application is monitored, not to mention the monitoring scheme itself is actually much faster.
- More accurate notification of changes. For example: in the 2.x series, through
Vue.set
Forcing a new attribute causes all watch functions that depend on the object to be executed once; In 3.x, only watch functions that depend on this specific property are notified. - Immutable Observable: It is possible to create an Immutable version of an object that prevents changes to it, including its nested properties, unless this restriction is temporarily lifted internally. This mechanism can be used to freeze objects passed to component properties and Vuex state trees outside the mutation range.
- Better debugability: by using the new
renderTracked
和renderTriggered
Hook, which allows us to track exactly when a component is rerendered and when it is rerendered, and why.
Other runtime enhancements
In a word: smaller, faster; Support tree shaking optimization; Support for Fragments and cross-component rendering; Support for custom renderers.
On the original
– Smaller: the new codebase is designed from the ground up to be tree-shaking friendly. Features such as built-in components (, ) and directive runtime helpers (v-model) are now imported on-demand and tree-shakable. The constant baseline size for the new runtime is <10kb gzipped. In addition, features being tree-shakable also allows us to offer more built-in features down the road without incurring payload Penalties for users that don’t use them. – Faster: on preliminary benchmarks, we are seeing up to 100% performance improvement across the board, including raw Virtual DOM mounting & patching (we learned quite a few tricks from Inferno, the fastest Virtual DOM implementation out there), Component Instance Initialization and data observation. 3.0 will shave off half the time spent in JavaScript when your app boots up. Fragments & Portals: despite the size reduction, 3.0 Comes with built-in support for Fragments (Component returning multiple root nodes) and Portals (access A) sub-tree in another part of the DOM, instead of inside the component). – Improved slots mechanism: All Compiler-generated slots are now functions and invoked during the child component’s render call. This is invoked dependencies in slots are collected as dependencies for the child instead of the parent. This means that: 1. when slot content changes, only the child re-renders; 2. when the parent re-renders, the child does not have to if its slot content did not change. This change offers even more precise change detection at the component tree level, so even fewer useless re-renders! – Custom Renderer API: a first-class API for creating custom renderers will be available, and no longer requires forking the Vue codebase with custom modifications. This will make it much easier for render-to-native projects like Weex and NativeScript Vue to stay up-to-date with upstream changes. It would also make it trivially easy to create custom renderers for various other purposes.
-
Smaller: The new code base was designed with tree-shaking friendly in mind. Features such as built-in components (
,
), runtime utility instructions (V-models), and so on will be imported on demand and thus “tree-shakable.” For this new runtime, its size will always remain below 10KB. In addition, by making these features “tree-shakable”, we can provide more built-in features without increasing the network load if they are not used.
Reduce JavaScript Payloads with Tree Shaking is an optimization method that removes unnecessary code when packaging
-
Faster: In early benchmark testing, we saw a doubling in overall performance, including the speed of mounting and patching the virtual DOM (we learned a few tricks from Inferno — it’s the fastest virtual DOM implementation out there), As well as component instantiation speed and data monitoring performance. In 3.0, your app’s startup time will be cut in half.
-
Support for Fragments and Portal: Although smaller, 3.0 will also have built-in support for Fragments (which allow components to have multiple root nodes) and Portal (which allows rendering in other parts of the DOM than inside components).
Vue – Portal is a third party implementation, you can see it; There is also a third-party library for the Fragments feature, but the translator feels that the internal implementation of this library is not perfect, called vue-Fragments, for those interested.
-
Enhanced slot mechanism: All compiler-generated slots will be functional and will only be called when the child’s render function is called. This causes the dependencies in slot to be treated as dependencies of the child component, rather than the current parent component; This means: 1) When the contents of a slot change, only child components are rerendered; 2) When the parent component is re-rendered, there is no need for the child component to be re-rendered if the contents of the child component have not changed. This change in mechanism provides more accurate change detection, thus eliminating unnecessary re-rendering.
-
Support for Custom Renderers: This API can be used to create custom renderers that will appear as “first-class citizens” and will no longer need to fork a copy of Vue code to implement customization. The arrival of this API will make it easier for projects such as Weex and NativeScript “render as native” to keep up to date with Vue. In addition, it will make it extremely easy to create custom renderers for a variety of purposes.
Compiler-specific improvements *
One sentence introduction: “tree shaking friendly” output; More AOT optimizations; Better parsing errors; Source Map is supported.
On the original
– When targeting tree-shaking-capable bundlers, templates that make use of optional features will generate code that imports those features using ES modules syntax. Unused optional features are thus dropped from the final bundle. – Due to improvements in the new Virtual DOM implementation, we are also able to perform more effective compile-time optimizations such as static tree hoisting, Static props, Compiler – Hints for Runtime to skip children revival, VNode creation fast Paths, etc… – We plan to rewrite the parser to provide location information in template compilation errors. This should also lead to template source map support, and the new parser can serve as the foundation for 3rd party tooling integration, such as eslint-plugin-vue and IDE language services.
- If you are using a tree-shaker packer, the optional features used in the template are imported in the generated code through the module syntax of ES. Optional features that are not used are “shaken out” in the packaged file.
- As a result of the improvements brought about by the new virtual DOM implementation, we can perform some more efficient compilation time optimization, such as static tree lifting and static properties lifting as of July 1, 1997; As well as providing some hints from the compiler to the runtime to avoid the Children normalization process of child components; Provides a quick path for creating vNodes. And so on.
- We plan to rewrite the parser to provide information about where errors occurred when compiling the template; Source map support for templates is also available; Third-party tools such as
eslint-plugin-vue
And the IDE’s Language Services feature.
Compatible with IE 11 *
In a word: IE 11 will be supported, but it will be in the form of a separate build, which will have the same limitations as Vue 2.x’s responsive mechanism.
On the original
The new codebase currently targets evergreen browsers only and assumes baseline native ES2015 support. But alas, we know a lot of our users still need to support IE11 for the foreseeable future. Most of the ES2015 features used can be transpiled / polyfilled for IE11, with the exception for Proxies. Our plan is to implement an alternative observer with the same API, but using the good old ES5 Object.defineProperty API. A separate build of Vue 3.x will be distributed using this observer implementation. However, this build will be subject to the same change detection caveats of Vue 2.x and thus not fully compatible with the “Modern” build of 3.x. We are aware that this imposes some pachter for library authors as they will need to be aware of compatibility for two different builds, but we will make sure to provide clear guidelines on this when we reach that stage.
The new codebase is currently only for major browsers, and we assume they all support ES2015. But, alas, we also know that many users will still need to support IE11 for the foreseeable future. With the exception of Proxy, most of the ES2015 features can be used in IE11 in the form of translation or shippers. Our plan is to implement a separate alternative Observer with the same API, but based on the old Object.defineProperty API; It is then released by building a separate version of Vue 3.x that uses this implementation, but this separate version still has the same change detection problems as Vue 2.x, so it is not really a fully compatible version of 3.x. We also realize that this will cause some inconvenience to third-party library authors who need to consider compatibility issues between two different versions, but when we do get to that stage, we will certainly make sure to provide clear guidance.
How will we get there
While we are making this announcement today, we do not have a firm timetable, and we now have steps to achieve these goals:
1. Solicit feedback on runtime prototypes
On the original
This is the phase we are in right now. Currently, we already have a working runtime prototype that includes the new observer, Virtual DOM and component implementation. We have invited a group of authors of influential community projects to provide feedback for the internal changes, and would like to make sure they are comfortable with the changes before moving forward. We want to ensure that important libraries in the ecosystem will be ready at the same time when we release 3.0, so that users relying on those projects can upgrade easily.
That’s where we are right now. We now have a working runtime prototype that includes a new observer, a new virtual DOM, and a new component implementation. We invited a team of popular community project authors to gather their feedback on these underlying changes, hoping they’d be comfortable with them before moving forward. We hope that by 3.0, these key tripartite libraries in the Vue ecosystem will be synchronized and ready so that users who rely on these projects can easily upgrade.
2. Solicit public feedback through RFC
On the original
Once we gain a certain level of confidence in the new design, for each breaking change we will be opening a dedicated RFC issue which includes:
Scope of the change;
- Reasoning behind the change: what do we gain, and what tradeoffs are being made;
- Upgrade path: can it be introduced in a completely backwards-compatible fashion, via a removable compatibility layer, or via codemods?
- We will anticipate public feedback from the wider community to help us consolidate these ideas.
After we have gained some confidence in the new design, we will create a dedicated RFC channel for each incompatibility change, which will contain the following information:
- The scope of impact of the change;
- The pros and cons of this change: what will we gain and what will it cost.
- How will this change be upgraded: in the form of full backward-compatibility, by incorporating a removable compatibility layer, or by changing the code?
3. Introduce compatibility features in 2.x and 2.x-next
On the original
We are not forgetting about 2.x! In fact, we plan to use 2.x to progressively accustom users to the new changes. We will be gradually introducing confirmed API changes into 2.x via opt-in adaptors, and 2.x-next will allow users to try out the new Proxy-based observer.
The last minor release in 2.x will become LTS and continue to receive bugs and security fixes for 18 months when 3.0 is released.
We won’t forget 2.x! We plan to use 2.x to gradually adapt users to these new changes. We will gradually introduce verified API changes into 2.x through some adapters; In addition, the 2.X-Next release will also allow users to try out the new proxy-based Observer.
The last 2.x release will become the LTS release and will continue to receive bugs and security fixes for 18 months after the 3.0 release.
4. The Alpha stage
On the original
Next, We will finish up the compiler and server-side rendering parts of 3.0 and start making alpha releases. These will mostly be for stability testing purposes in small greenfield apps.
In this next phase, we will finish the compiler and server-side rendering of 3.0 and start working on the alpha version. The main purpose of this work is to perform stability tests in small applications.
5. Beta phase
On the original
During beta phase, our main goal is updating support libraries and tools like Vue Router, Vuex, Vue CLI, Vue DevTools and make sure they work smoothly with the new core. We will also be working with major library authors from the community to help them get ready for 3.0.
During the beta phase, our main goal was to update the relevant support libraries, such as Vue Router, Vuex, Vue CLI, and Vue DevTools, to ensure that they worked smoothly with the new kernel. We will also help third-party library developers through the community and work with them as we prepare for 3.0.
6. RC phase
On the original
Once we consider the API and codebase stable, We will enter RC phase with API freeze. During this phase we will also work on a “compat build” : A build of 3.0 that includes compatibility layers for 2.x API. This build will also ship with a flag you can turn on to emit deprecation warnings for 2.x API usage in your app. The compat build can be used as a guide to upgrade your app to 3.0.
When we think the apis and codebase are stable, we will move into the RC phase and the API will be fixed. At this stage, we will also build a “compat build” : A 3.0 version that includes a compatibility layer that is compatible with the 2.x API. It will also provide a flag that you can turn on to warn you that the API is obsolete where your application uses the 2.x API. So this “compatible version” can also be used to provide guidance when upgrading 3.0.
7. Build IE 11
The last task before the final release will be the IE11 compatibility build as mentioned above.
The final task before the final release is the aforementioned IE 11-compatible version.
8. Final release
On the original
In all honesty, we don’t know when this will happen yet, but likely In 2019. we care more about shipping something that is solid and stable rather than hitting specific dates. There is a lot of Work to be done, but we are excited for what’s coming next!
Frankly, we don’t know when we’ll get to that stage yet, but it could be 2019. Again, we’re looking for stability rather than a specific date. It’s a lot of work, but we’re very excited about these new features!