React Interview Questions (Part 4): Rendering and Performance Optimization
Table of contents
- What is the virtual DOM, and how does React use it to improve performance?
- What are controlled and uncontrolled components, and how do they impact performance?
- How does the use of keys in lists affect performance in React?
- What is code-splitting, and how do you implement it in React?
- How does lazy loading work in React with React.lazy and Suspense?
What is the virtual DOM, and how does React use it to improve performance?
The virtual DOM is a lightweight, in-memory representation of the actual DOM. Instead of updating the entire real DOM every time a change occurs, React creates a new virtual DOM whenever the state changes. React then compares the new virtual DOM with the previous one in a process called reconciliation.
This approach allows React to update only the parts of the DOM that have changed, which minimizes expensive DOM operations and improves performance.
What are controlled and uncontrolled components, and how do they impact performance?
Controlled components have their value managed by React’s state, meaning the component’s value is always synchronized with the state. This provides better control over form inputs, but can lead to more frequent re-renders as the state updates.
Uncontrolled components, on the other hand, manage their own internal state. While they don’t trigger re-renders as often, they can lead to synchronization issues with the rest of the UI.
In terms of performance, controlled components provide better predictability, while uncontrolled components might offer better performance in simpler use cases, but at the cost of less control.
// Controlled Component
function ControlledInput() {
const [value, setValue] = useState('');
return (
<input
value={value}
onChange={e => setValue(e.target.value)}
/>
);
}
// Uncontrolled Component
function UncontrolledInput() {
const inputRef = useRef();
return (
<input ref={inputRef} />
);
}
How does the use of keys in lists affect performance in React?
When rendering lists in React, each item must have a unique key. Keys help React identify which items have changed, been added, or removed. Without proper keys, React may end up re-rendering the entire list, which is inefficient.
Using keys ensures that React can efficiently update only the items that need to change, improving overall performance.
const items = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
];
function ItemList() {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li> // Not recommended
))}
</ul>
);
}
// Correct usage of unique keys:
function ItemListWithKeys() {
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li> // Recommended: Use unique identifier
))}
</ul>
);
}
What is code-splitting, and how do you implement it in React?
Code-splitting is a technique that breaks your JavaScript bundle into smaller pieces, allowing only the necessary code to load when it’s needed. This reduces the initial load time and improves performance, especially in large applications.
In React, code-splitting can be implemented using React.lazy and Suspense, which dynamically load components as the user interacts with the app.
How does lazy loading work in React with React.lazy and Suspense?
Lazy loading defers the loading of components until they are needed. Using React.lazy, you can load components dynamically, reducing the initial load time. Suspense wraps the lazy-loaded component and provides a fallback (like a loading spinner) until the component has finished loading.
This technique improves performance by reducing the size of the initial JavaScript bundle, especially for large applications with many components.
const MyComponent = React.lazy(() => import('./MyComponent'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
);
}
Subscribe to my newsletter
Read articles from Yusuf Uysal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Yusuf Uysal
Yusuf Uysal
𝗗𝗿𝗶𝘃𝗲𝗻 𝗙𝗿𝗼𝗻𝘁𝗲𝗻𝗱 𝗗𝗲𝘃𝗲𝗹𝗼𝗽𝗲𝗿 with extensive experience in JavaScript, React.js, and Next.js. I help companies enhance user engagement and deliver high-performance web applications that are responsive, accessible, and visually appealing. Beyond my technical skills, I am a 𝗰𝗼𝗹𝗹𝗮𝗯𝗼𝗿𝗮𝘁𝗶𝘃𝗲 𝘁𝗲𝗮𝗺 𝗽𝗹𝗮𝘆𝗲𝗿 who thrives in environments that value continuous learning and innovation. I enjoy projects where I can leverage my expertise in 𝗿𝗲𝘀𝗽𝗼𝗻𝘀𝗶𝘃𝗲 𝗱𝗲𝘀𝗶𝗴𝗻, 𝗯𝗿𝗼𝘄𝘀𝗲𝗿 𝗰𝗼𝗺𝗽𝗮𝘁𝗶𝗯𝗶𝗹𝗶𝘁𝘆, 𝗮𝗻𝗱 𝘄𝗲𝗯 𝗽𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲 to deliver seamless user experiences. I get excited about opportunities where I can contribute to creating dynamic, user-focused applications while working closely with cross-functional teams to drive impactful results. I love connecting with new people, and you can reach me at yusufuysal.dev@gmail.com.