Skip to content

Conversation

@crtag
Copy link

@crtag crtag commented Oct 18, 2025

Problem

The ChatKitPanel component had severe performance issues causing:

  • Browser unresponsiveness and freezing during use
  • Extreme memory consumption (20GB+ RAM usage)
  • Browser tab crashes
  • Input lag when typing in the chat interface

These issues are documented in #44, and may also address similar performance concerns mentioned in #21 and #6.

Root Cause

The useChatKit hook was receiving new function and object references on every component render, causing the ChatKit SDK to continuously re-initialize. This created:

  1. Infinite re-render cycles - New inline callback functions were created on each render, triggering useChatKit to re-run its internal effects
  2. Unnecessary SDK re-initializations - New configuration objects caused the SDK to tear down and rebuild its iframe/web component repeatedly
  3. Memory leaks - The constant re-initialization prevented proper cleanup, leading to massive memory consumption

Solution

Commit 1: Fix infinite re-render loop (Critical Fix)

Wrapped all callback functions in useCallback hooks to maintain stable references:

  • onClientTool - handles theme switching and fact recording
  • onResponseEnd - called when AI response completes
  • onResponseStart - resets error state when response starts
  • onThreadChange - clears processed facts cache
  • onError - error logging handler

Impact: Resolved the critical memory leak and browser stability issues.

Commit 2: Optimize configuration with memoization (Performance Enhancement)

Memoized all configuration objects passed to useChatKit:

  • themeConfig - memoized with [theme] dependency
  • apiConfig - memoized with [getClientSecret] dependency
  • startScreenConfig, composerConfig, threadItemActionsConfig - memoized with empty dependencies (static configs)

Also removed unnecessary callback wrapper for onResponseEnd (prop is already stable from parent).

Impact: Prevents unnecessary SDK re-initializations when internal component state changes (error handling, initialization, script loading).

Commit 3: Add troubleshooting documentation

Added a "Troubleshooting" section to the README documenting:

  • ChatKit's iframe-based architecture and why it's used (security isolation)
  • How browser extensions can interfere with cross-frame messaging (postMessage)
  • Guidance for diagnosing extension-related performance issues
  • Recommendation to use server-side integration for production applications

Impact: Helps future users understand architectural tradeoffs and avoid misdiagnosing extension interference as application bugs.

Testing

  • ✅ Extended usage sessions - no memory leaks observed
  • ✅ Component remains responsive during typing
  • ✅ Browser memory usage stays under 100MB (down from 20GB+)
  • ✅ No browser tab crashes
  • ✅ All functionality preserved (theme switching, attachments, error handling)

Technical Details

These changes follow React performance best practices:

  • Using useCallback for function props to prevent unnecessary re-renders
  • Using useMemo for complex object configurations to maintain referential equality
  • Ensuring that hooks receive stable dependencies to prevent effect re-execution loops

Related Issues

Fixes #44 - Extreme memory usage and browser freezes
May help with #21 - Performance-related concerns
May help with #6 - Potential performance issues

Notes

During investigation, I discovered that some residual performance issues can be caused by Chrome extension interference with the ChatKit SDK's postMessage architecture. Extensions that monitor DOM changes or intercept cross-frame communication can slow down the SDK's message handlers. The code fixes in this PR address the React-level performance issues; extension interference is a separate environmental concern documented in the new Troubleshooting section.

crtag added 3 commits October 18, 2025 21:15
Wrap all callback functions passed to useChatKit in useCallback hooks
to prevent infinite re-render cycles. Previously, new callback instances
were created on every render, causing useChatKit to reinitialize
repeatedly, leading to browser freezes and extreme memory usage (20GB+).

Changes:
- Extract onClientTool, onResponseEnd, onResponseStart, onThreadChange,
  and onError into separate useCallback hooks with proper dependencies
- This ensures stable function references across renders
- Prevents unnecessary re-initialization of the ChatKit component
Memoize all configuration objects passed to useChatKit to prevent
unnecessary re-initializations of the ChatKit SDK. This reduces
performance overhead from the SDK's postMessage architecture.

Changes:
- Add useMemo import from React
- Memoize themeConfig with [theme] dependency
- Memoize apiConfig with [getClientSecret] dependency
- Memoize startScreenConfig, composerConfig, threadItemActionsConfig
  with empty dependencies (static configs)
- Pass onResponseEnd prop directly instead of wrapping in useCallback
- Remove unnecessary render state console.debug logging
- Remove comment about ChatKit error handling (self-evident)

This ensures the SDK only reinitializes when actual configuration
values change, not on every render due to new object references.
Document that ChatKit's iframe-based architecture can be affected by
browser extensions that interfere with cross-frame messaging (postMessage).

Provides guidance for:
- Testing in incognito mode to rule out extension interference
- Monitoring memory usage for potential issues
- Considering server-side integration for production applications

This helps users understand architectural tradeoffs and avoid
misdiagnosing extension interference as application bugs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dev environment rendering and memory issues

1 participant