Rebuilding a High-Stakes Sales App from the Ground Up

RBMSoft modernized a legacy associate-facing sales application into a fast, reliable tool capable of managing million-dollar client projects β€” without missing a beat.

Reduction in response-to-render time on high-volume operations
~ 0 %
Reduction in wait time on pricing updates for associates
~ 0 %

Zero

Browser crashes on large multi-tab projects after modernization

The Concierge App

A Mission-Critical Tool for Million-Dollar Consultations

The Concierge is a B2B sales application used by in-store associates at a luxury furniture company to manage high-value client projects β€” from first consultation through final purchase.

Associates use the app to build out a client’s project, organizing products into spaces (a balcony, a home library, a master suite), grouping spaces into opportunities, and tracking everything across a single client relationship.

When a client is standing in a gallery making million-dollar purchase decisions, the tool the associate is using can’t lag, crash, or show the wrong data.

RBMSoft modernized the platform and made it fast, reliable, and scalable for high-value customer interactions.

The Concierge App

What We Found

Four Pain Points That Couldn't Be Hidden from Clients

We didn’t start with code review. Rather we went to galleries and sat down with associates to understand the challenges they were facing with the Concierge app.

Severe Performance

Severe Performance Bottlenecks

The most consistent complaint was speed. Pages took too long to load. Updates didn’t reflect immediately. Navigating between sections of a project felt sluggish. Speed matters a lot in a live consultation but even the simplest actions such as price updates took several seconds to complete. The stop-and-wait experience poorly affected the revenue figures as well as the brand perception.

SPEED Β· LATENCY Β· RENDER TIME

High Interaction

High Interaction Friction

Associates were navigating through more steps than necessary to complete routine tasks. Adding a product, updating a configuration, moving an item between spaces. These actions happened dozens of times in a single client session. The cumulative friction was significant, and because it happened in front of clients, it couldn’t be hidden or worked around.

UX Β· WORKFLOW Β· TASK FRICTION

Browser Crashes

Browser Crashes on Large Projects

High-value clients typically have large, complex projects. Multiple spaces. Hundreds of items. The application would load all of them at once, which consumed browser resources aggressively. Associates working across multiple tabs reported frequent browser crashes and slow recovery. The bigger the project, the more fragile the experience became.

MEMORY Β· STABILITY Β· CRASHES

Stale Data Created Trust Issues

Perhaps the most damaging problem was stale data. Updates made during a session weren’t always reflected immediately. Pricing would show an old figure. A product the associate had just added might not appear. For associates quoting prices and configuring products in front of clients, showing incorrect data was a credibility problem.

DATA INTEGRITY Β· SYNC Β· TRUST

The Solution

A Two-Phase Transformation Grounded in Field Research

Our work on the Concierge happened across two phases. The first phase established the modern foundation. The second phase, informed directly by what we’d heard from associates in the galleries.

Phase One

Built the Foundation

The first phase was a migration from the legacy JSP/Servlet stack to a React single-page application. The focus was on feature parity: bringing all existing functionality into the modern architecture without regression. We also made early UI refinements and introduced the core technology layer that Phase 2 would build on: React with Material UI, a GraphQL BFF (Backend for Frontend) layer connecting to multiple microservices, and Redis caching for response time reduction.

Phase One

Made it Fast

Phase 2 was where we addressed what we’d heard in the galleries. Each change was tied directly to a problem associates had described.

1

Removed the GraphQL Layer for High-Volume Data

One of the more significant performance bottlenecks was the GraphQL processing layer. For high-volume responses involving large product lists, the GraphQL server was adding substantial processing time on top of the API response time, and the browser was then adding its own overhead on top of that. The cumulative latency meant associates were waiting far longer than the underlying API actually required. We moved high-volume endpoints from GraphQL to REST. By removing the GraphQL compression and transformation step for these calls, we cut response-to-render time by around 50% on the most data-heavy operations in the application.

2

Optimistic UI for Pricing Updates

Pricing in the Concierge cascades through multiple levels: an update at the item level affects space totals, opportunity totals, and project totals. The previous flow made an update call, waited for it to resolve, then made a GET call to fetch the refreshed project data before updating the UI. The sequential nature of this meant every pricing change had a visible delay. We introduced Optimistic UI for pricing updates. Instead of waiting for the server round-trip, the response from the update mutation is used immediately to calculate and reflect pricing changes across the project. The UI updates in real time. If the server response differs (which is rare), it reconciles. This reduced wait time on pricing interactions by approximately 40%.

3

Native Drag-and-Drop to Replace Custom Implementation

Associates frequently move items between spaces during client sessions. The existing drag-and-drop implementation was custom-built and suffered from increasing performance degradation as project size grew. Dragging items in large projects became noticeably laggy. We replaced it with the native HTML5 drag-and-drop API. The native implementation uses a lightweight ghost element instead of rendering the actual item during the drag operation, which is dramatically less expensive for the browser.

4

Windowing for Large Product Lists

The application was loading all items in a project on initial render, regardless of how many were visible on screen. For large projects this meant the browser was maintaining full DOM nodes for hundreds of items simultaneously, consuming memory aggressively and causing crashes when the application was open across multiple tabs. We implemented windowing, a technique that renders only the items currently visible in the viewport and adds or removes items as the user scrolls. Since the browser is now only maintaining a small number of active DOM nodes at any time, memory utilization dropped significantly and browser crash issues were resolved.

5

Targeted State Management with Jotai

The application had been using React’s Context API for global state management. The problem with Context at this scale is that any mutation anywhere in the tree triggers a re-render of all components consuming that context, even those unaffected by the change. In an application with complex, nested project data, this was generating substantial unnecessary rendering work. We replaced the relevant state with Jotai, a reactive state management library that only re-renders components that actually consume the changed data. The result was a significant reduction in unnecessary renders and a noticeably more responsive UI, particularly during pricing updates and configuration changes.

6

Eliminated the Heroku Intermediary Layer

The stale data problem associates had flagged came down to a specific architectural issue: data update calls were routing through three hops before resolving. The UI called the BFF layer, the BFF called a Heroku service that maintained its own copy of the data, and the Heroku service called Salesforce. This chain created redundant data copies and caching inconsistencies that caused associates to see outdated information during active sessions. We removed the Heroku layer and established a direct connection between the BFF and Salesforce.

Technology Changes

Every Decision, Every Reason

Area Technology Direction What Changed
Frontend React Retained Retained from Phase 1; refined with performance patterns
Styling Tailwind CSS Replaced MUI Build-time CSS vs. runtime CSS-in-JS β€” eliminates render overhead
State Jotai Replaced Context Targeted re-renders vs. global re-renders on every mutation
Data Fetching REST API Replaced GraphQL High-volume endpoints bypassed GraphQL β€” ~50% latency reduction
Drag & Drop Native HTML5 Replaced Custom Lightweight ghost element instead of full item render β€” zero lag
List Rendering Windowing New Renders only visible items β€” eliminated browser crashes entirely
Data Layer BFF β†’ Salesforce Direct Removed Heroku intermediary β€” resolved stale data entirely
Caching Redis + Akamai CDN Multi-layer Multi-level caching across BFF and API layers

The Outcome

The Tool Associates Never Have to Think About

The transformation changed how associates interacted with the system β€” and how clients experienced the design process.

Faster Response-to-Render

End-to-end interaction time reduced by up to 50%, eliminating multi-second delays and enabling fluid, uninterrupted client consultations.

Faster Pricing Updates

Wait time on pricing interactions dropped ~40%. One of the most frequent actions in a client session now feels immediate, with cascading updates across spaces.

Stability at Scale

With windowing and optimized rendering, the platform now handles large, multi-space projects with zero browser crashes β€” even with hundreds of items loaded across multiple tabs.

Improved Resource Utilization

Frontend optimizations β€” lazy loading, lighter rendering, reduced bundle size β€” significantly lowered memory consumption, ensuring consistent performance across all session lengths.

Ready to rethink merchandising at scale?

Let’s talk about turning a manual, error-prone process into an automated engine built for the complexity of your catalog β€” and the growth ahead.

Thanks!

We’ve sent the framework to your email. Please check inbox.

Thanks For Reaching Out!

We’re mobilizing the right person to connect with you. While we prep, come hang out on our social pages!