Frontend

The Hidden Work Inside Your Frontend Code

By DeepCoder 5 min read
The Hidden Work Inside Your Frontend Code

Understanding the JavaScript and React performance problems that are easy to overlook 

Introduction 

When frontend developers talk about performance, the conversation usually starts with bundle size, lazy loading, image optimization, caching, and Lighthouse scores. 

A frontend application can have a small JavaScript bundle and still feel slow because performance is not only about load time but also about work performed during user interaction. 

Every search, click, scroll, drag, filter, and state update can cause additional JavaScript execution and rendering work. 

  1. JavaScript Execution Can Matter More Than Bundle Size

Bundle size matters because larger files take longer to download. But downloading JavaScript is only the beginning – it must then be parsed, compiled, and executed. 

Consider two applications: one with more JavaScript but minimal post-load work, and another with less JavaScript but heavy calculations during interaction. The second may feel slower despite smaller bundle size. 

On mobile and lower-end devices with limited CPU resources, this becomes even more critical. We should ask both: How much JavaScript are we shipping? AND How much JavaScript are we making the browser execute? 

  1. JavaScript Object Allocation and Garbage Collection

JavaScript applications constantly create objects, arrays, functions, and temporary values. The problem emerges when applications create large numbers of temporary objects repeatedly during filtering, sorting, searching, mapping, animations, and events. 

When temporary objects are no longer needed, the JavaScript engine cleans them up through garbage collection. Frequent garbage collection can increase CPU usage and contribute to UI jank. 

The lesson is not to never create objects, but to avoid unnecessary allocations in frequently executed code. 

  1. React Re-rendering IsNot the Same asDOM Updating 

A common misunderstanding: every React render updates the DOM. These are different stages. React performs rendering and reconciliation, then determines what actually needs to change in the DOM. 

Simply counting React renders doesn’t show the complete performance picture. We must investigate: Why is this component rendering? How much work does the render perform? Does the render result in actual DOM changes? 

React DevTools and browser performance tools together provide complete understanding. 

  1. Referential Equality Can Create Hidden Work

JavaScript objects and arrays are compared by reference. Two objects with identical values are still different references. This matters in React since components receive objects, arrays, and functions as props. 

This affects React.memo, useMemo, useEffect, useCallback, Redux selectors, and dependency arrays. Understanding referential equality is important but using memoization everywhere is wasteful. 

The goal is preventing unnecessary work where reference changes actually affect performance. 

  1. RenderingToo Much Data 

Large datasets cause serious frontend performance problems. Rendering thousands of records forces the browser to manage all those elements even though the user sees only a portion. 

Techniques like pagination, virtualization, server-side filtering, and incremental loading help by avoiding unnecessary browser processing of data the user doesn’t currently need. 

  1. High-Frequency Events Can Quietly Hurt Performance

Browser events like scroll, mouse movement, dragging, and touch movement happen many times per interaction. Problems arise when these events perform expensive work. 

Throttling, batching, debouncing, and requestAnimationFrame can help, but the better question is: Does this event really need to trigger this much work? Reducing work is better than just making work faster. 

  1. A Fast API Does Not Guarantee a Fast UI

An API responding in 100 milliseconds sounds fast, but the user experiences the complete chain: parse response, transform data, update state, render components, update DOM, paint interface. 

API and UI performance must be measured separately. The real metric is: How long before the user can meaningfully interact with the updated interface? 

  1. Memory Leaks in Single Page Applications

SPAs remain open for hours, making small memory leaks compound into serious problems. Repeatedly navigating while creating uncleaned event listeners, timers, WebSocket connections, and subscriptions causes memory to grow continuously. 

Common leak sources include event listeners, timers, WebSocket connections, observers, subscriptions, and global caches. Components must not continue holding unneeded resources. 

  1. Web Workers Are Still Underused

Not all calculations should run on the main UI thread. Heavy processing like JSON transformations, image processing, and mathematical calculations can interfere with user interaction when on the main thread. 

Web Workers move processing away from the main thread, useful for CAD applications, data visualization, image editors, and mapping applications. The goal is simple: keep the main thread available for the user. 

  1. Performance Should Be Measured Per Interaction

Focusing only on page-load performance is a critical mistake. Users search, filter, scroll, open menus, and navigate through applications. Each interaction triggers different amounts of work. 

Typing into a search box triggers: search logic → API request → data filtering → object creation → React rendering → DOM updates → browser rendering. If this chain is too slow, users experience typing lag. 

Measure both page-load speed and responsiveness to user actions. 

Conclusion 

Frontend performance isn’t just about reducing bundle size. It’s about understanding how much work the application performs during execution. 

Identify unnecessary work and avoid repeating it. Ask how often you make the browser execute code, not just how fast the code is. 

This perspective reveals performance problems that traditional optimization techniques miss.