React · Case Study
React Healthcare Dashboard: Fixing a Slow Patient Operations Platform Without Disrupting Care Teams
A full production-style case study showing how a healthcare SaaS company improved React dashboard performance, reduced rendering delays, fixed slow patient search, stabilized real-time updates, and rebuilt front-end architecture without a complete rewrite.
ClientCarePulse
IndustryHealthcare Technology
Project typeReact Dashboard Performance Optimization and Front-End Architecture Refactoring
Duration15 weeks
Overview
Project: React Dashboard Performance Optimization and Front-End Architecture Refactoring
Duration: 15 weeks
CarePulse provides a healthcare operations dashboard used by clinics, outpatient centers, and care coordination teams to manage patient queues, appointments, lab status, provider availability, alerts, and follow-up tasks. The platform started as a simple admin panel but gradually became a complex real-time workspace. Over time, the React application gained patient search, live queue updates, notification panels, appointment timelines, insurance verification widgets, role-based access, audit logs, and reporting dashboards. The feature growth helped the business, but the front-end became increasingly slow. Care teams reported that patient search lagged, tables froze during updates, notification panels caused delays, and appointment pages took too long to become usable on older clinic hardware.
The core problem
The dashboard had become overloaded with client-side rendering and broad shared state. Real-time updates triggered unnecessary re-renders across large tables, patient cards, alert panels, and navigation components. Patient search ran too much synchronous work on the main thread, large dashboards loaded every widget upfront, and real-time data streams updated UI sections that were not visible to the user. The result was a platform that looked complete but often felt delayed during critical workflows.
Issues we addressed
Business signals
- Clinic staff reported delays while searching for patients during busy hours.
- Care coordinators lost confidence in live queue updates because the interface sometimes froze.
- Support tickets increased around dashboard slowness and delayed notifications.
- Larger clinic customers hesitated to expand usage because performance varied by device.
- Product teams were afraid to add new dashboard widgets because each feature increased page weight.
- Implementation teams needed extra training time to explain workarounds for slow screens.
- Customer success teams had difficulty proving whether performance complaints were fixed after releases.
- Engineering teams spent too much time debugging repeated rendering problems.
Technical signals
- Patient lists rendered hundreds of rows at once.
- Real-time WebSocket updates caused broad React re-render cascades.
- Global Context providers stored too much unrelated dashboard state.
- Patient search performed expensive filtering synchronously.
- Large reporting widgets loaded on dashboard routes even when hidden below the fold.
- Notification panels recalculated unread counts too frequently.
- Audit log components loaded heavy table utilities on routes that did not need them.
- Role-based navigation recalculated permissions on every route transition.
- Appointment timelines rendered too many historical events by default.
- Charts and reporting libraries increased initial JavaScript payload.
- Some API polling continued even when tabs or panels were not visible.
- Loading skeletons did not reserve consistent space, causing layout shifts.
- The team lacked route-level performance budgets.
Baseline & measurement
Metrics C L S: 0.16 on patient detail pages
I N P: 468ms at p75 on patient search and queue pages
L C P: 4.6s at p75 on dashboard landing routes
Table Render Count: Hundreds of rows rendered during initial load
Patient Search Delay: 420ms to 900ms depending on patient list size
Average Hydration Time: 3.2s on shared clinic workstations
Queue Update Render Cost: Large sections of the dashboard re-rendered after each live update
Notification Panel Delay: Unread counts and alert lists lagged during peak usage
Initial Java Script Payload: 970KB compressed on operations dashboard
Pages Measured
- Main operations dashboard
- Patient search
- Appointment queue
- Patient detail page
- Care task board
- Notifications panel
- Reporting dashboard
- Audit log
Primary Audience: Clinic staff using mid-range Windows desktops, older tablets, and shared workstation browsers
Measurement Window: 30 days before optimization
Discovery & diagnosis
The team started by identifying whether slowdowns came from backend APIs, real-time streams, or the React front end. Measurements showed that many delays happened after data had already arrived, meaning the browser was spending too much time rendering, hydrating, recalculating derived state, and processing updates.
What we inspected
-
Title: Workflow-based monitoring setup
Description: The team added performance tracking around patient search, queue updates, appointment selection, notification opening, and task board interactions. This made it possible to measure the workflows that clinic staff used most often.
-
Title: React Profiler investigation
Description: Profiling showed that WebSocket updates caused unrelated components to re-render together. Patient tables, queue summaries, sidebar navigation, notification badges, and reporting cards were updating more often than necessary.
-
Title: Bundle analysis
Description: The bundle report showed that charts, audit table utilities, date formatting libraries, and reporting widgets were included in dashboard routes even when users did not open those sections.
-
Title: Real-time update tracing
Description: The team reviewed how live updates moved through the application. Many updates were stored in broad providers, which forced large parts of the interface to process changes even when only one patient row needed to update.
-
Title: Search interaction review
Description: Patient search was analyzed with browser traces. Expensive filtering, sorting, highlighting, and permission checks were running synchronously during typing, which caused visible input delay.
The challenge
The main challenge was improving performance without interrupting daily clinical operations. The platform was used during active care workflows, so the team could not take major modules offline or risk unstable releases. The application also handled sensitive healthcare data, so every architectural change had to preserve security, auditability, and role-based access rules. CarePulse needed faster patient lookup, smoother dashboards, more predictable real-time updates, and better maintainability without replacing the existing React stack.
Approach
The solution focused on reducing unnecessary rendering work and making the dashboard respond faster during real clinical workflows. The team kept React but changed how data updates flowed through the application, how tables rendered, how search executed, and how heavy widgets loaded.
Strategy
- Reduce initial JavaScript on dashboard routes.
- Virtualize patient tables and queue lists.
- Move real-time updates closer to affected components.
- Split large Context providers into focused state boundaries.
- Defer non-critical widgets and reporting modules.
- Make patient search responsive during typing.
- Pause hidden polling and invisible subscriptions.
- Stabilize layout for patient details and alerts.
- Use profiling data instead of guessing.
- Add performance budgets and workflow-level monitoring.
Implementation playbook
Phase1 Title: Dashboard route cleanup
Actions
- Split the main dashboard into critical and non-critical sections.
- Delayed reporting widgets below the fold.
- Moved audit log utilities out of the default operations bundle.
- Lazy-loaded chart libraries only on reporting routes.
- Added Suspense boundaries around non-critical dashboard panels.
- Reduced client-side rendering for static help text and role descriptions.
- Removed unused dashboard widgets from default layouts.
Description: The team separated operational dashboards from reporting-heavy routes. Clinical workflows loaded first, while analytics and secondary widgets were delayed until needed.
Phase2 Title: Patient table virtualization
Actions
- Virtualized patient search results.
- Virtualized appointment queue rows.
- Reduced DOM complexity inside patient table rows.
- Moved secondary patient metadata behind expandable sections.
- Reserved space for status badges and priority labels.
- Lazy-rendered row actions until hover or focus.
- Reduced expensive date and status formatting inside each row.
Description: Large patient and appointment tables were one of the biggest rendering costs. The team changed these views so only visible rows rendered.
Phase3 Title: Real-time update isolation
Actions
- Split queue, notification, patient detail, and task board state into separate stores.
- Updated individual patient rows instead of replacing entire lists.
- Used memoized selectors for queue counts and status summaries.
- Ignored invisible panel updates until panels became active.
- Batched rapid WebSocket updates during peak usage.
- Reduced unnecessary notification badge recalculations.
- Separated urgent clinical alerts from lower-priority dashboard updates.
Description: The original WebSocket update flow pushed too much data into broad shared state. The team redesigned update handling so only affected UI sections responded.
Phase4 Title: Patient search responsiveness
Actions
- Kept input typing responsive before result recalculation.
- Debounced search result updates for rapid typing.
- Moved expensive highlighting logic out of the critical input path.
- Cached recent patient search results.
- Precomputed normalized searchable fields where possible.
- Reduced permission checks during repeated search input.
- Displayed immediate loading feedback for slow result sets.
Description: Search needed to feel immediate because staff used it constantly. The team reduced synchronous work during typing and separated immediate input feedback from slower result updates.
Phase5 Title: State management refactor
Actions
- Split global providers into smaller focused providers.
- Moved tab and panel state into local route components.
- Separated user permissions from frequently changing queue data.
- Stabilized function references passed to table rows.
- Memoized derived dashboard summaries.
- Removed wrapper components that added render depth without value.
- Used React.memo only where profiling showed measurable benefit.
Description: The dashboard originally used large providers that mixed user session, permissions, live queues, notifications, filters, and UI preferences. The team separated state by ownership and update frequency.
Phase6 Title: Hidden work reduction
Actions
- Paused polling for hidden tabs.
- Stopped refreshing reporting cards when the reporting panel was closed.
- Deferred notification detail loading until the panel opened.
- Reduced background recalculation of unread alert groups.
- Delayed timeline history rendering until users expanded older events.
- Stopped loading full audit records on non-audit routes.
- Reduced background refetching during active typing and form entry.
Description: Several parts of the dashboard continued polling, recalculating, or rendering even when users could not see them.
Phase7 Title: Layout stability and perceived speed
Actions
- Reserved space for patient status badges.
- Standardized loading skeleton heights for detail panels.
- Prevented alert banners from pushing content after load.
- Kept queue row heights consistent during status changes.
- Prioritized above-the-fold dashboard content.
- Reduced late layout changes after appointment data loaded.
- Improved empty states and partial loading states.
Description: The team improved visual stability so the interface felt more predictable during loading and real-time updates.
Phase8 Title: Performance governance
Actions
- Added route-level JavaScript budgets.
- Tracked patient search delay as a product metric.
- Tracked queue update render cost after releases.
- Added pull request bundle reports.
- Created ownership rules for heavy dashboard widgets.
- Added performance review for new real-time features.
- Created dashboards for INP, LCP, hydration time, and long tasks.
Description: To prevent regression, performance checks became part of the release process.
Results
- INP improved from 468ms to 174ms at p75 on patient search and queue pages.
- LCP improved from 4.6s to 2.3s at p75 on dashboard landing routes.
- CLS improved from 0.16 to 0.04 on patient detail pages.
- Initial JavaScript payload on the operations dashboard dropped from 970KB to 384KB compressed.
- Average hydration time on shared clinic workstations dropped from 3.2s to 1.3s.
- Patient search delay dropped from 420-900ms to mostly under 150ms.
- Queue updates no longer caused full dashboard re-render cascades.
- Large patient tables became smooth because only visible rows rendered.
- Notification panels opened faster during peak clinic hours.
- Reporting libraries were removed from the default operations route bundle.
- Hidden tabs stopped consuming unnecessary polling and rendering work.
- Performance regressions became easier to catch before release.
- Clinic staff reported that patient lookup and queue management felt more reliable.
Business impact
The optimization improved the daily experience for care teams and reduced operational friction for clinic customers. Faster search, smoother queue updates, and more stable dashboards made the platform feel more dependable during busy clinical workflows.
Outcomes
- Faster patient lookup during front-desk and care coordination workflows.
- Fewer support complaints about frozen dashboards.
- Improved confidence in live queue updates.
- Better usability on older shared clinic workstations.
- Reduced training burden for implementation teams.
- More confidence for product teams adding new dashboard widgets.
- Clearer engineering visibility into performance regressions.
- Stronger customer trust during high-volume clinic hours.
Before & after
| Area | Before | After |
|---|---|---|
| User Experience | The dashboard showed the right information, but it often felt delayed. Patient search lagged, queue updates caused freezing, notification panels opened slowly, and large tables were difficult to use on older devices. | Patient search responded quickly, queue updates felt smoother, dashboards loaded faster, and appointment pages stayed visually stable. Staff could complete routine workflows without waiting for hidden widgets or unrelated panels to finish loading. |
| Business Experience | The product had strong functionality, but performance issues reduced customer confidence. Larger clinics worried that the system would slow down during peak usage. | CarePulse could support larger clinics and more complex workflows without turning every new dashboard feature into a performance risk. |
| Engineering Experience | Developers had difficulty tracing performance problems because updates moved through broad shared state. Real-time data, permissions, notifications, and UI preferences were too tightly connected. | The React architecture became easier to maintain. State ownership was clearer, real-time updates were isolated, large tables were virtualized, and performance was measurable during releases. |
Engineering decisions
-
Do not rebuild the platform from scratch.
A rewrite would have introduced risk to active clinical workflows. Targeted optimization solved the biggest bottlenecks faster and more safely.
-
Virtualize patient and appointment tables.
Rendering hundreds of rows upfront created unnecessary DOM work and slowed critical workflows.
-
Isolate real-time updates.
WebSocket events should update only affected UI sections, not the entire dashboard.
-
Split broad Context providers.
Mixing high-frequency queue updates with stable user and permission data caused avoidable render cascades.
-
Delay reporting modules.
Charts and analytics widgets were valuable but did not need to load before operational workflows became usable.
-
Track workflow-level performance.
Generic page metrics were not enough. The team needed to measure patient search, queue updates, and notification opening directly.
Lessons learned
- Real-time React dashboards need strict update boundaries.
- Large tables should be virtualized before they become a daily usability problem.
- Broad shared state is dangerous when some data updates frequently.
- Patient search performance depends on both backend speed and browser responsiveness.
- Hidden panels should not keep polling or rendering as if they are visible.
- Charting and reporting libraries should not load on operational routes by default.
- A dashboard can look loaded while still being unresponsive.
- Performance metrics should match real user workflows.
- Targeted refactoring is often safer than a full rewrite for mission-critical software.
- Performance governance is necessary because dashboard complexity grows gradually.
Role: Director of Product Engineering
Quote: The improvement was practical and immediate. Our care teams did not need a redesigned product; they needed the existing workflows to respond faster and more reliably. The team fixed the real bottlenecks without putting daily operations at risk.
Person: Maya Chen
Company: CarePulse
Summary
CarePulse's React optimization project showed that a complex healthcare operations dashboard can become significantly faster without a full rewrite. By reducing JavaScript, virtualizing large tables, isolating real-time updates, improving patient search responsiveness, delaying non-critical reporting modules, and adding performance governance, the team transformed a slow dashboard into a more reliable clinical workspace. The result was faster patient lookup, smoother queue management, better usability on older devices, and a React architecture that could support future healthcare workflows with less performance risk.
About the Author
Author icon By Eugen B.
- ✓ Verified Expert
Experience icon 6 years of experience
My name is Eugen B. and I have over 6 years of experience in the tech industry. I specialize in the following technologies: Golang, Rust, PostgreSQL, Kubernetes, TypeScript, etc.. I hold a degree in Bachelor of Science (BS). Some of the notable projects I’ve worked on include: Custom Checkout Flow for WooCommerce Backend (WordPress), Custom WordPress Plugin for Client's SaaS, My portfolio landing page, WordPress Plugin - fullstack development, Shop for a WordPress plugin, etc.. I am based in Hoechst im Odenwald, Germany. I've successfully completed 8 projects while developing at Softaims.
My expertise lies in deeply understanding and optimizing solution performance. I have a proven ability to profile systems, analyze data access methods, and implement caching strategies that dramatically reduce latency and improve responsiveness under load. I turn slow systems into high-speed performers.
I focus on writing highly efficient, clean, and well-documented code that minimizes resource consumption without sacrificing functionality. This dedication to efficiency is how I contribute measurable value to Softaims’ clients by reducing infrastructure costs and improving user satisfaction.
I approach every project with a critical eye for potential bottlenecks, proactively designing systems that are efficient from the ground up. I am committed to delivering software that sets the standard for speed and reliability.
