Vinit Kaushal
Vinit Kaushal

Reputation: 41

React Icons Dynamic Import Not Working in Production (Performance Issue) Vite-SWC React

I'm using react-icons in a loop to render multiple icons dynamically in my React component. However, this approach seems to be increasing the initial bundle size and slowing down the page load in production. I'm attempting to use dynamic imports to reduce the initial load time, but it's not working as expected in the production build.

 import React, { useEffect, useState } from 'react';
    
    const DynamicIcon = ({ iconName, color, size }) => {
        const [IconComponent, setIconComponent] = useState(null);
    
        useEffect(() => {
            const loadIcon = async () => {
                try {
                    const [lib, icon] = iconName.split('/');
                    const IconModule = await import(/* @vite-ignore */`/node_modules/react-icons/${lib}`);
                    const Icon = IconModule[icon];
                    if (Icon) {
                        setIconComponent(() => Icon);
                    } else {
                        console.error(`Icon ${iconName} not found`);
                    }
                } catch (err) {
                    console.error(`Failed to load icon: ${iconName}`, err);
                }
            };
    
            loadIcon();
        }, [iconName]);
    
        if (!IconComponent) return null;
    
        return <IconComponent color={color} size={size} />;
    };
    
    export default DynamicIcon;

Vite.config.js

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
export default defineConfig({
  plugins: [
    react(),
  ],
  optimizeDeps: {
    include: ['js-cookie', 'react-microsoft-login', 'redux-thunk', 'react-apexcharts', 'quill', 'react-icons']
  },
  build: {
    chunkSizeWarningLimit: 50000,
    outDir: "dist",
    minify: "esbuild",
    manifest: true,
    sourcemap: false,
    reportCompressedSize: true,
    rollupOptions: {
      output: {
        manualChunks(id) {
          const HugeLibraries = ['react-apexcharts', 'react-icons', 'quill'];
          if (HugeLibraries.some((libName) => id.includes(`node_modules/${libName}`))) {
            return id.toString().split("node_modules/")[1].split("/")[0].toString();
          }
        },
      },
    },
  },
})

Upvotes: 0

Views: 33

Answers (0)

Related Questions