Modernizing Legacy Codebases: A Pragmatic Approach
Working on RNID's main website — a site serving over 1 million monthly visitors — the challenge wasn't just performance. It was doing the work carefully, without breaking critical accessibility features that real users depend on.
The Challenge
Legacy codebases come with real constraints:
- You can't rewrite everything — The site needs to keep running
- Unknown dependencies — Documentation is often incomplete or absent
- Risk aversion — Any breaking change affects real users
- Technical debt — Years of quick fixes compound into something hard to untangle
The Approach
Measure Before Touching Anything
Before making changes, understanding the current state matters. Tooling that helped:
- Lighthouse CI integrated into the pipeline
- JMeter load testing to find bottlenecks
- Monitoring to track real performance before and after changes
You can't improve what you don't measure.
Incremental Over Big-Bang
Rather than a full rewrite, the work was phased:
Phase 1: Build Pipeline
- Upgraded Gulp from v3 to v4
- Improved asset optimisation
- Cleaned up the build process
Phase 2: Dependency Updates
- Government Design System upgrade (v3 to v5)
- Node packages systematically updated
- Removed dependencies that were no longer maintained
Phase 3: Code Improvements
- Component-by-component refactoring
- Removal of legacy patterns
- Codebase clean-up to reduce maintenance burden
Accessibility Is Non-Negotiable
On a site used by people with hearing loss and related conditions, accessibility isn't optional. Every change was checked against:
- Screen reader behaviour
- Keyboard navigation
- Automated accessibility tooling
- WCAG 2.2 criteria
What Changed
Performance improved significantly — Lighthouse scores that were in the 30s moved into the 80s and 90s range. Load times dropped noticeably. The codebase became easier to maintain.
None of those outcomes were instant. They were the result of consistent, incremental improvement over several months.
Key Takeaways
1. Respect the existing system — It's running for a reason. Understand before you change.
2. Incremental is sustainable — Small improvements compound over time
3. Automate the safety net — Testing and CI makes incremental changes less risky
4. Accessibility is a feature — Not a constraint. Build for it from the start.
The goal isn't perfection — it's measurable, consistent improvement that serves real users better.
Working on legacy modernisation or performance improvement? Happy to talk through approaches.