Head of Engineering atÂ
Author of uniforms
Everything is at radekmie.dev
2023-10-01
Core contributor of Meteor.js
Cross-browser compatibility is the ability of a website or web application to function across different browsers and degrade gracefully when browser features are absent or lacking.
jQuery
underscore.js
core-js
@babel/preset-env
???
???
???
???
// Concat plain strings: 'a'
joinName('a');
Most important helper of uniforms
// Flatten and concat strings in arrays: 'b.c'
joinName(['b'], 'c');
// Concat numbers: 'd.0'
joinName('d', 0);
// Ignore `undefined` and `null`: 'e'
joinName(undefined, 'e');
// All of the above: 'a.b.1.c.d.2.e'
joinName('a.b', 1, ['c', 'd'], undefined, 2, 'e');
function joinName(...parts: unknown[]) {
return parts
.reduce(
(path, part) =>
[],
)
.join('.');
}
part || part === 0
? path.concat(
typeof part === 'string'
? part.split('.')
: part
)
: path,
for (let round = 1; round <= 50; ++round) {
console.time();
for (let _ = 0; _ < 100000; ++_) {
joinName('a');
joinName(['b'], 'c');
joinName('d', 0);
joinName(undefined, 'e');
}
console.timeEnd();
}
Aggregate with
vazco.github.io/console-time-analyzer/
Browser | avg | max | min | std | sum |
---|
Chrome 117 | 38.2103ms | 68.7729ms | 36.6030ms | 4.39672ms | 1.910515s |
Firefox 117 | 105.560ms | 122.000ms | 103.000ms | 2.69191ms | 5.278000s |
Safari 16.6 | 62.7956ms | 92.2490ms | 60.9030ms | 4.26657ms | 3.139782s |
function joinName(...parts) {
const path = [];
for (let index = 0; index !== parts.length; ++index) {
}
return path.join('.');
}
const part = parts[index];
if (part || part === 0) {
}
if (typeof part === 'string') {
if (part.indexOf('.') !== -1) {
path.push(...part.split('.'));
} else {
path.push(part);
}
} else if (Array.isArray(part)) {
parts.splice(index--, 1, ...part);
} else {
path.push('' + part);
}
Browser | avg | max | min | std | sum |
---|
Chrome 117 | 25.4948ms | 53.3352ms | 24.3627ms | 4.09573ms | 1.274742s |
Firefox 117 | 101.340ms | 119.000ms | 99.0000ms | 2.62762ms | 5.067000s |
Safari 16.6 | 44.3199ms | 72.2010ms | 42.6200ms | 4.03886ms | 2.215998s |
Hey, I've noticed the new implementation is actually significantly slower for me!
~ Someone using Firefox
for (let round = 1; round <= 50; ++round) {
console.time();
for (let _ = 0; _ < 100000; ++_) {
joinName('a');
joinName(['b'], 'c');
joinName('d', 0);
joinName(undefined, 'e');
}
console.timeEnd();
}
for (let round = 1; round <= 50; ++round) {
console.time();
for (let _ = 0; _ < 100000; ++_) {
joinName('a');
joinName(['b'], 'c');
joinName('d', 0);
joinName(undefined, 'e');
}
console.timeEnd();
}
One more real-life scenario
joinName('a.b', 1, ['c', 'd'], null, 2, 'e');
Browser | avg | max | min | std | sum |
---|
v1 Chrome 117 | 80.8508ms | 113.457ms | 78.8718ms | 4.66811ms | 4.042544s |
v1 Firefox 117 | 158.740ms | 175.000ms | 155.000ms | 3.21751ms | 7.937000s |
v1 Safari 16.6 | 101.327ms | 125.107ms | 98.8790ms | 3.61048ms | 5.066369s |
v2 Chrome 117 | 50.3077ms | 83.5910ms | 48.7460ms | 4.80059ms | 2.515386s |
v2 Firefox 117 | 182.060ms | 195.000ms | 176.000ms | 4.56249ms | 9.103000s |
v2 Safari 16.6 | 83.8215ms | 112.198ms | 81.4840ms | 4.23691ms | 4.191076s |
Chrome
iOS Safari
Safari
Edge
Firefox
Other
9%
8%
Overall, it's faster for 83% and slower for 9% of users.
Remaining 8%
is unchecked!
// Sample usage:
[omitUnnecessaryFields({arrayIndices, value: undefined})];
We're messing up with hidden classes in V8!
const omitUnnecessaryFields = result => {
if (!result.dontIterate) {
delete result.dontIterate;
}
if (result.arrayIndices && !result.arrayIndices.length) {
delete result.arrayIndices;
}
return result;
};
function buildResult(arrayIndices, dontIterate, value) {
return arrayIndices && arrayIndices.length
? dontIterate
? [{ arrayIndices, dontIterate, value }]
: [{ arrayIndices, value }]
: dontIterate
? [{ dontIterate, value }]
: [{ value }];
}
// Sample usage:
buildResult(arrayIndices, false, undefined);
V8 is happy now!
Depending on the test case, it got 50%-90% faster in Chrome and between 10% slower or faster on Safari.
>95% of the usage is on the server! Node.js and Chrome use the same V8 runtime, so...
Ship it!