VS Code optimizes the name obfuscation and compression, reducing the built-in JS by 20%!

Visual Studio Code recently reduced the size of its built-in JavaScript by 20%, saving over 3.9 MB. This reduction not only reduces download and storage requirements, but also improves startup speeds since there is less source code to scan before JavaScript can run. This reduction was achieved through a new build step "name obfuscation compaction", rather than removing any code or doing major refactoring.

 

The size of workbench.js changes over time, and there are two drop points on the right: the first largest drop in VS Code 1.74 comes from obfuscation and compression of private properties, and the second smallest drop in VS Code 1.80 comes from obfuscation and compression export.

In this article, the author specifically introduces the thinking behind it , mainly two aspects of optimization. Take a look at the implementation logic below.

Obfuscation of compressed private properties

The obfuscated minified JavaScript still contains many long identifier names such as extensionIgnoredRecommendationsService. The author originally thought that esbuild had simplified these identifiers, such as:

  • const someLongVariableName = 123;

  • console.log(someLongVariableName);

becomes shorter:

  • const x = 123;

  • console.log(x);

Since JavaScript is distributed as source text, reducing the length of identifier names can actually reduce program size. This kind of optimization might seem absurd, but in the JavaScript world, it's really hard to beat.

Although esbuild implements obfuscation, by default it only processes names when it is certain that obfuscation will not change the behavior of the code. Therefore, in practice, esbuild only processes local variable names and parameter names.

In other words, esbuild's conservative policy means that many unsure whether it is safe to change the name is ignored.

How to do it?

The author team ended up using TypeScript to validate the obfuscated code. Just as TypeScript can catch unknown property accesses in regular code, the TypeScript compiler can catch cases where a property has been obfuscated but references to it have not been updated correctly.

Solution: You can obfuscate the TypeScript source code, and then compile it with the new TypeScript whose identifier name has been changed. This way you can have a higher degree of certainty that you haven't inadvertently broken your code.

Also, by using TypeScript, you can actually find all private properties (rather than just those starting with _), and you can even take advantage of TypeScript's existing renaming functionality to intelligently rename symbols without accidentally reshaping objects.

They propose a new rough workflow:

Use TypeScript's AST for each private or protected property found in the codebase:

        If this property needs to be modified:

                Calculate a new name by looking for unused symbol names

                Use TypeScript to generate all renaming edits that reference the property

Applies all renaming edits to TypeScript source code

Compile new edited Typescript resources with modified names

The results mostly worked.

Of course, there are some exceptions that need to be handled:

  • Uniqueness within the current class does not meet the requirements, and must also be unique between superclasses and subclasses. The root cause is that TypeScripts private keyword is just a compile-time decorator and doesn't really prevent super and subclasses from accessing private properties. If not handled carefully, this can lead to name collisions when renaming (fortunately Typescript reports this as an error).

  • In some cases, the subclass publicly inherits the protected permissions from the parent class, which is a wrong operation in many cases, and it is necessary to prohibit confusion here.

After a successful build, the size of the main workbench.js file of VS Code is reduced from 12.3MB to 10.6MB after obfuscating private attributes, a reduction of nearly 14%. This also results in a 5% faster loading speed, as less text needs to be scanned.

Obfuscate compressed export

On the other hand, in fact, there is obviously room for improvement with long names such as provideWorkspaceTrustExtensionProposals, or the localize function (used for UI display strings). The treatment for it is: export symbol names. As long as the exports are for internal use only, they can be shortened without changing code behavior.

In the end, after optimization, the overall file size was 20% smaller than without name compression. Across VS Code, name compression removes 3.9MB of JavaScript code from compiled source code, which both reduces download size and installation size, and reduces the amount of JS code that needs to be scanned every time VS Code starts by 3.9MB.

Supongo que te gusta

Origin www.oschina.net/news/251219/mangling-vscode
Recomendado
Clasificación