Optimizing a React Progress Bar Component: From Inefficient Implementation to GPU‑Accelerated Performance
This article examines a common React progress‑bar component, explains why the naïve timer‑based implementation causes heavy reflows and repaints, and presents a GPU‑accelerated CSS animation solution that dramatically improves frame rates and reduces layout work.
In the introduction the author, a front‑end developer, shares a progress‑bar component he found in a project and points out that, while functionally correct, it suffers from serious performance problems caused by frequent state updates.
The component is typically used in video‑playback scenarios (e.g., TikTok‑style short videos) where the bar must grow with the video length and pause when the video is paused.
Problematic implementation (React + timer)
// index.jsx
import { useState } from 'react';
import './index.css';
let timer = null; // timer that increments progress
let totalTime = 3000; // assume video length is 3 s
function App() {
const [progress, setProgress] = useState(0); // progress
const [isPlay, setIsPlay] = useState(false); // playing flag
const handlerProgress = pre => {
if (pre < 100) return pre + 1;
else {
alert('播放结束');
return 0; // restart after finish
}
};
const handleVideo = () => {
setIsPlay(!isPlay);
isPlay ? clearInterval(timer) : timer = setInterval(() => setProgress(handlerProgress), totalTime / 100);
};
const replay = () => {
setIsPlay(true);
if (timer) clearInterval(timer);
setProgress(0);
timer = setInterval(() => setProgress(handlerProgress), totalTime / 100);
};
return (
{ isPlay ? '暂停' : '播放' }
重播
);
}The CSS for the above version simply defines a container and a red bar whose width is updated via the progress state, causing the browser to recalculate layout on every tick, which leads to noticeable jank.
Why this approach is slow
Each change to progress triggers a React re‑render, which updates the width style of the bar. Changing width forces the browser to perform layout (reflow) and paint (repaint) on every frame, resulting in heavy CPU usage and low FPS.
Recommended implementation (CSS animation + GPU acceleration)
// index.jsx
import { useState } from 'react';
import './index.css';
let totalTime = 3000; // 3 s video
function App() {
const [isPlay, setIsPlay] = useState(false);
const [count, setCount] = useState(0);
const [type, setType] = useState(0); // 0: play, 1: replay
const handleVideo = () => setIsPlay(!isPlay);
const replay = () => {
setIsPlay(true);
setType(type ? 0 : 1);
};
const end = () => {
setCount(count + 1);
replay();
};
return (
{ isPlay ? '暂停' : '播放' }
重播
{ `播放次数为:${count}` }
);
}The accompanying CSS uses two @keyframes (play and replay) that animate the transform property instead of width . By animating scaleX and translateX , the browser can off‑load the work to the GPU, avoiding layout thrashing.
@keyframes play {
0% { transform: translateX(-50%) scaleX(0); }
to { transform: translateX(0) scaleX(1); }
}
@keyframes replay {
0% { transform: translateX(-50%) scaleX(0); }
to { transform: translateX(0) scaleX(1); }
}
.container {
height: 10px;
border-radius: 5px;
border: 1px solid black;
}
.progress {
height: 100%;
width: 100%; /* start at full width, then scale */
background-color: red;
will-change: transform;
animation-timing-function: linear;
}
.progress.play { animation-play-state: running; }
.progress.pause { animation-play-state: paused; }Because the animation only modifies transform , the browser creates a separate compositing layer for the bar, eliminating most reflows and repaints. The author validates the improvement with Chrome DevTools Performance, showing a reduction of layout work and a stable FPS of 55‑70 compared to 32‑50 for the timer‑based version.
In real‑world projects with more complex pages, the same technique can yield performance gains well beyond the 40‑54 % measured on this minimal demo.
Finally, the article includes a “small easter egg” showing how to inspect the new GPU layer using Chrome DevTools Layers, confirming that the progress bar is now rendered on its own layer.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.