Skip to content

What is a better approach to searching a large array for a particular entry multiple times on the same page?

I want to display many icons on the same page but I understand looping through the same array many times each render is too much work and it will reduce performance especially in slower devices. How do you approach this problem?

The allIconsSet array is stored and exported in a file and bundled in the app. The services array comes from a server so it can’t have React Components but only strings.

export const allIconsSet = [
        { id: `live-sports`, icon: <FaTV/> },
        { id: `drinking`, icon: <FaBeer/> },
        { id: `smoking`, icon: <FaCigarette/> },
        { id: `billiard`, icon: <FaBilliard/> },
        // ... 500 more records
]

const services =  [
        { title: `Live Sports`, slug: `live-sports` },
        { title: `Drink`, slug: `drinking` },
        { title: `Smoke`, slug: `smoking` },
        { title: `Billiard`, slug: `billiard` },
        // ... 100 more records
]

function Services()
{
        return (

            <div className="Services">

                    { services.map( service => {

                            const { title, slug } = service

                            const icon = allIconsSet.map( item => {
                                    if ( slug === item.id ) return item.icon
                            });

                            return (

                                <div className="service">
                                        <div className="label">{ title }</div>
                                        <div className="icon">{ icon }</div>
                                </div>

                            )
                    }) }

            </div>

        )
}

export default Services

Answer

Simply transform your icon Array into an Object. And you’ll be able to find an icon like this: allIconsSet['smoking'].

const allIconsSet = {
  'live-sports': { icon: <FaTV/> },
  'drinking':    { icon: <FaBeer/> },
  'smoking':     { icon: <FaCigarette/> },
  'billiard':    { icon: <FaBilliard/> },
  // ...
};

const smokingIcon = allIconsSet.smoking;
const liveSportsIcon = allIconSet['live-sports'];

If you don’t plan to add additional data, you could ditch the icon field and directly pass the component as the icon property value, like: 'smoking': <FaCigarette />,.

NOTE: Icons exists as webfonts that can be used just like any fonts making them easy to use, customizable with CSS and lightweight. Font Awesome does this, you should check it out, it will certainly be less memory/CPU intensive than having one component per icon.

EDIT: Below you’ll find an example of webfont usage with Google Material Icons.

/* You can replace all of this by putting this in your page <head> tag:
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> */


/* fallback */
@font-face {
  font-family: 'Material Icons';
  font-style: normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/s/materialicons/v85/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2) format('woff2');
}

.material-icons {
  font-family: 'Material Icons';
  font-weight: normal;
  font-style: normal;
  font-size: 24px;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-block;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  -webkit-font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
}

/* You can then stylized your icon just like any text */
.my-class {
  color: #333;
  font-size: 40px;
}
<span class="my-class material-icons">delete</span>
<span class="my-class material-icons">edit</span>
<span class="my-class material-icons">alarm</span>