Skip to content

Conversation

@benlife5
Copy link
Contributor

@benlife5 benlife5 commented Dec 9, 2025

#935 added a deepEqual check for re-resolving all data which seemed to have helped a bit.

This PR adds additional save state management, which helps particularly when clearing local changes.
Reducing the placeholder image size seems to make the re-rendering a little faster.

There still is a delay when publishing and then switching tabs. I'm not entirely sure what is triggering it but the slowness seems to be on Puck's side. Puck has some slot performance improvements coming up, so I think we should take a look again after those are done.

@benlife5 benlife5 added the create-dev-release Triggers dev release workflow label Dec 9, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Dec 9, 2025

Warning: Component files have been updated but no migrations have been added. See https://github.com/yext/visual-editor/blob/main/packages/visual-editor/src/components/migrations/README.md for more information.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 9, 2025

commit: 3a694bc

@colton-demetriou
Copy link
Contributor

@benlife5 benlife5 marked this pull request as ready for review December 10, 2025 16:01
@benlife5 benlife5 changed the title fix: tab slowness [draft] fix: tab slowness Dec 10, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 10, 2025

Walkthrough

This PR exposes a setLayoutSaveState setter from useLayoutMessageReceivers, uses it to reset layout save state when clearing history and before publishing, and replaces direct publishLayout calls with a new handlePublish that clears save state then delegates to publish. It also memoizes QueryClient creation in VisualEditorProvider to avoid recreating the client each render, updates default layout image URLs with explicit sizing/fitting parameters, and simplifies TeamCard image initialization by removing an unused placeholder fallback.

Possibly related PRs

Suggested reviewers

  • briantstephan
  • colton-demetriou
  • asanehisa

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: tab slowness' is directly related to the changeset, which includes multiple performance improvements targeting slower tab switching and rendering.
Description check ✅ Passed The description accurately relates to the changeset, explaining the performance optimization efforts including save state management, placeholder image size reduction, and referencing PR #935.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch tab-slowness

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32d432d and 6ddbca9.

📒 Files selected for processing (1)
  • packages/visual-editor/src/vite-plugin/defaultLayoutData.ts (16 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/visual-editor/src/vite-plugin/defaultLayoutData.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/visual-editor/src/vite-plugin/defaultLayoutData.ts (1)

318-321: Standardizing default Unsplash image URLs with w=1000 is consistent and safe

All the updated url fields now use the same IDs plus a w=1000 width cap, which should reduce payload size and keep defaults in sync with the placeholder utility. Since only static data changed and dimensions/slots are untouched, this is a low-risk, desirable tweak. Long term, you might consider centralizing these shared URLs/IDs to avoid copy‑paste drift.

Also applies to: 398-401, 685-688, 804-807, 933-936, 1062-1065, 1784-1787, 1949-1952, 2112-2115, 2334-2337, 2492-2495, 2650-2653, 2829-2832, 2837-2840, 2845-2848, 2937-2940, 3077-3080, 3217-3220

packages/visual-editor/src/utils/VisualEditorProvider.tsx (1)

35-38: Good change to stabilize QueryClient instance; optional tweak to align with React Query docs

Memoizing the QueryClient like this avoids re-creating it on every render, which should help with both cache stability and perf. This looks correct.

If you want to align more closely with common React Query patterns (and avoid any confusion around useMemo semantics), you could optionally switch to a lazy useState initializer, which guarantees the factory only runs once per mount:

-  // Use useMemo to prevent creating a new QueryClient on every render
-  // QueryClient maintains internal caches, so creating new instances unnecessarily
-  // could lead to memory accumulation
-  const queryClient = React.useMemo(() => new QueryClient(), []);
+  // Create a single QueryClient instance per provider mount.
+  // QueryClient maintains internal caches, so we avoid re-instantiating it on re-renders.
+  const [queryClient] = React.useState(() => new QueryClient());
packages/visual-editor/src/internal/components/LayoutEditor.tsx (1)

84-91: Resetting layoutSaveState before delete/publish matches the data-flow goal; consider memoizing handlePublish

Clearing the local layoutSaveState before:

  • deleteLayoutSaveState() in clearHistory, and
  • publishLayout(data) in handlePublish

keeps the in-memory view aligned with the intended “no pending save state” semantics and should help avoid re-sending stale history to Puck after those actions. Behaviorally this matches the PR’s objective.

For a small perf polish (since this is a hot-ish path for slowness work), you could memoize handlePublish so InternalLayoutEditor doesn’t see a new function on every render:

-  const handlePublish = (data?: any) => {
-    setLayoutSaveState(undefined);
-    publishLayout(data);
-  };
+  const handlePublish = useCallback(
+    (data?: any) => {
+      setLayoutSaveState(undefined);
+      publishLayout(data);
+    },
+    [setLayoutSaveState, publishLayout]
+  );

This is non-blocking but may help reduce unnecessary child re-renders.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f7cb67d and 7a5be04.

📒 Files selected for processing (5)
  • packages/visual-editor/src/internal/components/LayoutEditor.tsx (3 hunks)
  • packages/visual-editor/src/internal/hooks/layout/useMessageReceivers.ts (1 hunks)
  • packages/visual-editor/src/utils/VisualEditorProvider.tsx (1 hunks)
  • packages/visual-editor/src/utils/imagePlaceholders.ts (1 hunks)
  • packages/visual-editor/src/vite-plugin/defaultLayoutData.ts (16 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/visual-editor/src/internal/components/LayoutEditor.tsx (1)
packages/visual-editor/src/internal/hooks/layout/useMessageReceivers.ts (1)
  • useLayoutMessageReceivers (22-108)
🔇 Additional comments (4)
packages/visual-editor/src/utils/imagePlaceholders.ts (1)

5-7: Placeholder image IDs updated to fixed width look good

Appending w=1000 to the base IDs keeps behavior identical while constraining intrinsic size; matches the PR goal of lighter placeholder assets. No issues from this change in the existing URL-construction logic.

packages/visual-editor/src/internal/hooks/layout/useMessageReceivers.ts (1)

103-107: Exposing setLayoutSaveState from the hook is appropriate

Returning setLayoutSaveState alongside layoutSaveState / layoutSaveStateFetched cleanly enables external flows (publish, clear history) to reset the save state without changing existing behavior.

packages/visual-editor/src/internal/components/LayoutEditor.tsx (2)

62-63: Extending useLayoutMessageReceivers usage to include the setter looks correct

Wiring setLayoutSaveState through from useLayoutMessageReceivers(localDev, puckConfig, streamDocument) is consistent with the hook’s return shape and enables the new flows below without changing existing consumers.


290-290: Prop wiring to InternalLayoutEditor updated correctly to use handlePublish

Switching the publishLayout prop to pass handlePublish ensures the new “reset save state then publish” behavior is applied wherever InternalLayoutEditor triggers a publish, without changing its public API. This looks consistent with the rest of the component.

Copy link
Collaborator

@mkilpatrick mkilpatrick left a comment

Choose a reason for hiding this comment

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

LG. If we get other images for header/footer that can be a separate PR if you want to close this one out.

@benlife5
Copy link
Contributor Author

Confirmed with Ming that this is what we want for the Team Section. Header/Footer logo still pending, will open new PR if that is resolved.

@benlife5 benlife5 merged commit 2b73006 into main Dec 11, 2025
16 checks passed
@benlife5 benlife5 deleted the tab-slowness branch December 11, 2025 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

create-dev-release Triggers dev release workflow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants