Technical note
From 4s to 1.5s on internal banking apps
What we measured and changed at Santander Consumer to cut load times ~62% on React/Next.js apps handling 600+ daily operations.
By the numbers
600+
Ops / day
−62%
Load time
4s → 1.5s
Approx. LCP
100%
TypeScript
Real context
At Santander Consumer I work on internal platforms: insurance, assistance, and banking systems used daily by operators and customers. These aren't marketing landings — long forms, paginated tables, validations, and multiple REST calls. When a screen takes 4 seconds to become usable, the cost isn't just UX: it slows operations and creates support rework.
Measure before optimizing
First step was agreeing what to measure: Lighthouse in CI, Web Vitals in staging, and manual review of the top 5 traffic screens. We found three repeating patterns: oversized first-load bundles, sequential fetch waterfalls on mount, and heavy components rendered even when not visible.
Changes that actually moved the needle
We applied lazy loading for routes and secondary modules, moved data fetching to server components/loaders where the stack allowed, and parallelized independent client requests. For large tables: server-side pagination and skeletons instead of blocking the whole view. Nothing exotic — but applied consistently on critical flows.
// Before: waterfall on dashboard mount
const customer = await fetchCustomer(id);
const policies = await fetchPolicies(id);
const claims = await fetchClaims(id);
// After: independent requests in parallel
const [customer, policies, claims] = await Promise.all([
fetchCustomer(id),
fetchPolicies(id),
fetchClaims(id),
]);Quality in a regulated environment
In banking, fast isn't enough: TDD on business logic, PRs with strict typecheck, and CI/CD pipelines with Git. We also work with Docker/Kubernetes in a microservices architecture and event-driven flows with serverless functions (AWS Lambda) for certain processes. Performance and maintainability go together when deploys are frequent.
Outcome
We went from ~4s to ~1.5s on target screens (~62% improvement). The most valuable change wasn't a one-off trick but repeating the same checklist on every new feature: measure, trim bundle, parallelize IO, validate in staging with real data.
Takeaways
- Measure on high-traffic screens, not global averages
- Parallelize independent fetches before micro-optimizing CSS
- Lazy-load routes and secondary modules on heavy internal apps
- CI/CD + strict TypeScript prevents performance regressions
- ~62% faster load with incremental changes, not a rewrite