Back to technical notes
8 min

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.

TypeScript · parallel fetch
// 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
ReactNext.jsPerformanceBankingTypeScript