#react #tutorial #advanced

Day 10: Performance Optimization

Day 10: Performance Optimization

Congratulations on making it to Day 10! Today we discuss how to make your apps faster. React is fast by default, but as apps grow, we need to be careful.

1. memo (Skipping Re-renders)

If a parent component re-renders, all its children re-render too, recursively. If a child component is “expensive” to render and its props haven’t changed, this is wasted work.

memo (formerly React.memo) lets you skip re-rendering a component if its props are the same.

import { memo, useState } from 'react';

const ExpensiveComponent = memo(function({ name }) {
  console.log("Rendering ExpensiveComponent");
  return <div>Hello {name}</div>;
});

function App() {
  const [count, setCount] = useState(0);

  return (
    <>
      <button onClick={() => setCount(count + 1)}>Count: {count}</button>
      {/* ExpensiveComponent won't re-render when 'count' changes! */}
      <ExpensiveComponent name="Jack" />
    </>
  );
}

2. useMemo (Caching Expensive Computations)

If you have a heavy calculation inside your component, you don’t want to run it on every render.

import { useMemo } from 'react';

function Dashboard({ users, filter }) {
  // Only re-calculate filteredUsers if 'users' or 'filter' changes
  const filteredUsers = useMemo(() => {
    return users.filter(u => u.name.includes(filter));
  }, [users, filter]);

  return <List items={filteredUsers} />;
}

3. useCallback (Caching Functions)

When you pass a function to a child component, React sees it as a new function every render. This breaks memo. useCallback caches the function definition between renders.

import { useCallback } from 'react';

function Parent() {
  const handleClick = useCallback(() => {
    console.log('Clicked');
  }, []); // Dependencies

  return <Child onClick={handleClick} />;
}

4. Code Splitting (Lazy Loading)

By default, React bundles your whole app into one big JavaScript file. If it gets too big, the initial page load is slow. Code splitting lets you load parts of your app only when needed.

import { lazy, Suspense } from 'react';

// Don't import normally
// import AdminPanel from './AdminPanel';

// Import lazily
const AdminPanel = lazy(() => import('./AdminPanel'));

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

Now, the code for AdminPanel is only downloaded when the user actually tries to view it.


Conclusion

You’ve done it! You’ve gone from “Hello World” to Advanced Performance patterns.

Where to go from here?

  • Build Projects: The best way to learn is by doing. Clone Twitter, Trello, or Instagram.
  • Learn a Framework: Next.js or Remix. These are built on React but add Server Side Rendering (SSR) and Routing out of the box.
  • State Management Libraries: Redux Toolkit, Zustand, or TanStack Query.

Thank you for following along with this series. Happy Coding!