Master React Performance Optimization in WordPress. Learn how to implement shallow comparison and memoized selectors to prevent unnecessary re-renders.
Previously in this course, we covered writing selectors for data access to retrieve state from our custom data store. While those basic selectors work for simple data, they can trigger expensive re-renders in your admin dashboard if they return new object references every time they are called. Today, we’re leveling up: we will learn to optimize selector performance to ensure our Knowledge Base plugin remains responsive as our dataset grows.
In the WordPress Data module, a component subscribed to a selector will re-render whenever the value returned by that selector changes. This check is performed using a "shallow equality" comparison. If your selector returns a new object or array—even if the underlying data inside is identical—React assumes the state has changed and forces a re-render.
This is a classic performance trap. If your Knowledge Base dashboard has a list of 50 articles and your selector returns a fresh array object every time, every single list item component will re-render on every state update, even if the data for that specific item hasn't changed.
To prevent these unnecessary updates, we must ensure our selectors return the exact same reference if the input state hasn't changed. We do this using createSelector from the @wordpress/data package, which provides memoization by default.
Consider this unoptimized selector:
JAVASCRIPT// A common performance pitfall const getActiveArticles = (state) => { return state.articles.filter(article => article.status === CE9178">'publish'); };
Every time getActiveArticles is called, .filter() creates a new array instance. If you use this in a component via useSelect, that component will re-render every time any part of the global state changes, because the array reference is always "new."
Here is how we optimize it:
JAVASCRIPTimport { createSelector } from CE9178">'@wordpress/data'; const getActiveArticles = createSelector( (state) => { return state.articles.filter(article => article.status === CE9178">'publish'); }, (state) => [state.articles] // Dependency array );
The createSelector function takes two arguments: the transformation function and a dependency function. It only re-runs the transformation if the result of the dependency function changes. By returning [state.articles], we tell the store: "Only re-calculate the filtered list if the articles array reference itself changes."
Let's apply this to our Knowledge Base plugin. Open your store/selectors.js file and find your article list selector.
createSelector.createSelector. Memoization consumes memory. Only optimize selectors that return derived objects or arrays, or those that perform expensive computations.createSelector, make sure you aren't creating new function references that break the memoization cache.To see these optimizations in action, you need to measure them. In your browser's DevTools:
If you see a component rendering that shouldn't be, check the selector it's using. If it's returning a fresh object, you've found your performance bottleneck. This is a critical step to take alongside understanding React re-rendering, as it ensures your plugin handles data-heavy admin interfaces with ease.
By mastering these techniques, you ensure that your WordPress plugins provide a professional, lag-free experience for site administrators. This is a core pillar of structuring state for performance in larger React applications.
Up next: We will tackle complex state dependencies where one selector needs to consume the output of another, ensuring our data remains consistent across the entire dashboard.
Master selectors in @wordpress/data to efficiently retrieve state. Learn to implement memoization for high-performance React admin interfaces in WordPress.
Read moreLearn to build robust input validation for your WordPress plugin. Discover how to provide instant client-side feedback and handle server-side errors gracefully.
Optimizing Performance with Selectors
Protecting Admin Screens
Production Build Pipeline
Debugging React in the WordPress Admin
Building Search and Filter Functionality
Internationalization in React
Managing File Uploads via REST API
Optimizing API Response Times
Working with Date and Time in React
Implementing Drag-and-Drop Sorting
Creating Custom Hooks for API Logic
Integrating with Gutenberg Blocks
Handling Conflict Resolution
Building a Modal Confirmation System
Implementing Activity Logging
Using Webpack Aliases
Unit Testing API Endpoints
Unit Testing React Components
Handling Large Datasets with GraphQL
Implementing Real-time Updates with Web