Back to blog
ReactPerformanceOptimizationJavaScriptFrontend

Say Goodbye to Slow Renders: Optimizing React Apps with `react-scan`

Published Dec 2, 2024

Performance optimization is a critical aspect of building robust React applications, especially those with complex components or dynamic data flows. react-scan is a powerful tool that helps developers diagnose and fixes rendering inefficiencies, making your app faster and more efficient.

In this blog, we'll explore how to install and configure react-scan, leverage its APIs, and apply practical optimization techniques for your React components.

![Say Goodbye to Slow Renders](/images/blogs/Say Goodbye to Slow Renders- Optimizing React Apps with react-scan.jpg)

What is react-scan?

react-scan is a diagnostic tool for React apps, designed to analyze performance issues and identify unnecessary renders. It logs detailed information about component render cycles and generates reports to help you address bottlenecks efficiently.

Installation and Setup

Depending on your workflow, you can integrate react-scan in several ways, ranging from CLI usage for quick analysis to embedding scripts directly in your codebase.

I. Quick Start with CLI The easiest way to start using react-scan is through its CLI. This opens an isolated browser instance for analyzing any React app.

  • Scan your local app:
npx react-scan@latest http://localhost:3000
  • Analyze any React-based website:
npx react-scan@latest https://react.dev

This method is ideal for quick diagnostics without modifying your source code.

II. Integrating into Your Development Workflow You can incorporate react-scan into your development process by running it alongside your local development server. For example, in a Next.js project:

A. Update the scripts section in your package.json:

{
  "scripts": {
    "dev": "next dev",
    "scan": "next dev & npx react-scan@latest http://localhost:3000"
  }
}

B. Start your development environment with:

npm run scan

This will launch both the development server and react-scan for real-time analysis.

III. Embedding the Script in Your App If you want a more integrated experience, you can embed the react-scan script directly in your project.

  • For Next.js (pages mode):

Add the script to your pages/_document.tsx:

import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
  return (
    <Html lang="en">
      <Head>
        <script src="https://unpkg.com/react-scan/dist/auto.global.js"></script>
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}
  • For Next.js (app mode):

Embed the script in your app/layout.tsx:

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <script src="https://unpkg.com/react-scan/dist/auto.global.js" async />
      </head>
      <body>{children}</body>
    </html>
  );
}
  • For Vite or Create React App:

Add the script in your index.html:

<!doctype html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/react-scan/dist/auto.global.js"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

Key APIs of react-scan

react-scan provides versatile APIs for diagnosing and improving component performance:

  1. scan(options): An imperative API to start scanning.
  2. useScan(options): A hook for targeted scanning in functional components.
  3. withScan(Component, options): A Higher-Order Component (HOC) to analyze specific components.
  4. getReport(): Generates a detailed report of all renders.

Examples of Component Optimization

A. Prevent Unnecessary Renders with React.memo Without optimization, a child component may re-render whenever its parent updates, even if the child's props don't change:

const Child = ({ data }) => {
  console.log('Child render');
  return <div>{data}</div>;
};

export default Child;

Using React.memo, you can prevent redundant renders:

import React from 'react';

const Child = React.memo(({ data }) => {
  console.log('Child render');
  return <div>{data}</div>;
});

export default Child;

B. Use useScan for Targeted Analysis Analyze specific components with the useScan hook:

import React from 'react';
import { useScan } from 'react-scan';

const HeavyComponent = ({ count }) => {
  useScan({ log: true }); // Enables scanning for this component
  console.log('HeavyComponent render');

  return <div>Count: {count}</div>;
};

export default HeavyComponent;

III. Generate Detailed Reports with getReport Generate a comprehensive performance report for all components:

import { getReport } from 'react-scan';

const generateReport = () => {
  const report = getReport();
  console.log('Performance Report:', report);
};

Best Practices for Optimization

  1. Break Down Large Components: Smaller, focused components are easier to optimize.
  2. Leverage React.memo and React.useMemo: Avoid recomputation and re-rendering when dependencies haven't changed.
  3. Avoid Inline Functions: Use React.useCallback to ensure stable function references.
  4. Virtualize Long Lists: Use libraries like react-window for handling large data sets efficiently.

Conclusion

react-scan is an indispensable tool for React developers aiming to enhance application performance. Whether you use the CLI for quick insights or integrate it into your codebase for ongoing analysis, react-scan helps identify and fix bottlenecks effectively.

Start using react-scan today and take your React app performance to the next level.

GitHub project: Project Link

Let's build something

Have a project in mind? I'm open to freelance work and full-time roles.

Get in touch →