Bestellen & planning

Bestellen & planning

Legacy CodeAngularRxJsUXCore Web Vitals

Context

Een Angular 11-applicatie, centraal in het businessmodel van een platform voor diensten aan particulieren en professionals; zonder deze app wordt het merendeel van de bestellingen niet verwerkt.

De eerste keer dat ik het project opende, was dat een schok. Een codebase zonder documentatie, zonder betrouwbare tests, en met een technische schuld zo diep dat meerdere developers er vóór mij al op waren afgehaakt. Ik kende Angular niet. Niemand was er om het uit te leggen. Ik had kunnen kiezen om gewoon te overleven; ik koos ervoor om te begrijpen.

Uiteindelijk heb ik dit project volledig eigen gemaakt, alleen, gedurende bijna 2 jaar.

Technische schuld

Structurele technische schuld

  • 🍝 "Spaghetti"-codebase: verspreide en verweven logica (bijwerkingen die moeilijk te voorspellen zijn bij elke wijziging)
  • ⚠️ Instabiele interne afhankelijkheden, te fundamenteel om op te schonen zonder het geheel te destabiliseren
  • 🔀 Vermenging van businesslogica frontend & backend: geen duidelijke scheiding van verantwoordelijkheden

De symptomen

  • 📦 De hoofd JavaScript-bundle was enorm (15MB!), wat leidde tot extreem lange laadtijden op minder krachtige toestellen en netwerken, voor een applicatie die direct impact had op de omzet
  • ⏳ Ontwikkeltijd die bij elke wijziging sterk toenam
  • 💥 Groot risico op bugs en regressies

Ik leerde al snel dat je zo’n applicatie niet in één keer refactort. Je werkt per zone, je beveiligt wat je aanraakt, je documenteert wat je begrijpt, en je gaat stap voor stap vooruit.

Performance-optimalisatie

Tussen twee sprints door identificeerde ik een grote opportuniteit voor verbetering en stelde ik voor om dit prioriteit te geven.

De belangrijkste oorzaak van de traagheid was de grootte van de initiële bundle: de volledige applicatie werd bij het opstarten geladen, ongeacht welke pagina werd bezocht.

Daarom focuste ik eerst op wat de meeste impact had: lazy-loading van modules per pagina, zodat alleen relevante code wordt geladen:

  • ✂️ Herstructurering en lazy-loading van modules: elke pagina kreeg een eigen module, die pas geladen wordt bij navigatie

  • 🧼 Opschonen van de root module: niet-structurele afhankelijkheden verwijderd of verplaatst naar de modules waar ze effectief nodig waren

    ⚠️ Gevoelige operatie

    In deze Angular-versie kan het verplaatsen van een dependency zonder elke referentie manueel te controleren leiden tot het verdwijnen van bestaand gedrag, zonder foutmelding.

We gingen hier van 15 naar 5.59MB, wat nog steeds niet voldoende was.

Andere optimalisaties volgden:

  • 🧹 Opschonen van een gedeelde module
  • 🗑️ Verwijderen van dode code
  • ⚡ Optimalisatie van het timing van netwerkrequests

Eindresultaat

  • Reductie van 88% van de hoofd-bundle
  • ✅ Lighthouse-score van ~34 naar ~78, met een winst van 13,2 seconden op de LCP
  • ✅ Businesslogica ongewijzigd en 0 regressies

Voor een strategische applicatie, waar elke seconde laadtijd een directe impact heeft op de conversie, is dit niet alleen een technische verbetering maar een echte business-impact.

Voor optimalisatieLighthouse-score vóór optimalisatie
Na optimalisatieNa optimalisatie: + ~130% verbetering

Herwerking van de klantenzone

Op vraag van de product owner leidde ik de herwerking van de klantenzone: een functioneel maar verwarrend onderdeel dat leidde tot onnodige supportcalls.

De doelstellingen waren drieledig:

  • 🧠 UX verduidelijken: de interface opnieuw ontwerpen zodat ze de businessdata correct weerspiegelt en de gebruiker duidelijk naar de juiste actie leidt
  • 📞 Supportdruk verlagen: minder inkomende vragen die de interface zelf zou moeten beantwoorden
  • 🎨 UI moderniseren: duidelijker, consistenter en aangenamer in gebruik

Aanpak en uitvoering

Dit project bracht me ertoe om:

  • 👥 Rechtstreeks samen te werken met niet-technische stakeholders om feedback uit het veld te verzamelen
  • 📊 Designbeslissingen te nemen op basis van gedragsdata via Hotjar
  • 🧬 Volledige backward compatibility te garanderen: bestaand gedrag in kaart brengen in een complexe en ongedocumenteerde codebase
  • 🛫 Gefaseerd te migreren: gecontroleerde rollout (A/B testing via feature flags) om adoptie te valideren via analytics
Klantenzone (voor)

In v1 werd de orderopvolging in één monolithische view getoond: globale status, lijst van diensten en acties (betaling, planning) stonden samen zonder duidelijke hiërarchie. De gebruiker moest zelf interpreteren wat de status was en wat hij moest doen, wat leidde tot verwarring en supportcalls.

Klantenzone (na): order viewKlantenzone (na): service view

In v2 is er een duidelijke scheiding tussen de bestelling en de afzonderlijke diensten. De orderview (beeld 1) geeft een overzicht: details, totaalbedrag en een tabel met per dienst de status en volgende actie. Klikken op een dienst opent een aparte pagina (beeld 2) met een stapsgewijze flow. De gebruiker weet altijd waar hij staat en wat hij moet doen.

Creatie & planning: een uniforme workflow

Het ticket leek te gaan over een planningsfeature: producten selecteren, beschikbaarheden tonen, een tijdslot boeken. Drie stappen, één scherm.

Maar bij analyse van de afhankelijkheden werd duidelijk wat ontbrak: een planning vereist een bestaande bestelling. Het ging eigenlijk om een volledig module dat opnieuw opgebouwd moest worden.

Ik heb het echte scope gecommuniceerd en het volledige geheel opgeleverd: een geïntegreerde workflow, van service-selectie met prijsberekening tot bevestiging van tijdsloten per dienst in één agenda, zonder de technische schuld van de bestaande modules.

Dit alles met een nette co-existentie met het oude bestelsysteem, zonder regressies.

Nieuwe bestel- en planningsflow

Dit module is vandaag een functionele herimplementatie van het hoofd-bestelformulier. Het is enkel beschikbaar voor een beperkte gebruikersgroep (business constraint), maar de architectuur is gezond en uitbreidbaar.

Documentatie & overdracht

Als enige maintainer van een complexe applicatie draag je een vaak onzichtbare verantwoordelijkheid: code leeft langer dan zijn auteurs. In dit project was dat extra duidelijk: kennis was verdwenen door personeelsverloop. Dat wilde ik niet herhalen.

Ik heb een uitgebreide documentatie geschreven (functioneel en technisch), inclusief architectuur, businesslogica, risicozones en beslissingen. Een maand werk, parallel met development.

Bij mijn vertrek heb ik mijn opvolger ingewerkt zodat hij niet van nul moest starten.

Conclusie

Bijna 2 jaar op een applicatie die niemand wilde aanraken. Dit project leerde me werken onder beperkingen, impact boven perfectie te plaatsen, en te leveren in een context waar elke technische beslissing directe businessgevolgen had.

Wat ik meeneem:

  • Angular en RxJS leren in productie
  • 🛠️ Volledige verantwoordelijkheid en ownership over een strategische applicatie
  • 🧠 Genoeg afstand om de impact van mijn eigen beslissingen op maintainability te begrijpen en daaruit te leren