Performance Optimization with Selectors in WordPress React Apps
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.
The Problem: Why Selectors Cause Re-renders
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.
Implementing Shallow Comparison and Memoization
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."
Hands-on Exercise: Optimizing the Knowledge Base List
Let's apply this to our Knowledge Base plugin. Open your store/selectors.js file and find your article list selector.
- Refactor: Wrap your existing selector in
createSelector. - Define Dependencies: Identify exactly which part of the state tree your selector depends on.
- Verify: Use the React Developer Tools "Profiler" tab to record your dashboard interactions. Look for the "Why did this render?" badge. If you see "Props changed" for your list items, your selector is likely returning new references.
Common Pitfalls
- Over-memoization: Don't wrap every trivial selector in
createSelector. Memoization consumes memory. Only optimize selectors that return derived objects or arrays, or those that perform expensive computations. - Ignoring Dependency Arrays: If you pass an incorrect dependency (e.g., watching the wrong state slice), your UI will become stale and fail to update when data actually changes.
- Anonymous Functions in Selectors: If you define the transformation function inline inside
createSelector, make sure you aren't creating new function references that break the memoization cache.
Profiling Your Dashboard
To see these optimizations in action, you need to measure them. In your browser's DevTools:
- Open the Profiler tab.
- Click the "Record" button.
- Perform an action in your Knowledge Base dashboard (e.g., adding an article).
- Stop recording and inspect the "Ranked" chart.
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.
Work with me

Custom WordPress Plugin Development
Custom WordPress & WooCommerce plugins built to standard — by the developer behind a plugin with 5,000+ active installs and a SaaS with 10,000+ users.

Laravel Bug Fixes, Maintenance & Optimization
Stuck on a Laravel bug or a slow app? Fast, reliable fixes, upgrades, and performance tuning from an experienced Laravel engineer.