> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/react-icons/react-icons/llms.txt
> Use this file to discover all available pages before exploring further.

# Performance Optimization

> Optimize bundle size and runtime performance with tree-shaking and best practices

React Icons is designed for optimal performance through ES6 imports and tree-shaking, allowing you to include only the icons your project uses.

## Tree-Shaking Benefits

React Icons uses ES6 module imports, enabling modern bundlers to eliminate unused code:

<CodeGroup>
  ```jsx Modern Import (Tree-shakeable) theme={null}
  import { FaBeer, FaCoffee } from "react-icons/fa";

  function Beverages() {
    return (
      <div>
        <FaBeer />
        <FaCoffee />
      </div>
    );
  }
  // ✓ Only FaBeer and FaCoffee are included in your bundle
  ```

  ```jsx Legacy Import (Not Recommended) theme={null}
  // ❌ OLD STYLE - Don't use this
  import FaBeer from "react-icons/lib/fa/beer";

  function Question() {
    return (
      <h3>
        Lets go for a <FaBeer />?
      </h3>
    );
  }
  // This import style is deprecated since version 3
  ```
</CodeGroup>

<Tip>
  With proper tree-shaking, importing from `react-icons/fa` only bundles the icons you actually use, not the entire Font Awesome library.
</Tip>

## Import Strategies

<Tabs>
  <Tab title="Named Imports (Recommended)">
    Import specific icons by name:

    ```jsx theme={null}
    import { FaReact, FaNodeJs, FaPython } from "react-icons/fa";
    import { MdEmail, MdPhone } from "react-icons/md";
    import { AiFillGithub } from "react-icons/ai";

    function TechStack() {
      return (
        <div>
          <FaReact />
          <FaNodeJs />
          <FaPython />
        </div>
      );
    }
    ```

    **Pros**: Best tree-shaking, explicit dependencies, fast build times
  </Tab>

  <Tab title="Icon Pack Imports">
    Import from specific icon packs:

    ```jsx theme={null}
    // Each icon pack is in its own subpath
    import { FaBeer } from "react-icons/fa";      // Font Awesome
    import { MdHome } from "react-icons/md";      // Material Design
    import { AiFillHeart } from "react-icons/ai"; // Ant Design
    import { BiSearch } from "react-icons/bi";    // BoxIcons
    import { BsCart } from "react-icons/bs";      // Bootstrap Icons
    ```

    **Pros**: Organized by icon family, still tree-shakeable
  </Tab>

  <Tab title="Individual File Imports">
    For environments with build issues, import individual files:

    ```jsx theme={null}
    import { FaBeer } from "@react-icons/all-files/fa/FaBeer";

    function Question() {
      return (
        <h3>
          Lets go for a <FaBeer />?
        </h3>
      );
    }
    ```

    **Pros**: Guaranteed tree-shaking, no bundler configuration needed

    **Cons**: Slower installation, more verbose imports
  </Tab>
</Tabs>

## Bundle Size Analysis

Monitor your bundle size to ensure tree-shaking is working:

<Steps>
  <Step title="Install bundle analyzer">
    ```bash theme={null}
    npm install --save-dev webpack-bundle-analyzer
    # or
    yarn add -D webpack-bundle-analyzer
    ```
  </Step>

  <Step title="Add to webpack config">
    ```javascript theme={null}
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

    module.exports = {
      plugins: [
        new BundleAnalyzerPlugin()
      ]
    };
    ```
  </Step>

  <Step title="Build and analyze">
    ```bash theme={null}
    npm run build
    # Opens visualization showing react-icons bundle size
    ```
  </Step>
</Steps>

<Warning>
  If you see the entire icon pack in your bundle instead of individual icons, check your bundler configuration for tree-shaking support.
</Warning>

## Lazy Loading Icons

For applications with many icons, use code splitting:

```jsx theme={null}
import { lazy, Suspense } from 'react';

// Lazy load icon-heavy components
const IconGallery = lazy(() => import('./components/IconGallery'));

function App() {
  return (
    <Suspense fallback={<div>Loading icons...</div>}>
      <IconGallery />
    </Suspense>
  );
}
```

## Dynamic Icon Loading

For truly dynamic icon selection, consider this pattern:

<CodeGroup>
  ```jsx Dynamic Icon Component theme={null}
  import { lazy, Suspense } from 'react';
  import * as FaIcons from 'react-icons/fa';

  function DynamicIcon({ iconName, ...props }) {
    const Icon = FaIcons[iconName];
    
    if (!Icon) {
      console.warn(`Icon "${iconName}" not found`);
      return null;
    }
    
    return <Icon {...props} />;
  }

  // Usage
  function App() {
    return (
      <div>
        <DynamicIcon iconName="FaBeer" size={24} />
        <DynamicIcon iconName="FaCoffee" size={24} />
      </div>
    );
  }
  ```

  ```jsx Icon Map (Better Tree-Shaking) theme={null}
  // icons/iconMap.js
  import { FaBeer, FaCoffee, FaWine } from 'react-icons/fa';

  export const iconMap = {
    beer: FaBeer,
    coffee: FaCoffee,
    wine: FaWine,
  };

  // components/DynamicIcon.jsx
  import { iconMap } from '../icons/iconMap';

  function DynamicIcon({ name, ...props }) {
    const Icon = iconMap[name];
    
    if (!Icon) return null;
    
    return <Icon {...props} />;
  }

  // Usage - only icons in iconMap are bundled
  <DynamicIcon name="beer" size={24} />
  ```
</CodeGroup>

<Tip>
  The icon map approach provides better tree-shaking because only icons explicitly added to the map are included in the bundle.
</Tip>

## Runtime Performance

### Memoization

For icons that re-render frequently, use React.memo:

```jsx theme={null}
import { memo } from 'react';
import { FaStar } from 'react-icons/fa';

const StarIcon = memo(({ filled, ...props }) => (
  <FaStar 
    color={filled ? 'gold' : 'gray'} 
    {...props} 
  />
));

function StarRating({ rating }) {
  return (
    <div>
      {[1, 2, 3, 4, 5].map(star => (
        <StarIcon 
          key={star} 
          filled={star <= rating} 
        />
      ))}
    </div>
  );
}
```

### IconContext Optimization

Place `IconContext.Provider` strategically to avoid unnecessary re-renders:

<CodeGroup>
  ```jsx Optimized Context Placement theme={null}
  import { IconContext } from 'react-icons';
  import { useMemo } from 'react';

  function App() {
    const iconConfig = useMemo(() => ({
      color: 'blue',
      size: '1.5em',
      className: 'global-icon'
    }), []);
    
    return (
      <IconContext.Provider value={iconConfig}>
        <Navigation />
        <Content />
      </IconContext.Provider>
    );
  }
  ```

  ```jsx Avoid Inline Objects theme={null}
  import { IconContext } from 'react-icons';

  function App() {
    // ❌ Creates new object on every render
    return (
      <IconContext.Provider value={{ color: 'blue', size: '1.5em' }}>
        <Navigation />
      </IconContext.Provider>
    );
  }
  ```
</CodeGroup>

## Build Configuration

Ensure your bundler is configured for optimal tree-shaking:

<Tabs>
  <Tab title="Webpack 5">
    ```javascript theme={null}
    // webpack.config.js
    module.exports = {
      mode: 'production',
      optimization: {
        usedExports: true,
        sideEffects: false,
      },
      resolve: {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
    };
    ```
  </Tab>

  <Tab title="Vite">
    ```javascript theme={null}
    // vite.config.js
    import { defineConfig } from 'vite';
    import react from '@vitejs/plugin-react';

    export default defineConfig({
      plugins: [react()],
      build: {
        rollupOptions: {
          output: {
            manualChunks: {
              'react-icons': ['react-icons'],
            },
          },
        },
      },
    });
    ```
  </Tab>

  <Tab title="Next.js">
    ```javascript theme={null}
    // next.config.js
    module.exports = {
      webpack: (config) => {
        config.optimization = {
          ...config.optimization,
          sideEffects: false,
        };
        return config;
      },
    };
    ```
  </Tab>
</Tabs>

## Large Bundle Size Issues

If your bundle is larger than expected:

<AccordionGroup>
  <Accordion title="Check import statements">
    Ensure you're using named imports from subpaths:

    ```jsx theme={null}
    // ✓ Good
    import { FaBeer } from "react-icons/fa";

    // ✓ Good
    import { FaBeer } from "@react-icons/all-files/fa/FaBeer";

    // ❌ Bad - imports everything
    import * as Icons from "react-icons/fa";
    ```
  </Accordion>

  <Accordion title="Verify bundler configuration">
    Ensure tree-shaking is enabled:

    * Set `mode: 'production'` in webpack
    * Enable `sideEffects: false` in optimization
    * Check `package.json` for `"sideEffects": false`
  </Accordion>

  <Accordion title="Use @react-icons/all-files">
    If tree-shaking isn't working, use the alternative package:

    ```bash theme={null}
    npm install @react-icons/all-files
    ```

    ```jsx theme={null}
    import { FaBeer } from "@react-icons/all-files/fa/FaBeer";
    ```

    Trade-off: Slower installation, but guaranteed small bundle.
  </Accordion>

  <Accordion title="Split icon imports by route">
    Use code splitting to load icons only when needed:

    ```jsx theme={null}
    // routes/Dashboard.jsx
    import { FaHome, FaUser } from "react-icons/fa";

    // routes/Settings.jsx  
    import { FaCog, FaBell } from "react-icons/fa";

    // Only relevant icons load per route
    ```
  </Accordion>
</AccordionGroup>

## Performance Benchmarks

Typical bundle impact per icon:

| Metric                  | Value        |
| ----------------------- | ------------ |
| Single icon (gzipped)   | \~0.3-0.5 KB |
| IconBase core (gzipped) | \~0.5 KB     |
| IconContext (gzipped)   | \~0.2 KB     |
| 10 icons total          | \~3-5 KB     |
| 50 icons total          | \~15-25 KB   |

<Tip>
  React Icons SVG components have minimal runtime overhead compared to icon fonts. There's no blocking network request for font files, and icons render immediately.
</Tip>

## SVG vs Icon Fonts

React Icons uses SVG components, which offer performance advantages:

| Aspect            | React Icons (SVG)    | Icon Fonts       |
| ----------------- | -------------------- | ---------------- |
| **Bundle Size**   | Only used icons      | Entire font file |
| **Loading**       | No network request   | Blocks rendering |
| **Rendering**     | Immediate            | After font loads |
| **Scalability**   | Perfect at any size  | Good             |
| **Customization** | Full control         | Limited          |
| **Accessibility** | Better semantic HTML | Requires ARIA    |
| **Tree-shaking**  | Yes                  | No               |

## Monitoring Performance

Track icon performance in production:

```jsx theme={null}
import { FaBeer } from 'react-icons/fa';
import { useEffect } from 'react';

function MonitoredIcon() {
  useEffect(() => {
    // Measure rendering performance
    performance.mark('icon-render-start');
    
    return () => {
      performance.mark('icon-render-end');
      performance.measure(
        'icon-render',
        'icon-render-start',
        'icon-render-end'
      );
    };
  }, []);
  
  return <FaBeer />;
}
```

## Best Practices Summary

<CardGroup cols={2}>
  <Card title="Use Named Imports" icon="file-import">
    Import specific icons to enable tree-shaking
  </Card>

  <Card title="Analyze Bundle Size" icon="chart-line">
    Regularly check that only used icons are bundled
  </Card>

  <Card title="Lazy Load Heavy Components" icon="spinner">
    Use code splitting for icon-heavy sections
  </Card>

  <Card title="Memoize IconContext" icon="memory">
    Avoid creating new context objects on every render
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Getting Started" icon="rocket" href="/quickstart">
    Set up React Icons in your project
  </Card>

  <Card title="Customizing Icons" icon="sliders" href="/guides/customizing-icons">
    Learn about icon customization options
  </Card>
</CardGroup>
