Using inline styles in React can negatively impact performance in several ways, particularly by causing unnecessary re-renders and preventing browser optimizations that CSS classes enable.
Why Inline Styles Hurt Performance
- New object references on each render:
// Creates new object every render
<div style={{ color: 'red', padding: '10px' }} />
- Prevents CSSOM optimizations that browsers do with regular CSS
- Forces style recalculations instead of reusing class definitions
- Increases bundle size with repetitive style definitions
Better Approaches
1. Use CSS/SASS/LESS Classes
// styles.css
.my-component {
color: red;
padding: 10px;
}
// Component.jsx
import './styles.css';
function Component() {
return <div className="my-component" />;
}
2. CSS Modules for Scoped Styles
// Component.module.css
.container {
color: red;
padding: 10px;
}
// Component.jsx
import styles from './Component.module.css';
function Component() {
return <div className={styles.container} />;
}
3. Styled Components (CSS-in-JS)
import styled from 'styled-components';
const StyledDiv = styled.div`
color: red;
padding: 10px;
`;
function Component() {
return <StyledDiv />;
}
4. Emotion (CSS-in-JS with Better Performance)
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
const style = css`
color: red;
padding: 10px;
`;
function Component() {
return <div css={style} />;
}
5. For Dynamic Styles: Combine Classes with Inline
// styles.css
.base {
padding: 10px;
font-size: 16px;
}
.primary {
color: blue;
}
.warning {
color: orange;
}
// Component.jsx
function Component({ variant }) {
const variantClass = variant === 'warning' ? 'warning' : 'primary';
return <div className={`base ${variantClass}`} />;
}
When Inline Styles Are Acceptable
- Truly dynamic styles that change frequently:
function Draggable() {
const [position, setPosition] = useState({ x: 0, y: 0 });
return (
<div
style={{
transform: `translate(${position.x}px, ${position.y}px)`
}}
/>
);
}
- Style overrides where CSS specificity is problematic
- Small, one-off styles that don’t justify a new CSS rule
Performance Optimization Techniques
1. Memoize Inline Styles When Necessary
function Component() {
const style = useMemo(() => ({
color: 'red',
padding: '10px'
}), []);
return <div style={style} />;
}
2. Use CSS Variables for Dynamic Values
// styles.css
.dynamic {
color: var(--custom-color, red);
padding: 10px;
}
// Component.jsx
function Component({ color }) {
return (
<div
className="dynamic"
style={{ '--custom-color': color }}
/>
);
}
3. Extract Static Parts to CSS
// Instead of:
<div style={{
display: 'flex',
alignItems: 'center',
color: dynamicColor
}} />
// Do:
// styles.css
.flex-center {
display: flex;
align-items: center;
}
// Component.jsx
<div
className="flex-center"
style={{ color: dynamicColor }}
/>
Measuring the Impact
Use React DevTools to:
- Highlight re-renders
- Profile component render times
- Compare with and without inline styles
Use browser DevTools to:
- Check “Recalculate Style” events in Performance tab
- Compare rendering performance
Migration Strategy
- Identify frequently rendered components with inline styles
- Convert static styles to CSS classes first
- Handle dynamic styles with CSS variables or minimal inline styles
- Profile after each change to verify improvements