编程知识 cdmana.com

The story behind the creation of Vue 3.0

translator : Wang Qiang

Reading this article requires 3 minute

At the beginning of this year Vue 3 I wrote this long article before it was officially released , detailed Vue 3 Design process . Top of the front end will translate the full text as follows , I hope it can help you better understand Vue 3 The story behind it .

In the past year ,Vue The team has been developing Vue.js Next major version of , We hope to release it in the first half of this year ( At the end of this paper, this work is still in progress ).Vue The idea of the new version was shaped by 2018 end of the year , at that time Vue 2 Is two and a half years old . It doesn't seem that long compared to the life cycle of general software , But in this period , The front-end world is no longer the same .

After we update ( And rewrite )Vue The main version of , There are two main factors to consider : The first is the new JavaScript The level of support for language features in mainstream browsers ; Secondly, some design and architecture problems gradually exposed over time in the current code base .

Why rewrite

Take advantage of new language features

With ES2015 Standard landing ,JavaScript( Formerly known as ECMAScript, Abbreviation for ES) Many significant improvements have been made , At the same time, mainstream browsers are finally starting to provide good support for these new features . Some of these features allow us to greatly improve Vue The ability of .

One of the most remarkable things about this is Proxy , It provides the framework with the ability to intercept operations against objects .Vue One of the core features of is to listen for user-defined state changes , And respond to update DOM.Vue 2 By replacing state object properties getter and setter To achieve this responsiveness . to turn to Proxy after , We can solve Vue There are many limitations in the present ( For example, new attributes cannot be detected ), It also provides better performance .

but Proxy It's a native language feature , Can't provide complete polyfill. To do this, we need to change the browser support scope of the new framework —— This is a disruptive change , Only the new major version can implement .

Solve architecture problems

Fixing these problems on the existing code base requires a lot of high-risk refactoring work , Almost equivalent to rewriting .

Maintaining Vue 2 In the process of , Many of the problems we have accumulated are difficult to solve due to the existing architecture . for example , Template compiler writing makes it difficult to achieve good source mapping support . in addition , although Vue 2 Technical support for the construction of non DOM Advanced renderers for platforms , But to achieve this support , We need to fork The code base , You have to copy a lot of code . Fixing these problems on the existing code base requires a lot of high-risk refactoring work , It's almost equivalent to rewriting .

meanwhile , We create a lot of hidden coupling between many internal modules and seemingly nowhere to go code , As a result, a lot of technical debts have been accumulated . Now it's hard to understand the meaning of a part of the code base alone , And we've also noticed that contributors are rarely confident of making radical changes . By rewriting , We've been able to rethink how code is organized based on these issues .

The early prototype stage

We are from 2018 At the end of the year Vue 3 The prototype of , The main goal is to validate solutions to the above problems . At this stage , We mainly lay a solid foundation for the follow-up development work .

to turn to TypeScript

Vue 2 At first it was pure ES Compiling . Shortly after the prototype phase began , We realized that for a project of this scale , The type system can be very useful . Type checking can greatly reduce the introduction of surprises in refactoring bug The risk of , It also increases the confidence of contributors in making breakthrough changes . We used Facebook Of Flow Type checker , Because it can be progressively added to an existing pure ES In the project .Flow It played a certain role , But our earnings are less than expected ; In particular, there are too many major changes to it , It's quite painful to upgrade . It doesn't support the integrated development environment as well TypeScript And VS Code The level of deep integration .

We also notice that more and more users are using it in combination Vue and TypeScript. To support their usage scenarios , We need to write and maintain a separate set of TypeScript Statement , It uses another type system . to turn to TypeScript after , We can automatically generate declaration files , Reduce maintenance costs .

Decouple the inner package

We also used a single warehouse solution , The framework is made up of many internal packages , Each package has its own independent API、 Type definitions and test cases . We want to make the dependencies between the modules more obvious , Make it easier for developers to read 、 Understand and modify all of these dependencies . It's about lowering the threshold of project contribution , Key initiatives to improve its long-term maintainability .

To develop RFC technological process

2018 end of the year , We have a new response system and virtualization DOM The prototype of the renderer . We verified the internal architecture optimization in the plan , But it's just a rough draft of the external facing API Change your mind . Now it's time to turn these ideas into concrete designs .

We know that this step needs to be done carefully at an early stage .Vue The widespread popularity of this means that significant changes can bring huge migration costs to users , It could also lead to ecological fragmentation . To get users to submit feedback on major changes , We are 2019 At the beginning of the year, a set of RFC( For advice ) technological process . all RFC There's a template , Including motivation 、 Design details 、 Trade off and strategy adoption . The implementation form of this process , It's in one. Github The warehouse submits the proposal as a pull request , So it's natural to discuss the proposal in the comments .

It turns out that this RFC The process is very useful . As a frame of thinking , It forces us to consider all aspects of a potential change , And let the whole community participate in the design process , And submit fully considered feature requirements .

faster , smaller

The performance of the front-end framework is crucial .

The performance of the front-end framework is crucial . Even though Vue 2 Has provided competitive performance , But this rewrite gives us the opportunity to experiment with new rendering strategies to further improve performance .

Break through the virtual DOM Bottleneck

Vue There is a unique rendering strategy : It provides a class HTML Template syntax for , But the template is compiled into a return virtual DOM Tree rendering function . The framework recursively traverses two virtual DOM Trees , Compare all the attributes of each node to determine the update DOM Which parts of . This relatively violent algorithm is generally fast , Thanks to Hyundai JS So many advanced optimizations implemented by the engine . But the update process still involves a lot of unnecessary CPU Work . When your template has a lot of static content , But only a small number of dynamic binding , The efficiency of the update will be particularly low —— Or to recursively traverse the entire virtual DOM Trees , To find out what to update .

Fortunately, template compilation allows us to do static analysis of templates , And extract the dynamic part of the information .Vue 2 Skip static subtree , To a certain extent, this has been done ; But because of the over simplified compiler architecture , More advanced optimizations are hard to implement . stay Vue 3 We've rewritten the compiler , Added a suitable AST transform The Conduit , So that we can transform Compile time optimization in the form of plug-ins .

Now there's a new architecture , We want to find a rendering strategy that minimizes the overhead . One option is to abandon the virtual DOM And directly generate imperative DOM operation , But it's going to lose direct writing virtual DOM The ability to render functions , We found that this is a very valuable capability for advanced users and library authors . Besides , It's also going to be a big change with a huge impact .

The next option is to get rid of unnecessary virtualization DOM Tree traversal and attribute comparison , This is also the most expensive part of the update process . So , The compiler and runtime need to work together : Compiler analysis templates , Generate code with optimization clues , And the runtime takes clues and chooses the fastest path . Here are three major optimizations :

First , At the tree level , We notice that there is no template instruction to dynamically adjust the node structure ( Such as v-if and v-for) when , The structure of the node remains completely static . If we split the template into nested parts according to these structured instructions " block ", The node structure in each block will also remain static . When we update a node in a block , You don't have to recursively traverse the whole tree —— Dynamic binding within a block can be traced in a flat array . This optimization greatly reduces the number of trees to traverse , Avoid most of the virtual DOM Tree overhead .

secondly , The compiler will aggressively detect static nodes in the template 、 Subtrees and even data objects , They will be generated outside of and rendered to . This avoids re creating these objects every time you render , Greatly reduces memory usage , And reduce the frequency of garbage collection .

Last , At the element level , The compiler will have a dynamic binding for each element , Generate an optimization flag based on the type of update it needs to make . For example, an element has a dynamic class Binding and some static properties , It will get a logo , It means that only needs to be done here class Check . The runtime gets these flags , Then choose the fastest path .

CPU Time : Refer to JavaScript The time taken by the operation , Not including browsers DOM The time taken to operate .

Combining these optimizations , Our rendering update speed has been significantly improved , In some cases Vue 3 Of CPU Time Only for Vue 2 Less than one tenth of .

Reduce the package size

The size of the framework also affects its performance . This is a Web Application specific phenomena , Because assets need to be downloaded online , And the application needs to wait until the browser has finished parsing the necessary JavaScript Only after the code can we start to interact . This is particularly true of single page applications . Even though Vue It's always been a relatively lightweight framework ——Vue 2 The runtime size of is 23KB(gzip After the compression ), We still notice two problems :

First , Not everyone needs the full functionality of the framework . for example , Applications that never need transition features still need to download and parse relevant code .

in addition , We're constantly adding new features to the framework , The framework is getting bigger , There is no end . So when we weigh the pros and cons of the new feature , We have to be very concerned about the weight of packet size . result , We tend to just add features that most users will use .

ideally , Users can build without features they don't need in the framework ( That is to say " Shaking tree optimization "), Keep only the features you use . So when we add features that only some users will use , It will not add the burden of application volume to other users .

stay Vue 3 in , We take most of the overall situation API And internal helper Moved to ES Module export , And that's the goal . This allows modern wrappers to statically analyze module dependencies , And remove the code related to unused exports . The template compiler also generates code suitable for shake tree optimization , It will only import the features that the template really applies to helper.

Some parts of the framework can never be optimized by shaking trees , Because they are important for all application types . We call the volume of code that cannot be discarded as baseline size . although Vue 3 Many new features have been added , It's only about the baseline size 10KB(gzip after ), Less than Vue 2 Half of .

Meet the expansion requirements

We also want to improve Vue The ability to deal with large-scale applications . We originally designed Vue The main idea is to lower the threshold and smooth the learning curve . But as the Vue More and more popular , We also see more and more project requirements expanding over time , The later stage even contains hundreds of modules , It takes dozens of developers to maintain . For this type of project ,TypeScript This type system and can provide clarity of organization 、 The ability to easily reuse code is essential , but Vue 2 The level of support in these areas is not ideal .

stay Vue 3 The early design phase of , We try to use built-in pairs class Support for writing components , To better integrate TypeScript. The problem here is , In order to make class Many of the language features available and needed ( for example class fields and decorators) They are still in the proposal stage , There may be changes in the official version . The complexity and uncertainty that comes with it makes us question Class API Whether it's really appropriate , Because it can only improve a little TypeScript It's just the ability to integrate .

So we decided to explore other ways to solve the problem of expansion . suffer React Hooks Inspired by the , We're thinking of exposing the underlying responsive and component life cycles API, This provides a more flexible way to write component logic , That is to say Composition API .Composition API No longer need to define components with a long configuration list , It allows users to define 、 Composition and reuse of component logic , It's like writing functions , At the same time, it can provide perfect TypeScript Support .

We really like the idea . Even though Composition API Is designed to solve specific types of problems , But it can also be used in simple component development . In the first draft of the proposal, we were a bit carried away , It suggests that we may use Composition API Replace the current Options API. This caused a huge backlash from community members , It taught us an important lesson , Let us recognize the long-term plan and development direction of communication with the community , And the importance of understanding user needs . After listening to community feedback , We completely rewrote the proposal , confirm Composition API It's just icing on the cake , yes Options API A supplement to . The feedback from the new proposal is much more positive , We also received a lot of constructive comments .

Hold the balance

Diversity of developers means diversity of usage scenarios .

More than a million developers are using Vue, One of them only knows a little HTML/CSS novice , from jQuery Experts along the way , Old birds from other frameworks , Back end engineers looking for front-end solutions , There are architects who design large-scale software . Diversity of developers means diversity of usage scenarios : Some developers may want to enhance the interactive experience of old projects , Others may want to quickly develop low-cost, one-off projects ; Architects may have to deal with large, long-term projects , And the change of development team members during the project life cycle .

Vue Design is constantly changing and evolving according to these requirements , We also try to find a balance among the many trade-offs .Vue The slogan of the “ Progressive framework ”, And behind that is the layering that's formed in this process API Design . Novices can use CDN script、 be based on HTML The template and intuitive Options API Smooth learning Introduction . And experts can use full-featured CLI、 Rendering functions and Composition API To deal with complex requirements .

There is still a lot of work to be done to realize our vision , One of the most important is to update the support library 、 Documentation and tools , To ensure smooth migration . We will continue to work hard in the coming months , And we can't wait to see the community use Vue 3 What a wonderful creation .

The authors introduce

Yuxi is Vue.js The creator and project leader of the framework , Also an independent open source Developer .


This article is from WeChat official account. - Front end preacher (honeyBadger8) , author : Especially the rain creek

The source and reprint of the original text are detailed in the text , If there is any infringement , Please contact the yunjia_community@tencent.com Delete .

Original publication time : 2020-06-05

Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .

本文为[Southern Jiangsu]所创,转载请带上原文链接,感谢

Scroll to Top