Skip to content

Instantly share code, notes, and snippets.

@johnsoncodehk
Last active July 20, 2024 09:50
Show Gist options
  • Save johnsoncodehk/62580d04cb86e576e0e8d6bf1cb44e73 to your computer and use it in GitHub Desktop.
Save johnsoncodehk/62580d04cb86e576e0e8d6bf1cb44e73 to your computer and use it in GitHub Desktop.

Volar 2.0 "Link"

I am Johnson, the author of Volar (now known as Vue Language Tools), and we released version 2.0 in March this year. This article will introduce you to the improvements and development experiences brought by 2.0.

Why 2.0?

In Vetur and Volar v1, we implemented Vue's IDE support through the Language Server Protocol (LSP), which works well for most small to medium-sized Vue projects, but there may be problems for very large projects.

TS Server and Vue Language Server are using double the memory

The memory usage of the TS Server and Vue language server is proportional to the number of project files and lines of code (including .d.ts files in node_modules), with each file generating expensive TS AST instances. In extreme cases (for example, when some dependencies contain thousands of .d.ts files), memory usage can spike, and when the TS Server and Vue Language Server each need a copy of the project files' TS AST, it could exhaust the computer's memory.

img1

In the above figure, the Vue Language Server occupies additional memory compared to the TS Server, which is occupied by Vue files. This part of the memory size is affected by the number of Vue files and the number and size of .d.ts files in node_modules that are directly or indirectly referenced by Vue files.

TypeScript Vue Plugin

To allow .ts files to recognize .vue component types, as well as support renaming variables in .vue from .ts, etc., we also need to install the TypeScript Vue Plugin, ultimately leading to double the memory usage.

img2

Takeover Mode

To address this issue, in Volar v1, we introduced a takeover mode, where when you manually disable the TS Server, the Vue Language Server takes over IDE support for .ts files. Finally, the memory issue seemed to be resolved.

img3

Limitations of Takeover Mode

If you have ever enabled takeover mode, you might find it not so convenient to use. You need to:

  1. Find the list of Built-in extensions in VSCode
  2. Locate "TypeScript and JavaScript Language Features"
  3. Disable it for each of your Vue project workspaces

If you don't look at Vue's documentation, you might not even know about the existence of takeover mode, hence this feature has always been used by only a minority of users.

Moreover, takeover mode has some other limitations:

  1. Does not support TypeScript LS Plugin
  2. Features lag behind VSCode
  3. Every time the TS version is updated, performance regression might occur due to changes in the TS auto import cache code
  4. Difficult to implement invalidation of auto import cache

New Exploration: Hybrid Mode

Since the TypeScript Vue Plugin can proxy TS functionalities, why not take over all TS functionalities for Vue files within the TypeScript Vue Plugin?

Given that TS support for Vue files is provided by the TS Server, and language features unrelated to TS (such as CSS, HTML, JSON) are provided by the Vue Language Server, we call this approach Hybrid Mode. (You can also think of it as an inverse takeover mode.)

The Vue Language Server no longer needs a TypeScript LS instance, thus achieving memory usage performance similar to Takeover Mode.

img4

In August 2023, I first proposed the idea of addressing the problem in a new direction in version 2.0 and completed a PoC after 4 months of development.

img5

In January 2024, we released Volar.js 2.0 to complete the infrastructure and refactoring needed for Hybrid Mode.

Finally, we implemented the TS plugin migration in one PR and were thrilled to find that it solved many of our problems!

img6

The Unusable 2.0.0

Just when we thought everything was ready and set to release 2.0.0 in March, we hit the worst timing for a release.

Being the first language tool to fully adopt a TS plugin, we encountered many compatibility issues that were not discovered during our internal testing.

The worst part was one of the issues stemmed from a bug in the version of Node.js bundled with VSCode. We were in a completely passive situation for a month, waiting for VSCode to release an update with a new version of Node.js.

After I resolved all the stability issues I could reproduce, the user complaints did not stop. After going through this process for several months, I became possibly the first extension developer to suffer from depression due to developing a VSCode extension.

As of writing this article, the latest version is 2.0.26. Under normal circumstances, the performance should have significantly improved compared to v1, and the memory usage is even slightly lower than v1 Takeover Mode.

(Test results at https://github.com/elk-zone/elk)

TS Server Vue Language Server Total
v1 without Takeover Mode 516 MB 541 MB + 197 MB 1254 MB
v1 with Takeover Mode --- 541 MB + 197 MB 738 MB
v2 with Hybrid Mode 516 MB 123 MB 639 MB

2.0 Development Dilemmas

There were no other successful cases to refer to for full integration with the TS Server, everything had to be figured out on our own. Therefore, it took us 7 months, from August 2023 to March 2024, to land version 2.0.

Investing several months into a single task for an open-source project is a process that can easily lead to getting lost. During this time, I constantly experienced sleep deprivation and self-doubt, but fortunately, we persisted and completed it. Currently, more and more frameworks are migrating to full TS plugin integration through Volar.js, and I believe this is the right path to achieving the highest point of Developer Experience (DX) for all of us.

Besides the mental challenges, full-time open source is also an economic challenge. I have been thinking about how to improve the sustainability of open-source projects. This is not just about my personal income but also about how to fairly distribute sponsorships to contributors to motivate project development.

I do not want to force people to pay for open-source software, nor do I want to emotionally blackmail people into sponsoring, but rather aim to establish a fair trade that is fair to everyone. Therefore, we are now exploring a charging method that offers early access to features for sponsors. If you think this plan benefits you, please consider subscribing to it. (Spoiler: The Reactions Visualization feature is very useful.)

Ending

This article only introduced Hybrid Mode, but in reality, version 2.0 includes many powerful improvements, such as rewriting vue-tsc to significantly reduce memory usage, among other features. I hope to have the opportunity to introduce these to you in the future.

I want to give a huge thank you to StackBlitz, who have supported me in full-time development since the beginning of last year, making these world-improving changes possible.

Also, a big thank you to Astro and JetBrains for generously donating ten thousand dollars, allowing us to focus entirely on development without worrying about anything else.

(This space is reserved for our lovely supporters.)

Special Sponsor

Stay in the flow with instant dev experiences.
No more hours stashing/pulling/installing locally

— just click, and start coding.

Platinum Sponsors

An approachable, performant and versatile framework for building web user interfaces.

Astro powers the world's fastest websites, client-side web apps, dynamic API endpoints, and everything in-between.

Essential tools for software developers and teams.

Open Source enables Microsoft products and services to bring choice, technology and community to our customers.

Silver Sponsors
@NaoyaMiyagawa
Copy link

Truly amazing work, Johnson💚 We cannot thank you enough!! Please take a break anytime you need too..!

@LouisHaftmann
Copy link

❤️

@Hyphon
Copy link

Hyphon commented Jul 15, 2024

❤️ thx for amazing work !

@jhxxs
Copy link

jhxxs commented Jul 15, 2024

❤️

@orta
Copy link

orta commented Jul 15, 2024

👍

@DrJume
Copy link

DrJume commented Jul 15, 2024

💚

@childrentime
Copy link

👍

@misbahansori
Copy link

👍

@StevenJPx2
Copy link

Thank you for the amazing work on Volar 2. Like you mentioned, the beginning phase of the v2 rollout was very rough, especially for neovim users. Now, with a little extra TLC compared to other LSPs, it works extremely well! I love the DX, especially the the scoped styles showing up in suggestions as you type in the class attribute. Don't know if that's a new feature or not.

@bruce-ws
Copy link

❤🌹

@yankeeinlondon
Copy link

Thank you for your open and very complete story of how we got to this point. Also congratulations on being a pioneer and taking the Volar plugin to a much better place by pushing into the "cutting/bleeding" edge. While the bleeding edge can be exhilarating at times it can quickly lead to disappointment and when that sits on top of many other developers expectations I can imagine that must be quite a large mental challenge. Anyway, I appreciate your openness on how hard it was and I hope you find a fast path back to recovery. We are all indebted to your work. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment