How We Optimized React for Mobile: Lessons from HandQ School Group Refactor

This article details the challenges and solutions encountered while refactoring the HandQ school‑group web app with React, covering React's core features, performance pitfalls, the use of Immutable.js and pure‑render decorators, build‑tool choices, and concrete optimization tips that yielded measurable speed gains.

21CTO
21CTO
21CTO
How We Optimized React for Mobile: Lessons from HandQ School Group Refactor

In the last quarter we rebuilt the HandQ school‑group pages using React, replacing the previous problematic framework. React was chosen for three main reasons: "Learn once, write anywhere", the Virtual DOM, and component‑based architecture.

React Features

1. Learn once, write anywhere – After learning React you can develop web, server‑rendered, and native applications, choosing ReactJS for lightweight needs, React Server Render for faster first‑paint, or React Native for performance‑critical scenarios. However, the learning curve is steep; Webpack + React + Redux already challenge newcomers, let alone handling both web and mobile outputs.

2. Virtual DOM – Facebook claims the Virtual DOM gives good performance, but only when proper optimization techniques are applied.

3. Componentization – React promotes clearer code organization and easier maintenance, though this becomes apparent after overcoming initial pitfalls and mastering the React + Redux coding conventions.

Expectations vs Reality

Beginners often expect React to outperform all other frameworks, even native rendering, but the official documentation notes that React aims to match non‑React performance, not exceed it. First‑render speed may be slower, but interaction can be faster if redundant renders are avoided.

First‑paint may be slower than native; consider React Server Render (Isomorphic) to improve it.

Interactive response can be faster if you prevent unnecessary re‑renders.

HandQ School‑Group Refactor Example

The feature consists of three pages: list, assignment, and detail. The list page is completed and released, the assignment page is ready for testing, and the detail page is under reconstruction. We also completed isomorphic server‑render optimization for the list page and prepared React Native optimizations.

Before the mobile refactor we had a PC version built with the typical React stack:

Build tools: gulp + webpack

Development efficiency: redux‑dev‑tools + hot‑reload

State management: redux

Performance: immutable + pureRender

Routing: react‑router (not used in HandQ)

Build‑time Optimizations

We wrote a separate article on webpack optimization for React; the key point is that a solid build setup is essential for performance.

Development‑time Tools

On PC we use Redux‑DevTools to inspect actions and state changes. Because mobile screens are small, the dev‑tools panel is placed at the bottom and can be toggled via a debug flag to avoid rendering overhead.

Data Management and Performance

Redux unified data management – React solves duplicate rendering with the Virtual DOM, but the diff algorithm needs immutable data to work efficiently. We therefore adopted Redux together with Immutable.js, which provides immutable structures and fast equality checks via Immutable.is(). This allows shouldComponentUpdate to compare prevProps/prevState with nextProps/nextState directly.

We created a pure‑render decorator that uses Immutable.js for deep comparison, and we rewrote reducers to use Immutable APIs.

When using shouldComponentUpdate, we bind methods in the constructor, avoid binding in render, and pass only the props a component truly needs.

Immutable.js as a Performance Savior

Immutable.js generates immutable data, eliminating manual deep copies and providing Immutable.is() for fast comparisons. By integrating it into shouldComponentUpdate, we reduced repeated renders that caused noticeable jank on mobile.

However, large Immutable.js bundles (≈50 KB) can hurt mobile load time. Alternatives like seamless‑immutable (~2 KB) exist for simpler use cases.

Deep Compare Implementation

Our deep‑compare strategy focuses on two points:

Flatten incoming data as much as possible.

Limit recursion depth to avoid stack overflow.

We also ignore internal React fields such as $$typeof, _store, _self, _source, and _owner during comparison to keep it lightweight.

Component Props and Children

Passing whole components as props is flexible but costly; we switched to wrapping children via this.props.children and let each child decide its own rendering, reducing parent‑side work.

Routing and Code Splitting

For larger SPAs we need routing and bundle splitting. Although we initially avoided react‑router due to bundle size, we later used require.ensure to load floating‑layer components on demand, keeping the initial bundle small.

Performance Metrics

First‑screen interactive time improved from 18 % to 5.3 % after optimization. (Charts omitted for brevity.)

React Performance Checklist

Use immutable data structures for props, state, and store.

Combine pure‑render decorators with Immutable.js.

Avoid excessive setState calls.

Do not pass components as props unless necessary.

Bind methods in the constructor.

Pass only required props; avoid spread attributes.

Assign unique keys to list items to guarantee re‑rendering.

Prefer const elements for static components.

Tap Events

For simple tap handling use react‑tap‑event‑plugin; for complex gestures (long tap, swipe) we built a custom tap component.

Debug Tips

On mobile, limit use of Redux‑DevTools to prevent jank.

Avoid inline‑source‑map in production builds.

Other Considerations

Be cautious with very new ES6 features; polyfills like object‑assign may be needed on older devices.

Source: compiled from various internal notes and public React documentation.

frontend developmentReduxReActImmutable.js
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.