Skip to content

Conversation

@jordanl17
Copy link
Member

@jordanl17 jordanl17 commented Nov 17, 2025

Description

Some issues occur with arrays of objects when the field is wrapped within a controlled visibility parent. eg. if wrapped in a sanity/ui's TabPanel where the recommended approach is to control the hidden prop (https://www.sanity.io/ui/docs/component/tab#tab-panel).

The issue is that virtualization of the array of objects is done based on the initial render. If the field is hidden, that screws up the sizing calculations.

This PR adds a new hook, which uses ReziseObserver to detect when the array of objects field changes visibility and will then re-mount the component to ensure accurate virtualization

What to review

Testing

Before:
arrayOfObjsVirtBeforePR
[Scrolling along with some other interactions like drag/drop, would trigger a resize and would resolve the issue on completion]

After:
arrayOfObjsVirtAfterPR

Notes for release

Fixes as issue where arrays of objects would sometimes not show all items in the list of objects when rendered within a visibility controlled parent.

@jordanl17 jordanl17 changed the title feat: implement virtualized array list with visibility detection when ancestors change hidden state fix: implement virtualized array list with visibility detection when ancestors change hidden state Nov 17, 2025
@vercel
Copy link

vercel bot commented Nov 17, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
page-building-studio Ready Ready Preview Comment Nov 18, 2025 0:15am
test-studio Ready Ready Preview Comment Nov 18, 2025 0:15am
3 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
e2e-studio Ignored Ignored Nov 18, 2025 0:15am
studio-workshop Ignored Ignored Preview Nov 18, 2025 0:15am
test-next-studio Ignored Ignored Nov 18, 2025 0:15am

@github-actions
Copy link
Contributor

github-actions bot commented Nov 17, 2025

🧪 E2E Preview environment

🔑 Environment Variables for Local Testing

This is the preview URL for the E2E tests: https://e2e-studio-1ez3hjvlu.sanity.dev

To run the E2E tests locally, you can use the following environment variables, then run pnpm test:e2e --ui to open the Playwright test runner.

💬 Remember to build the project first with pnpm build:e2e.

  SANITY_E2E_PROJECT_ID=ittbm412
  SANITY_E2E_BASE_URL=https://e2e-studio-1ez3hjvlu.sanity.dev
  SANITY_E2E_DATASET="update depending the project you want to test (pr-11166-chromium-19465557468 || pr-11166-firefox-19465557468 )"
  SANITY_E2E_DATASET_CHROMIUM=pr-11166-chromium-19465557468
  SANITY_E2E_DATASET_FIREFOX=pr-11166-firefox-19465557468

@github-actions
Copy link
Contributor

🧪 E2E Preview environment

Waiting for preview deployment to finish…

@github-actions
Copy link
Contributor

github-actions bot commented Nov 17, 2025

📊 Playwright Test Report

Download Full E2E Report

This report contains test results, including videos of failing tests.

@github-actions
Copy link
Contributor

📊 Playwright Test Report

Waiting for E2E tests to finish…

@github-actions
Copy link
Contributor

github-actions bot commented Nov 17, 2025

⚡️ Editor Performance Report

Updated Tue, 18 Nov 2025 20:17:50 GMT

Benchmark reference
latency of sanity@latest
experiment
latency of this branch
Δ (%)
latency difference
article (title) 28.2 efps (36ms) 27.0 efps (37ms) +2ms (+4.2%)
article (body) 38.8 efps (26ms) 36.7 efps (27ms) +1ms (+5.8%)
article (string inside object) 28.6 efps (35ms) 28.6 efps (35ms) +0ms (-/-%)
article (string inside array) 25.0 efps (40ms) 23.0 efps (44ms) +4ms (+8.8%)
recipe (name) 52.6 efps (19ms) 47.6 efps (21ms) +2ms (+10.5%)
recipe (description) 60.6 efps (17ms) 58.8 efps (17ms) +1ms (+3.0%)
recipe (instructions) 99.9+ efps (5ms) 99.9+ efps (6ms) +1ms (-/-%)
singleString (stringField) 66.7 efps (15ms) 66.7 efps (15ms) +0ms (-/-%)
synthetic (title) 17.5 efps (57ms) 17.9 efps (56ms) -1ms (-1.8%)
synthetic (string inside object) 17.9 efps (56ms) 18.9 efps (53ms) -3ms (-5.4%)

efps — editor "frames per second". The number of updates assumed to be possible within a second.

Derived from input latency. efps = 1000 / input_latency

Detailed information

🏠 Reference result

The performance result of sanity@latest

Benchmark latency p75 p90 p99 blocking time test duration
article (title) 36ms 43ms 68ms 83ms 44ms 9.8s
article (body) 26ms 31ms 63ms 103ms 81ms 5.7s
article (string inside object) 35ms 38ms 41ms 93ms 0ms 5.8s
article (string inside array) 40ms 42ms 48ms 89ms 2ms 6.4s
recipe (name) 19ms 22ms 24ms 51ms 0ms 6.5s
recipe (description) 17ms 18ms 21ms 40ms 0ms 4.3s
recipe (instructions) 5ms 9ms 11ms 13ms 0ms 3.0s
singleString (stringField) 15ms 17ms 19ms 35ms 0ms 6.0s
synthetic (title) 57ms 60ms 70ms 165ms 518ms 14.7s
synthetic (string inside object) 56ms 58ms 85ms 185ms 490ms 7.8s

🧪 Experiment result

The performance result of this branch

Benchmark latency p75 p90 p99 blocking time test duration
article (title) 37ms 51ms 76ms 86ms 27ms 10.0s
article (body) 27ms 32ms 69ms 109ms 119ms 6.1s
article (string inside object) 35ms 39ms 59ms 92ms 0ms 6.0s
article (string inside array) 44ms 50ms 73ms 99ms 100ms 6.7s
recipe (name) 21ms 23ms 28ms 46ms 0ms 6.4s
recipe (description) 17ms 20ms 23ms 48ms 0ms 4.4s
recipe (instructions) 6ms 10ms 11ms 25ms 0ms 3.0s
singleString (stringField) 15ms 17ms 19ms 31ms 0ms 5.7s
synthetic (title) 56ms 59ms 77ms 222ms 670ms 14.7s
synthetic (string inside object) 53ms 55ms 61ms 195ms 368ms 7.5s

📚 Glossary

column definitions

  • benchmark — the name of the test, e.g. "article", followed by the label of the field being measured, e.g. "(title)".
  • latency — the time between when a key was pressed and when it was rendered. derived from a set of samples. the median (p50) is shown to show the most common latency.
  • p75 — the 75th percentile of the input latency in the test run. 75% of the sampled inputs in this benchmark were processed faster than this value. this provides insight into the upper range of typical performance.
  • p90 — the 90th percentile of the input latency in the test run. 90% of the sampled inputs were faster than this. this metric helps identify slower interactions that occurred less frequently during the benchmark.
  • p99 — the 99th percentile of the input latency in the test run. only 1% of sampled inputs were slower than this. this represents the worst-case scenarios encountered during the benchmark, useful for identifying potential performance outliers.
  • blocking time — the total time during which the main thread was blocked, preventing user input and UI updates. this metric helps identify performance bottlenecks that may cause the interface to feel unresponsive.
  • test duration — how long the test run took to complete.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 17, 2025

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 44.61% 63572 / 142481
🔵 Statements 44.61% 63572 / 142481
🔵 Functions 48.32% 3396 / 7027
🔵 Branches 79.36% 12918 / 16277
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/sanity/src/core/form/inputs/arrays/ArrayOfObjectsInput/List/ListArrayInput.tsx 13.54% 100% 0% 13.54% 19-135
packages/sanity/src/core/form/inputs/arrays/ArrayOfObjectsInput/List/VirtualizedArrayList.tsx 5.33% 100% 0% 5.33% 46-239
packages/sanity/src/core/form/inputs/arrays/ArrayOfObjectsInput/List/useVisibilityDetection.ts 7.69% 100% 0% 7.69% 10-42
Generated in workflow #45761 for commit 3f09093 by the Vitest Coverage Report Action

Copy link
Member Author

Choose a reason for hiding this comment

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

This is mostly just what was removed from ListArrayInput. Abstracted to a separate component since it was being rendered in 2 different places now within ListArrayInput

@jordanl17 jordanl17 force-pushed the fix/virtualized-hidden-pane-changes branch from ad3079d to 3f09093 Compare November 18, 2025 12:06
@jordanl17 jordanl17 marked this pull request as ready for review November 18, 2025 20:32
@jordanl17 jordanl17 requested a review from a team as a code owner November 18, 2025 20:32
@jordanl17 jordanl17 requested review from juice49 and stipsan and removed request for a team November 18, 2025 20:32
Copy link
Member

@stipsan stipsan left a comment

Choose a reason for hiding this comment

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

A very nice fix indeed :chefs-kiss:

@jordanl17 jordanl17 merged commit fe0e624 into main Nov 19, 2025
77 of 84 checks passed
@jordanl17 jordanl17 deleted the fix/virtualized-hidden-pane-changes branch November 19, 2025 15:04
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.

3 participants