Scaling the Sidebar: How We Solved the "Recursive Crash" in CareerVivid
#performance#typescript#refactor#engineering
Scaling the Sidebar: How We Solved the "Recursive Crash" in CareerVivid Engineering a production-grade Tree Traversal Algorithm using Iterative DFS and Hash-Ma
Scaling the Sidebar: How We Solved the "Recursive Crash" in CareerVivid Engineering a production-grade Tree Traversal Algorithm using Iterative DFS and Hash-Mapped Adjacency Lists. --- In modern web applications, the Sidebar is often taken for granted. It’s a simple nested list, right? But as users scale their workflows — building massive projects with hundreds of nested folders and documents — the "simple" approach to tree management can quickly become a performance nightmare. Recently, at CareerVivid, we hit a critical scaling wall. Our recursive delete operations, while elegant in code, began crashing for our "power users" with deeply nested workspaces. Here is the story of how we refactored our core state management to move from "risky recursion" to a production-grade Iterative DFS with $O(N)$ efficiency. --- 1. The Call Stack: A Hidden Ceiling In JavaScript, every recursive function call consumes space on the Call Stack. This stack is small (typically 1MB). When you delete a folder that contains thousands of nested items, a recursive approach tries to "remember" every level of the tree on that tiny stack. The Failure Point For a user with 5,000 nested folders, this triggers the dreaded: Uncaught RangeError: Maximum call stack size exceeded --- 2. The Move to Iterative DFS To build a system that scales to millions of nodes, we replaced the Engine's call stack with the Application's heap memory. By using an explicit stack array (a simple ), we shift the burden to the RAM, which is gigabytes large rather than kilobytes. Our Production Implementation In our useSidebarStore, we implemented a robust iterative approach. We also added an Adjacency Map to ensure we aren't scanning the entire node list at every step (avoiding $O(N^2)$ slowdowns). --- 3. The Performance Dividend: $O(N^2) \to O(N)$ Algorithmic safety is only half the battle. If lookups are slow, the UI will "freeze" during deletions, even if it doesn't crash. Our original logic used .filter() inside