Explore mangling of private properties in VS Code codebase #165429
Labels
engineering
VS Code - Build / issue tracking / etc.
on-release-notes
Issue/pull request mentioned in release notes
perf
Milestone
Uh oh!
There was an error while loading. Please reload this page.
Background
The compiled JS source of VS Code still contains lots of long names that do not get minified:
Notice how
_notebookService
and_logSerivce
are using their original namesUnlike local variables, it not safe to mangle these names to be shorter for a few key reasons:
It can break dynamic code. Code such as
this['myProp']
would still be using the old property name (myProp
) instead of the new mangled nameIt can break public apis. Exported types also have their properties mangled, breaking public apis such as
vscode.d.ts
It can break apis that we consume. For instance, a mangler might rewrite all dom properties. I'm not sure if any tools out there are smart enough to not to do this (some have options to try avoiding mangling dom properties , but I'm not sure any handle all cases of this properly)
However mangling properties is very tempting as it could reduce the bundle size without any significant code changes. Because of above problems however, we need to be smart about how we go about enabling this.
Proposal
I propose that we explore enabling property mangling within the VS Code codebase. Our goals with this:
Since mangling can be dangerous, for now we will only look into mangling private properties. These theoretically should be safe to transform since they are can only used with a single class. We also don't have too many places where we are looking up private properties dynamically
November
For November, we will start exploring the managing of a very specific subset of private properties: private service properties.
This will let us learn more about property mangling and establish tools to use it successful going forward. Even so, I believe a 5% reduction in bundle size is reasonable just from mangling services.
Here's a rough plan for how this work will progress:
_
, such as_someService
_
from public/protected service properties: eslint: properties starting with underscore are private #165259_
: Try mangling_private
service props #165117_
. I have a simple tool that can automate thisPost November
If everything goes well in November, will can next explore mangling more private properties by extending mangling to every property that starts with
_
.A rough plan for this:
_
property in some of our built-in extensions. This will let us test this transformation in a smaller codebase before applying it to VS Code_
. Also provide tools to automate this change_
)._
, than we are more likely in the 10-20% range for bundle size reductionTODO: Investigate if esbuild can just mangle
private
props without matching on the name. That would let us avoid requiring the_
. However I'm not sure it is possible. Maybe using plugins?Long term
In the long term, if we adopt native
#
private properties mangling should always be safe (indeed#
private fields are mangled automatically by most tools). However I don't think we can easily jump right to#
privates in core for a few reason:Native private properties are only emitted by TS with
es2022+
, which also brings support for native class fields. With older targets, TS instead use a weak map for private fields. This has a runtime overhead and also could make the bundle larger instead of smallerSwitching to target
es2022
is also not trivial due to useDefineWithClassFields should use-before-init error when class property initializer refers to parameter property TypeScript#50971. At a minimum, we need TS to emit errors so we can catch cases like thisWe use
constructor(private prop: Thing)
a lot in our code base. TS currently has no plans to support this syntax for native private props.Migrating to standard JS syntax is technically correct but results in 3x the amount of TS just to declare and init a property
The text was updated successfully, but these errors were encountered: