I've noticed some strange behaviour in Javascript when a class with defined variables is instanced.
Note: the code below simply serves as a reproduction case for this specific issue.
Let's consider the following class:
class Vector3
{
#unused1;
#unused2;
#unused3;
#unused4;
#unused5;
#unused6;
#unused7;
#unused8;
#unused9;
#unused10;
#unused11;
#unused12;
#unused13;
constructor(x, y, z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
And the following script:
let frames = 0;
let p = 0;
let fn = () => {
let now = performance.now();
let sum;
for (let i = 0; i < 10000; i++) {
var vector = new Vector3(Math.random(),Math.random(),Math.random());
var o = new Vector3(vector.x + Math.random(), vector.y + Math.random(), vector.z + Math.random());
}
// check the amount of passed frames every second
if (now - p >= 1000) {
console.log(frames);
// added to also test performance without having Dev Tools open
document.documentElement.innerText = frames;
frames = 0;
p = now;
}
frames++;
requestAnimationFrame(() => {
return fn();
})
return;
}
fn();
When running the above and viewing the console we can see performance is around (depending on your specs), 30 to 35 frames.
Now, if we modify the class to contain no defined variables as such:
class Vector3
{
constructor(x, y, z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
We can see performance go up to (again, depending on your specs) 60 frames and above.
At first I thought this issue had to do with garbage collection but after checking the Chrome Profiler I noticed most of the performance was being eaten up by getting variables and after further research/benchmarking I noticed this issue didn't actually have to do with variables in use, but variables declared.
Also important to note is that it doesn't seem to "matter" if the variable is declared as private or public.
Does anyone have an explanation for why this issue occurs?
Update: this issue seems affect Chromium more than Firefox. Firefox "always" seems to hit 60.
The performance issue you highlight was an unoptimized case where initializing fields was slow. That existed until Chrome 96. It is now fixed in Chrome 97 which was released at the start of January 2022.
Here's some evidence.