Prestatiebudgetten houden webapps snel door heldere limieten te stellen op laadtijd, JS‑grootte en Core Web Vitals, plus snelle audits en fix‑eerst regels.

Een prestatiebudget is een set limieten waar je het over eens bent voordat je gaat bouwen. Het kan een tijdslimiet zijn (hoe snel de pagina aanvoelt), een limiet in grootte (hoeveel code je levert) of een simpele bovengrens (aantal requests, afbeeldingen, third‑party scripts). Als je over de limiet gaat, wordt het behandeld als een gebroken vereiste, niet als een “nice to fix later” taak.
Snelheid wordt meestal slechter omdat leveren cumulatief is. Elk nieuw widget voegt JavaScript, CSS, fonts, afbeeldingen, API‑calls en extra werk voor de browser toe. Zelfs kleine wijzigingen tellen op totdat de app zwaar aanvoelt, vooral op mid‑range telefoons en tragere netwerken waar de meeste echte gebruikers zitten.
Meningen beschermen je hier niet. De één zegt “het voelt prima op mijn laptop”, de ander zegt “het is traag”, en het team debatteert. Een budget beëindigt die discussie door performance een productconstraint te maken die je kunt meten en afdwingen.
Dit sluit aan bij Addy Osmani’s denkrichting: behandel performance als ontwerplimieten en beveiligingsregels. Je probeert niet “veilig te blijven” of “hoopt” dat de layout goed blijft. Je stelt standaarden, controleert ze continu en blokkeert veranderingen die ze breken.
Budgetten lossen meerdere praktische problemen tegelijk op. Ze maken afwegingen expliciet (een nieuwe feature betekent ergens anders betalen), vangen regressies vroeg (wanneer fixes goedkoper zijn) en geven iedereen dezelfde definitie van “snel genoeg.” Ze verminderen ook de late paniek die vaak vlak voor een lancering opduikt.
Hier is een scenario waar budgetten voor bedoeld zijn: je voegt een rijke charting‑library toe voor één dashboardview. Die wordt naar iedereen verzonden, vergroot de main bundle en duwt het moment van de eerste betekenisvolle weergave later. Zonder budget glipt dit erdoor omdat de feature “werkt.” Met een budget moet het team kiezen: lazy‑load de chart, vervang de library of vereenvoudig de view.
Dit wordt nog belangrijker als teams snel apps kunnen genereren en itereren, ook met chat‑gedreven build‑workflows zoals Koder.ai. Snelheid is geweldig, maar maakt het ook makkelijk om extra dependencies en UI‑franje te sturen zonder het te merken. Budgetten voorkomen dat snel itereren verandert in trage producten.
Prestatiewerk faalt wanneer je alles meet en niemand eigendom geeft. Kies één paginestroom die echt belangrijk is voor gebruikers en behandel die als anker voor je budgetten.
Een goed startpunt is een primaire journey waar snelheid conversie of dagelijks werk beïnvloedt, zoals “home naar signup”, “dashboard eerste laadbeurt na login” of “checkout en betalingsbevestiging.” Kies iets representatiefs en frequent, niet een randgeval.
Je app draait niet op je laptop. Een budget dat op een snelle machine goed lijkt, kan traag aanvoelen op een mid‑range telefoon.
Bepaal één apparaatklasse en één netwerkprofiel om mee te beginnen. Houd het simpel en schrijf het op als een zin die iedereen kan herhalen.
Bijvoorbeeld: een mid‑range Android‑telefoon van de laatste 2–3 jaar, op 4G terwijl de gebruiker onderweg is (niet kantoor‑Wi‑Fi), meetend bij een cold load en vervolgens één belangrijke navigatie, in dezelfde regio waar de meeste gebruikers zijn.
Het gaat niet om het kiezen van het slechtste geval. Het gaat om het kiezen van een veelvoorkomend geval waar je daadwerkelijk voor kunt optimaliseren.
Cijfers zijn alleen relevant als ze vergelijkbaar zijn. Als de ene run “Chrome met extensies op een MacBook” is en de volgende “gethrottled mobiel”, dan is je trend ruis.
Kies één baseline‑omgeving en houd je daaraan voor budgetchecks: dezelfde browser‑versie, dezelfde throttlinginstellingen, hetzelfde testpad en dezelfde cache‑status (cold of warm). Als je echte apparaten gebruikt, gebruik dan hetzelfde model.
Definieer vervolgens wat “snel genoeg” betekent in termen van gedrag, niet van perfecte demo’s. Bijvoorbeeld: “gebruikers kunnen snel beginnen met lezen” of “het dashboard voelt responsief na login.” Vertaal dat in één of twee metrics voor die journey en stel budgetten daaromheen in.
Budgetten werken het beste wanneer ze zowel de ervaring van gebruikers als wat teams kunnen controleren omvatten. Een goede set combineert experience‑metrics (het “voelde het snel?” deel) met resource‑ en CPU‑limieten (het “waarom werd het traag?” deel).
Deze volgen hoe de pagina zich gedraagt voor echte mensen. De meest bruikbare matchen direct met Core Web Vitals:
Timing‑budgetten zijn je noordster omdat ze overeenkomen met gebruikersfrustratie. Maar ze vertellen niet altijd wat te fixen is, dus je hebt ook de budgettypes hieronder nodig.
Deze zijn makkelijker af te dwingen in builds en reviews omdat ze concreet zijn.
Weight‑budgetten beperken zaken als totale JavaScript, totale CSS, afbeeldingsgewicht en fontgewicht. Request‑budgetten begrenzen het aantal requests en third‑party scripts, waardoor netwerkoverhead en “verrassing” door tags, widgets en trackers beperkt worden. Runtime‑budgetten limiteren long tasks, main‑thread tijd en hydration‑tijd (vooral bij React), wat vaak verklaart waarom een pagina op mid‑range telefoons “zwaar” aanvoelt.
Een praktisch React‑voorbeeld: de bundlegrootte lijkt prima, maar een nieuwe carousel voegt zware client‑side rendering toe. De pagina laadt, maar het aanraken van filters voelt stroef omdat hydration de main‑thread blokkeert. Een runtime‑budget zoals “geen long tasks boven X ms tijdens startup” of “hydration voltooid binnen Y seconden op een mid‑tier apparaat” kan dit vangen, zelfs als gewicht‑budgetten het niet doen.
De sterkste aanpak ziet dit als één systeem: experience‑budgetten definiëren succes, en grootte‑, request‑ en runtime‑budgetten houden releases eerlijk en maken het makkelijk om te antwoorden op “wat veranderde?”.
Als je te veel limieten stelt, stopt men met opletten. Kies 3–5 budgetten die overeenkomen met wat gebruikers het meest voelen en die je bij elke pull request of release kunt meten.
Een praktisch starterpakket (pas de getallen later aan):
Twee drempels houden het haalbaar. “Warn” vertelt je dat je afdrijft. “Fail” blokkeert een release of vereist expliciete goedkeuring. Dat maakt de limiet reëel zonder constante paniek.
Schrijf het budget neer op één gedeelde plek zodat niemand erover debatteert tijdens een drukke release. Houd het kort en specifiek: welke pagina’s of flows zijn gedekt, waar metingen draaien (lokale audit, CI, staged build), welk apparaat en netwerkprofiel je gebruikt, en precies hoe metrics gedefinieerd zijn (field vs lab, gzip vs raw, route‑niveau vs hele app).
Begin met een baseline die je kunt herhalen. Kies één of twee belangrijke pagina’s en test ze op hetzelfde apparaatprofiel en netwerk elke keer. Draai de test minstens drie keer en noteer de mediaan zodat één vreemde run je richting niet bepaalt.
Gebruik een simpel baseline‑blad dat zowel een gebruikersmetric als een build‑metric bevat. Bijvoorbeeld: LCP en INP voor de pagina, plus totale JavaScript‑grootte en totale afbeeldingsbytes voor de build. Dit maakt budgetten tastbaar omdat je kunt zien wat de app leverde, niet alleen wat een lab‑run schatte.
Stel budgetten iets scherper dan vandaag, niet fantasie‑getallen. Een goede vuistregel is 5–10 procent verbetering ten opzichte van je huidige mediaan op elke belangrijke metric. Als je LCP op je baseline 3,2s is, spring dan niet direct naar 2,0s. Begin met 3,0s en verscherp pas nadat je hebt bewezen dat je het kunt vasthouden.
Voeg een snelle check toe aan elke release voordat gebruikers hem zien. Houd het snel genoeg zodat mensen het niet overslaan. Een simpele versie is: draai één page‑audit op de overeengekomen pagina, fail de build als JavaScript of afbeeldingen het budget overschrijden, bewaar resultaten per commit zodat je kunt zien wanneer het veranderde, en test altijd hetzelfde URL‑patroon (geen random data).
Review overtredingen wekelijks, niet alleen wanneer iemand klaagt. Behandel een overtreding als een bug: identificeer de wijziging die het veroorzaakte, bepaal wat nu te repareren is en wat ingepland wordt. Verscherp langzaam, alleen nadat je de limiet voor een paar releases hebt vastgehouden.
Wanneer de productscope verandert, werk de budgetten doelbewust bij. Als je een nieuw analytics‑tool of een zware feature toevoegt, schrijf op wat groeide (grootte, requests, runtime), wat je zult doen om het later te compenseren en wanneer het budget weer teruggebracht moet zijn.
Een budget helpt alleen als je het snel kunt controleren. Het doel van een 10‑minuten audit is niet om een perfect nummer te bewijzen. Het is om te zien wat er sinds de laatste goede build veranderde en beslissen wat eerst te fixen.
Begin met één pagina die representatief is voor echt gebruik. Voer dan dezelfde snelle checks elke keer uit:
Twee weergaven geven meestal binnen enkele minuten antwoorden: de network waterfall en de main‑thread timeline.
In de waterfall, zoek naar één request dat het kritieke pad domineert: een gigantisch script, een blokkerend font of een afbeelding die laat start. Als de LCP‑resource niet vroeg wordt opgevraagd, kan de pagina geen LCP‑budget halen, ongeacht hoe snel de server is.
In de timeline, zoek naar long tasks (50 ms of meer). Een cluster van long tasks rond startup betekent vaak te veel JavaScript op de eerste laadbeurt. Eén enorme chunk is meestal een routing‑probleem of een gedeelde bundel die in de loop van de tijd groeide.
Snelle audits falen als elke run anders is. Leg een paar basics vast zodat veranderingen duidelijk zijn: page URL en build/version, testapparaat en netwerkprofiel, LCP‑elementbeschrijving, de kernnummers die je bijhoudt (bijv. LCP, totale JS‑bytes, request‑aantal) en een korte notitie over de grootste boosdoener.
Desktop‑testen is prima voor snelle feedback en PR‑checks. Gebruik een echt apparaat wanneer je dicht bij het budget zit, wanneer de pagina haperig aanvoelt of wanneer je gebruikers sterk mobiel zijn. Mobiele CPU’s maken long tasks duidelijk, en daar falen veel “op mijn laptop lijkt het goed” releases.
Wanneer een budget faalt, is de slechtste zet “alles optimaliseren.” Gebruik een herhaalbare triagevolgorde zodat elke fix een duidelijk resultaat heeft.
Begin met wat gebruikers het meest merken en werk daarna naar fijnere afstemming:
Een team levert een nieuw dashboard en mist plots het LCP‑budget. In plaats van eerst cache‑headers te tunen, vinden ze dat het LCP‑element een full‑width chart‑afbeelding is. Ze verkleinen deze, serveren een lichter formaat en laden alleen wat vroeg nodig is. Daarna merken ze dat een grote charting‑library op elke route laadt. Ze laden die alleen op de analytics‑pagina en stellen een third‑party support‑widget uit tot na de eerste interactie. Binnen een dag zit het dashboard weer binnen budget, en de volgende release heeft duidelijke “wat veranderde” antwoorden.
De grootste faalmode is budgetten behandelen als een eenmalig document. Budgetten werken alleen als ze makkelijk te checken zijn, moeilijk te negeren en gekoppeld aan hoe je levert.
De meeste teams lopen in een paar vallen:
Een veelvoorkomend patroon is een “kleine” feature die een nieuwe library binnenhaalt. De bundle groeit, LCP vertraagt met een seconde op tragere netwerken en niemand merkt het tot supporttickets binnenkomen. Budgetten bestaan om die verandering zichtbaar te maken bij reviewtijd.
Begin simpel en houd checks consistent. Kies 2–4 budgetten die bij de gebruikerservaring passen en verscherp ze geleidelijk. Vergrendel je testopstelling en schrijf die op. Volg ten minste één real‑user signaal indien mogelijk en gebruik lab‑tests om het “waarom” uit te leggen, niet om discussies te winnen. Wanneer een dependency merkbaar gewicht toevoegt, eis een korte notitie: wat het kost, wat het vervangt en waarom het de moeite waard is. Het belangrijkste: zet de budgetcheck op het normale releasepad.
Als budgetten voelen als constante wrijving, zijn ze meestal onrealistisch voor vandaag of niet gekoppeld aan echte beslissingen. Los die twee dingen eerst op.
Een klein team leverde een React‑analytics‑dashboard in een week. Het voelde eerst snel, maar elke vrijdagrelease maakte het wat zwaarder. Na een maand begonnen gebruikers te zeggen dat het eerste scherm “haperde” en filters traag waren.
Ze stopten met discussiëren over “snel genoeg” en schreven budgetten neer gekoppeld aan wat gebruikers merken:
De eerste overtreding kwam op twee plekken tegelijk. De initiële JS‑bundle kroop omhoog doordat charts, datum‑libraries en een UI‑kit werden toegevoegd. Tegelijk werd de dashboard‑headerafbeelding vervangen door een groter bestand “even tijdelijk”, waardoor LCP over de limiet ging. INP werd slechter omdat filterwijzigingen dure rerenders en zware berekeningen op de main‑thread veroorzaakten.
Ze losten het op in een volgorde die snel resultaat gaf en herhaling voorkwam:
Breng LCP terug onder de lijn door afbeeldingen te verkleinen en te comprimeren, expliciete afbeeldingsdimensies in te stellen en blokkerende fontloads te vermijden.
Snijd initiële JS door ongebruikte libraries te verwijderen, niet‑kritische routes te splitsen en charts lazy te loaden.
Verbeter INP door dure componenten te memoïseren, typen in filters te debouncen en zwaar werk van het hot path te verplaatsen.
Voeg een budgetcheck toe aan elke release zodat als een metric breekt, de release wacht.
Na twee releases daalde LCP van 3,4s naar 2,3s en verbeterde INP van ~350ms naar onder 180ms op hetzelfde testapparaat.
Een budget helpt alleen als mensen het steeds op dezelfde manier volgen. Houd het klein, noteer het en maak het onderdeel van leveren.
Kies een handvol metrics die bij je app passen, stel “warn vs fail” drempels in en documenteer precies hoe je test (apparaat, browser, netwerk, pagina/flow). Bewaar een baseline‑rapport van de huidige beste release en label het duidelijk. Bepaal wat een geldige uitzondering is en wat niet.
Voer voor elke release dezelfde audit uit en vergelijk met de baseline. Als iets terugvalt, log het waar je bugs bijhoudt en behandel het als een gebroken checkout‑stap, niet als een “later” taak. Als je met een uitzondering uitrolt, registreer een eigenaar en een vervaldatum (vaak 1–2 sprints). Als de uitzondering telkens verlengd wordt, moet het budget echt besproken worden.
Zet budgetten eerder in planning en schattingen: “Dit scherm voegt een chart‑library toe, dus we moeten iets anders verwijderen of het lazy‑loaden.” Als je bouwt met Koder.ai (koder.ai), kun je deze beperkingen vooraf in Planning Mode vastleggen, dan in kleinere stukjes itereren en snapshots en rollback gebruiken als een wijziging je over een limiet drijft. Het punt is niet het hulpmiddel, maar de gewoonte: elke nieuwe feature moet voor zijn gewicht betalen, anders gaat hij niet live.
Een performance‑budget is een set van harde limieten (tijd, grootte, requests, CPU‑werk) waar je team het over eens is voordat je bouwt.
Als een wijziging de limiet overschrijdt, behandel je het als een gebroken vereiste: fix het, beperk de scope of keur een uitzondering expliciet goed met een eigenaar en een vervaldatum.
Prestaties verslechteren geleidelijk. Elke feature voegt JavaScript, CSS, afbeeldingen, fonts, API‑calls en third‑party tags toe.
Budgetten stoppen die sluipende groei door een keuze af te dwingen: als je gewicht of werk toevoegt, moet je het goedmaken (lazy‑loaden, route splitsen, UI vereenvoudigen, dependency verwijderen).
Kies één echte gebruikersreis en één consistente testopstelling.
Een goed begin is iets frequents en bedrijfskritisch, zoals:
Vermijd randgevallen eerst; je wilt een flow die je bij elke release kunt meten.
Begin met één target die je typische gebruikers weerspiegelt, bijvoorbeeld:
Schrijf het op en houd het stabiel. Als je apparaat, netwerk, cache‑status of de testroute verandert, wordt je trend ruis.
Gebruik een kleine set die zowel wat gebruikers voelen als wat teams kunnen sturen dekt:
Een praktisch starterpakket is:
Gebruik twee drempels:
Dit voorkomt constante paniek maar maakt de limieten serieus als je ze overschrijdt.
Doe dit in volgorde:
Niet altijd. Bundlegrootte kan prima lijken terwijl de pagina toch traag aanvoelt omdat de main‑thread bezet is.
Veelvoorkomende React‑oorzaken:
Voeg een runtime‑budget toe (bijv. limiet op long tasks tijdens startup of een hydration‑tijdslimiet) om dit type probleem te vangen.
Snelle generatie en iteratie kan stilletjes dependencies, UI‑franje en third‑party scripts toevoegen die aan iedereen geleverd worden.
De oplossing is om budgetten onderdeel van de workflow te maken:
Dit voorkomt dat snel itereren verandert in een langzaam product.
Timing‑metrics tonen de pijn; grootte‑ en runtime‑limits helpen snel vinden wat het veroorzaakte.
Kies eerst 3–5 budgetten. Stel bij op basis van je baseline en release‑geschiedenis.
Behandel de overtreding als een bug: identificeer de commit, fix of scope‑reduce en voorkom herhaling.