Skip to content

Conversation

@rohan-chaturvedi
Copy link
Member

@rohan-chaturvedi rohan-chaturvedi commented Nov 14, 2025

🔍 Overview

The secret editor UI has various performance issues that cause slow downs in user interaction including input field latency. This PR aims to significantly improve performance and latency when interacting with various elements on the single and cross-env editors

💡 Proposed Changes

  • Wrap various components, callbacks and properties in useMemo to prevent re-renders and re-computes when not necssary
  • Wrap callbacks and state handlers in useCallback
  • Various code organisation and splitting to separate concerns
  • Refactor how various common state is passed to list components to reduce re-renders

🖼️ Screenshots or Demo

Include before and after screenshots or animated GIFs/demo links to illustrate the changes visually. This is especially useful for UI/UX improvements.

🎯 Reviewer Focus

Verify that functionality of the single and cross-env editor screens are intact, including:

  • Creating new secrets
  • Editing keys, values, comments, tags, folders
  • Deleting secrets
  • Updating values per env
  • Adding env values when missing
  • Deleting env values
  • Various permutations of these actions

Verify that performance is improved and does not noticable interfere with user inputs

💚 Did You...

  • Ensure linting passes (code style checks)?
    - [ ] Update dependencies and lockfiles (if required)
    - [ ] Update migrations (if required)
    - [ ] Regenerate graphql schema and types (if required)
  • Verify the app builds locally?
  • Manually test the changes on different browsers/devices?

Note

Optimize single- and cross-environment secret editors via memoization, component extraction, and streamlined delete/update handling; includes version bump.

  • Frontend:
    • Cross-env secrets (AppSecrets, AppSecretRow, EnvSecret):
      • Memoize filters, sorting, and handlers (useMemo/useCallback); add stable env sorting.
      • Add deep memoization for rows (memo with custom comparators) to cut re-renders.
      • Refactor delete staging: support env-level stagedForDelete flags, key-level toggling, and updated unsavedChanges checks.
      • Improve immutable updates and bulk import/update helpers.
      • Extract folder UI to AppFolderRow and EnvFolder (memoized); pass pathname for links.
    • Single-env editor (page.tsx):
      • Memoize unsaved-change detection, lookups (map by id), filters/sorts; canonicalSecret accessor.
      • Convert handlers to useCallback; simplify stageSecretForDelete.
      • Fix missing noSecrets; rename prop to canonicalSecret.
    • Components:
      • SecretRow: memoized; use canonicalSecret for permissions and diffing; minor UI tweaks.
      • SecretFolderRow: memoized to avoid unnecessary re-renders.
  • Backend:
    • Bump version to v2.54.2.

Written by Cursor Bugbot for commit c765190. This will update automatically on new commits. Configure here.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR aims to improve performance of the secret editor UI by implementing React optimization patterns including memo, useMemo, and useCallback to reduce unnecessary re-renders and recomputations. The changes also include code organization improvements by extracting components into separate files.

Key Changes

  • Wrapped components in React.memo with custom comparison functions to prevent unnecessary re-renders
  • Memoized expensive computations (filtering, sorting, map creation) using useMemo
  • Wrapped callbacks in useCallback to maintain referential stability
  • Extracted inline components (AppFolderRow, EnvFolder) into separate files for better code organization
  • Refactored state update logic to use functional setState patterns for better performance

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
SecretRow.tsx Added memo wrapper with comparison function; imported memo from React
SecretFolderRow.tsx Wrapped component in memo with field-based comparison logic
page.tsx (environment path) Added useMemo/useCallback for performance; refactored unsavedChanges calculation and state handlers
AppSecrets.tsx Memoized callbacks and filters; refactored complex state update logic; removed inline component definitions
AppSecretRow.tsx Added memo wrapper; changed staged delete logic to use per-secret flags instead of prop list
EnvFolder.tsx New file extracting EnvFolder component with memoization
AppFolderRow.tsx New file extracting AppFolderRow component with memoization

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@rohan-chaturvedi rohan-chaturvedi added enhancement New feature or request frontend Change in frontend code labels Nov 15, 2025
@rohan-chaturvedi rohan-chaturvedi marked this pull request as ready for review November 15, 2025 13:25
@nimish-ks
Copy link
Member

@cursor review

nimish-ks
nimish-ks previously approved these changes Nov 19, 2025
@nimish-ks nimish-ks merged commit db3a26e into main Nov 19, 2025
7 checks passed
if ((p?.stagedForDelete ?? false) !== (n?.stagedForDelete ?? false)) return false
}
return true
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Memo comparison missing callback function checks

The areAppSecretRowEqual comparison function doesn't verify that callback props like updateKey, updateValue, addEnvValue, deleteEnvValue, and deleteKey remain unchanged. Since addEnvValue, deleteEnvValue, and handleStageClientSecretForDelete aren't wrapped in useCallback in AppSecrets.tsx, they get new references on every render. The memo will prevent re-renders even when these callbacks change, causing the component to use stale function closures that may reference outdated state, leading to incorrect behavior when users interact with secrets.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request frontend Change in frontend code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants