Slide 1

Slide 1 text

Miroslav Jonaš / @meeroslav / Weblica 2025 The dark art of code optimization JavaScript Bible

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

@meeroslav

Slide 4

Slide 4 text

The deadline-driven development @meeroslav

Slide 5

Slide 5 text

The performance @meeroslav

Slide 6

Slide 6 text

@meeroslav Someone else will fix it

Slide 7

Slide 7 text

Static rendering

Slide 8

Slide 8 text

Lazy loading... @meeroslav

Slide 9

Slide 9 text

Hydration @meeroslav

Slide 10

Slide 10 text

Partial hydration @meeroslav

Slide 11

Slide 11 text

Is it though? @meeroslav

Slide 12

Slide 12 text

Miroslav Jonaš Lead DPE at @meeroslav

Slide 13

Slide 13 text

TTI FCP TBT LCP LSD NBA @meeroslav

Slide 14

Slide 14 text

Battle tested @meeroslav

Slide 15

Slide 15 text

The Big O @meeroslav

Slide 16

Slide 16 text

Know your loops const nodes = []; for (let i = 0; i < nodes.length; i ++ ) { const v = nodes[i]; v.children.forEach((c) => { for (key in c) { collection[key] = { . .. myInit }; } }); } 1 2 3 4 @meeroslav

Slide 17

Slide 17 text

MUTATIONS ARE BAD

Slide 18

Slide 18 text

const myList = fetch( / * super large JSON * / ); addFullName(myList); / / < -- - implement this @meeroslav

Slide 19

Slide 19 text

const myList = fetch( / * super large JSON * / ); addFullName(myList); / / < -- - implement this // immutable version function addFullName(myList) { const result = {}; Object.keys(myList).forEach(username = > { const user = myList[username]; result[username] = { . . . user, address: [ . . . user.address], fullName: user.firstName + ' ' + user.lastName, }; }); return result; } @meeroslav

Slide 20

Slide 20 text

const myList = fetch( /* super large JSON */ ); addFullName(myList); / / < -- - implement this // mutable version function addFullName(myList) { Object.entries(myList).forEach(user => { user.fullName = user.firstName + ' ' + user.lastName; }); } 27* times faster @meeroslav

Slide 21

Slide 21 text

PERFORMANCE DETECTION Repetitio est mater studio…

Slide 22

Slide 22 text

? const myList = fetch( /* super large JSON */ ); const initConnection = Object.keys(myList).reduce((acc, username) = > { return { . . . acc, [username]: false }; }, {}); const network = {}; Object.keys(myList).forEach(username => { network[username] = { .. . initConnection }; }); @meeroslav

Slide 23

Slide 23 text

350* times faster @meeroslav const network = {}; Object.keys(myList).forEach(username => { network[username] = {}; });

Slide 24

Slide 24 text

“No code is faster than any code ” - Me @meeroslav

Slide 25

Slide 25 text

PERFORMANCE DETECTION ARRAYS vs OBJECTS @meeroslav

Slide 26

Slide 26 text

export type SamplerTrack = { id: string; volume: number; reverb: number; solo: boolean; mute: boolean; gain: GainNode; type: 'SAMPLER'; sample: 'string'; envelope: { attack: number; decay: number; sustain: number; release: number; }; sequence: SynthNote[]; }; type SynthNote = { note: number | undefined | '-'; frequency ? : number; }; / / track.sequence[0].note / / track.envelope.sustain @meeroslav

Slide 27

Slide 27 text

const track: SamplerTrack = { id: 'abcdef', volume: 0.8, reverb: 0.2, solo: false, mute: false, gain: context.createGain(), type: 'SAMPLER', sample: 'kick', envelope: { attack: 0.1, decay: 0.2, sustain: 0.5, release: 0.3 }, sequence: [ { note: 6 }, { note: 4 }, { note: 8 }, { note: undefined }, { note: 2 }, { note: '-' }, { note: '-' }, { note: undefined }, { note: 6 }, { note: 4 }, { note: 8 }, { note: undefined }, { note: 2 }, { note: '-' }, { note: '-' }, { note: undefined }, ] } @meeroslav export type SamplerTrack = { id: string; volume: number; reverb: number; solo: boolean; mute: boolean; gain: GainNode; type: 'SAMPLER'; sample: 'string'; envelope: { attack: number; decay: number; sustain: number; release: number; }; sequence: SynthNote[]; }; type SynthNote = { note: number | undefined | '-'; frequency ? : number; }; / / track.sequence[0].note / / track.envelope.sustain

Slide 28

Slide 28 text

const track = [ 'abcdef', 0.8, 0.2, false, false, context.createGain(), 1, 'kick', [ 0.1, 0.2, 0.5, 0.3 ], [ 6, 4, 8, undefined, 2, '-', '-', undefined, 6, 4, 8, undefined, 2, '-', '-', undefined ] ]; @meeroslav const track: SamplerTrack = { id: 'abcdef', volume: 0.8, reverb: 0.2, solo: false, mute: false, gain: context.createGain(), type: 'SAMPLER', sample: 'kick', envelope: { attack: 0.1, decay: 0.2, sustain: 0.5, release: 0.3 }, sequence: [ { note: 6 }, { note: 4 }, { note: 8 }, { note: undefined }, { note: 2 }, { note: '-' }, { note: '-' }, { note: undefined }, { note: 6 }, { note: 4 }, { note: 8 }, { note: undefined }, { note: 2 }, { note: '-' }, { note: '-' }, { note: undefined }, ] }

Slide 29

Slide 29 text

const TRACK_ID = 0; const TRACK_VOLUME = 1; const TRACK_REVERB = 2; const TRACK_SOLO = 3; const TRACK_MUTE = 4; const TRACK_GAIN = 5; const TRACK_TYPE = 6; const TRACK_SAMPLE = 7; const TRACK_ENVELOPE = 8; const TRACK_SEQUENCE = 9; const ATTACK = 0; const DECAY = 1; const SUSTAIN = 2; const RELEASE = 3; / / track.sequence[5] track[TRACK_SEQUENCE][5] / / track.envelope.sustain track[TRACK_ENVELOPE][SUSTAIN] 18%* faster @meeroslav const track = [ 'abcdef', 0.8, 0.2, false, false, context.createGain(), 1, 'kick', [ 0.1, 0.2, 0.5, 0.3 ], [ 6, 4, 8, undefined, 2, '-', '-', undefined, 6, 4, 8, undefined, 2, '-', '-', undefined ] ];

Slide 30

Slide 30 text

PERFORMANCE DETECTION Don't Lookup tables

Slide 31

Slide 31 text

@meeroslav const myList = fetch( / * super large JSON * / ); getNickNameByRepo(repoUrl); // < - -- implement this

Slide 32

Slide 32 text

13000* times faster @meeroslav const myList = fetch( / * super large JSON * / ); const usernameLookup = {}; Object.entries(myList).forEach(([username, data]) => { data.repos.forEach((repo) => { usernameLookup[repo.url] = username; }); }); function getNickNameByRepo(repoUrl) { return usernameLookup[repoUrl] || 'Unknown'; }

Slide 33

Slide 33 text

MAPS VS HASHMAPS MAPS vs HASHMAPS

Slide 34

Slide 34 text

17* times faster @meeroslav const myList = fetch( / * super large JSON * / ); const usernameLookup = new Map(); Object.entries(myList).forEach(([username, data]) => { data.repos.forEach((repo) => { usernameLookup.set(repo.url, username); }); }); function getNickNameByRepo(repoUrl) { return usernameLookup.get(repoUrl]) || 'Unknown'; }

Slide 35

Slide 35 text

Higher order functions @meeroslav

Slide 36

Slide 36 text

tracks .filter(t => t.type === 'SAMPLER') .map(t => t.sequence) .reduce((acc, cur) = > [ . . . acc, . . . cur ], []); @meeroslav

Slide 37

Slide 37 text

200* times faster tracks .filter(t => t.type === 'SAMPLER') .map(t => t.sequence) .reduce((acc, cur) = > [ . . . acc, . . . cur ], []); const seq = []; tracks.forEach(t = > { if (t.type === 'SAMPLER') { t.sequence.forEach(s => { seq.push(s) }) } }) @meeroslav

Slide 38

Slide 38 text

@meeroslav a) Zone.js? b) vDOM? c) Signals? d) Reactivity?

Slide 39

Slide 39 text

@meeroslav Mutate & persist e)

Slide 40

Slide 40 text

PERFORMANCE DETECTION

Slide 41

Slide 41 text

JSBENCH.ME @meeroslav

Slide 42

Slide 42 text

console.time 4 the win @meeroslav

Slide 43

Slide 43 text

The Butterfly Effect: How we gave the Linter a 900x boost @meeroslav

Slide 44

Slide 44 text

know your loops embrace mutation choose structures wisely avoid HOF when performance matters use old school update measure what matters @meeroslav

Slide 45

Slide 45 text

console.time @meeroslav

Slide 46

Slide 46 text

JavaScript Bible The dark art of code optimization Miroslav Jonaš Thank you!