Skip to content

About

Hands-on React performance lab exploring rendering, caching, virtualization, responsive layouts, and browser profiling.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Frontend Performance Lab

A hands-on frontend engineering lab for studying and demonstrating real-world performance patterns in React applications.

The project focuses on understanding performance bottlenecks, measuring them with browser profiling tools, and applying targeted optimizations rather than premature optimization.

Goals

This project explores how frontend performance is affected by:

  • Rendering large datasets
  • DOM size and rendering cost
  • Request frequency and debouncing
  • Server-state caching
  • Request cancellation
  • List virtualization
  • Responsive virtualization
  • Dynamic row measurement
  • Image and asset loading
  • React rendering behavior
  • Browser rendering and layout

The goal is not only to make the application faster, but to understand why a particular optimization works and what trade-offs it introduces.

Performance Cases

1. Native React Search

A baseline implementation using React state and effects.

Explores:

  • useState
  • useEffect
  • Debouncing
  • AbortController
  • Request lifecycle
  • Loading and error states

2. TanStack Query Search

The same search experience implemented with TanStack Query.

Explores:

  • Server-state management
  • Query keys
  • Caching
  • Stale data
  • Request cancellation
  • Loading and error states

3. Virtualized Product List

A large dataset containing 10,000 generated products.

The case compares:

  • Normal rendering
  • Virtualized rendering

It demonstrates why rendering thousands of DOM nodes can become expensive and how virtualization reduces the amount of DOM that needs to be rendered.

The virtualization implementation also supports:

  • Responsive column counts
  • Container-based responsive behavior
  • Dynamic row measurement
  • Variable row heights
  • Overscan

Architecture

src/
├── cases/
│   ├── native-search/
│   │   └── NativeSearch.tsx
│   ├── tanstack-search/
│   │   └── TanStackSearch.tsx
│   └── virtualization/
│       └── Virtualization.tsx
├── components/
│   ├── SearchInput.tsx
│   ├── ProductList.tsx
│   ├── ProductCard.tsx
│   └── VirtualizedProductList.tsx
├── hooks/
│   ├── useDebounce.ts
│   └── useResponsiveColumns.ts
├── lib/
│   ├── api.ts
│   └── generateProducts.ts
├── types/
│   └── product.ts
├── App.tsx
└── main.tsx

The project is intentionally organized by performance case and shared UI primitives.

Each case is isolated so different approaches can be compared without mixing their implementation details.

Tech Stack

  • React — UI library
  • TypeScript — Type safety
  • Vite — Development and build tooling
  • Tailwind CSS — Styling
  • React Router — Client-side routing
  • TanStack Query — Server-state management and caching
  • TanStack Virtual — List virtualization

Performance Principles

The lab follows a simple principle:

Measure first, optimize second.

Instead of automatically adding useMemo, useCallback, or other optimizations, each performance problem should first be identified through profiling and then addressed at the appropriate layer.

Examples:

Problem Potential solution
Too many requests Debouncing
Stale concurrent requests AbortController / request cancellation
Repeated server-state fetching TanStack Query
Too many DOM nodes Virtualization
Expensive calculations Algorithm optimization / memoization
Large JavaScript payload Code splitting / lazy loading
Large images Responsive images / modern formats
Font overhead Reduce weights / subsets
Slow initial rendering Rendering and asset optimization

Request Lifecycle

The search cases demonstrate two different approaches to managing asynchronous data.

Native React

User input
    ↓
Debounce
    ↓
Fetch request
    ↓
Abort stale request if necessary
    ↓
Loading / Error / Data

TanStack Query

User input
    ↓
Debounce
    ↓
Query key
    ↓
TanStack Query
    ├── Cache
    ├── Request lifecycle
    └── Cancellation
    ↓
Loading / Error / Data

The comparison helps demonstrate the difference between manually managing server state and using a dedicated server-state library.

Virtualization

The virtualization case uses a dataset of 10,000 products.

Normal rendering creates a DOM representation for all products:

10,000 products
      ↓
10,000 ProductCard components
      ↓
Large DOM tree
      ↓
Higher rendering / layout / painting cost

Virtualized rendering keeps only the rows around the visible viewport:

10,000 products
      ↓
Virtualizer
      ↓
Only visible + overscan rows
      ↓
Much smaller DOM tree

Responsive Virtualization

The virtualized grid determines its column count from the actual container width using ResizeObserver.

Container width
      ↓
ResizeObserver
      ↓
useResponsiveColumns
      ↓
columnCount
      ├── 2 columns
      ├── 3 columns
      └── 4 columns

The same columnCount is used for both:

  1. CSS grid layout
  2. Virtualized row calculation

This keeps the visual layout and virtualization model consistent.

Dynamic Row Measurement

The virtualizer uses an initial estimate:

estimateSize: () => 180

This is only an initial prediction.

After the row is rendered, TanStack Virtual can measure the actual DOM element through:

ref={rowVirtualizer.measureElement}

The flow is:

estimateSize
      ↓
Initial virtual layout
      ↓
Row rendered
      ↓
measureElement
      ↓
Actual DOM height
      ↓
Virtualizer updates measurements
      ↓
getTotalSize()

This allows the virtualized list to work with responsive and variable row heights without hardcoding a fixed row height.

Performance Investigation

Browser DevTools is used to investigate:

  • Network waterfalls
  • JavaScript execution
  • Rendering
  • Layout
  • Painting
  • Garbage collection
  • DOM operations
  • React rendering behavior

The investigation process follows:

Perceived slowness
        ↓
Identify the suspected bottleneck
        ↓
Measure with profiling tools
        ↓
Apply a targeted optimization
        ↓
Re-measure
        ↓
Compare the result

The goal is to understand whether the bottleneck comes from:

  • JavaScript execution
  • React rendering
  • DOM creation
  • Layout
  • Style recalculation
  • Painting
  • Network requests
  • Asset loading
  • Memory pressure

Development

Install dependencies:

npm install

Start the development server:

npm start

Or:

npm run dev

Production Build

Create a production build:

npm run build

Preview the production build locally:

npm run preview

Routes

Route Description
/ Project overview
/native-search Native React search implementation
/tanstack-search TanStack Query search implementation
/virtualization Normal vs virtualized rendering comparison

Current Status

The current lab covers:

  • React search with debouncing
  • Request cancellation with AbortController
  • TanStack Query server-state management
  • Query caching
  • Large dataset generation
  • Normal list rendering
  • List virtualization
  • Responsive virtualized grids
  • Dynamic row measurement
  • Browser performance profiling

Planned Areas

Future experiments will explore:

  • Scroll performance profiling
  • React rendering optimization
  • Image optimization
  • Font optimization
  • Code splitting
  • Lazy loading
  • Next.js performance patterns
  • next/image
  • next/font
  • Server Components vs Client Components
  • Caching and revalidation
  • Production performance analysis

Learning Approach

This repository is intentionally built as an evolving engineering lab rather than a collection of isolated snippets.

Each experiment follows:

Problem
  ↓
Baseline implementation
  ↓
Measure
  ↓
Analyze bottleneck
  ↓
Apply targeted solution
  ↓
Measure again
  ↓
Document trade-offs

The objective is to develop performance intuition and engineering judgment, not simply memorize optimization techniques.

License

For educational and portfolio purposes.

About

Hands-on React performance lab exploring rendering, caching, virtualization, responsive layouts, and browser profiling.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages