C3 AI Documentation Home

Profile the front-end application

A slow UI frustrates users. Common performance issues include:

  • Components that re-render too often
  • Expensive calculations in TSX
  • Unbatched state updates
  • React state and Redux store updates triggering unnecessary work

You can’t optimize what you can’t measure. Chrome DevTools and React Developer Tools provide precise tools to analyze frame-by-frame performance and track which components are causing the most work.

Start with the Chrome DevTools Performance panel

The Performance panel records exactly how long each frame takes to render. Use it to analyze:

  • CPU usage during a user interaction
  • JavaScript execution time per frame
  • Layout, painting, and scripting bottlenecks

How to record a performance profile

  1. Open Chrome DevTools and switch to the Performance tab.
  2. Click the Record button (●).
  3. Interact with the UI — scroll, filter, click buttons.
  4. Stop recording.
  5. Use the flame chart to inspect frames that took longer than 16ms (these cause visual stutter).

What to look for

  • Scripting bars: High values mean your JavaScript logic takes too long.
  • Rendering bars: Suggest layout or DOM manipulation issues.
  • Long tasks: These are visible in red and block interactivity.

Use this when: You want to know where the slowness comes from — backend response, Redux update, or React render.

Use the React Profiler to measure component rendering

The React Profiler shows how much time each component took to render and why it re-rendered.

How to record with the React Profiler

  1. Open DevTools and switch to the Profiler tab (requires React Developer Tools).

  2. Click Record.

  3. Interact with the UI — open modals, change filters, click tabs.

  4. Stop the recording.

  5. Click on any component in the flame graph to see:

    • How long it took to render
    • Whether it re-rendered due to props, state, or context
    • How often it re-rendered

What to focus on

  • Components with high render time (more than 3–5ms)
  • Components that render frequently on small changes
  • Components that re-render even though props did not change

Use this when: The UI feels sluggish or input interactions lag.

Detect unnecessary re-renders using “Highlight updates”

In the Components tab:

  1. Open the settings menu (⚙️).
  2. Enable Highlight updates when components render.

Now every re-render causes a green flash around the component.

Use this live while interacting with the app.

Use this when: You want to see which components update on a Redux change, button click, or transform trigger.

Optimize high-cost components

Once you've identified slow components:

  • Use React.memo() to prevent unnecessary re-renders.
  • Wrap expensive derived calculations with useMemo().
  • Use useCallback() to avoid passing new functions on each render.

Example: Memoize a component

TypeScript
const TurbineRow = React.memo(({ turbine }) => {
  return <div>{turbine.name}</div>;
});

This prevents re-rendering unless turbine changes.

Use this when: A list of rows re-renders every time even if data hasn’t changed.

Reduce unnecessary Redux-driven renders

If a component uses useSelector, ensure that it selects the minimal slice of state:

TypeScript
const turbines = useSelector((state) => state.windTurbineList);

If the selector returns a new object or array every time, React re-renders even if nothing inside changed.

Use reselect or memoized selectors to fix this:

TypeScript
const selectTurbines = createSelector(
  (state) => state.windTurbineList,
  (list) => list.filter((row) => row.status === 'online')
);

Use this when: Redux state updates cause components to re-render even when the actual data didn’t change.

Batch state updates to avoid layout thrashing

If your component calls multiple setState or dispatch functions back-to-back, React may render multiple times unnecessarily.

Wrap them in a single useEffect, event handler, or callback:

TypeScript
const handleClick = () => {
  setExpanded(true);
  setSelectedId(id);
};

React batches updates automatically in modern versions, but code outside React (like backend callbacks) may still cause multiple renders.

Use this when: Clicking a single button causes multiple re-renders or layout shifts.

Profile slow forms, filters, and tables

C3 UI apps often render large grids or filters that react to user selections. If typing, selecting, or paginating feels slow:

  • Profile the interaction with the React Profiler
  • Look for repeated re-renders of entire grid components
  • Confirm that onChange handlers, filters, or paginators do not trigger full state reloads

Use React.memo for each row or cell. Confirm that only changed cells re-render.

Avoid re-renders caused by metadata transforms

Transforms that run on every input change can introduce subtle slowdowns.

Example:

TypeScript
return function (_, context) {
  return {
    rows: context.applicationStateRef?.myRows,
    total: context.uiInput?.length,
  };
};

If this runs every keystroke and produces a new object, React re-renders everything downstream.

Use this when: Input typing, dropdowns, or search fields freeze the UI.

Troubleshooting checklist

SymptomProfiling ToolOptimization Strategy
UI feels slowChrome Performance panelIdentify slow frames, scripting, layout
Grid or table re-renders on scrollReact ProfilerMemoize rows, batch updates
Form input causes lagReact Profiler + ComponentsDebounce events, memoize input handlers
State update causes UI flickerHighlight updatesCheck unnecessary re-renders, split state
Redux updates cause wide re-rendersReact Profiler + Redux panelUse memoized selectors, narrow subscriptions
Was this page helpful?