Skip to content

Conversation

@judofyr
Copy link
Contributor

@judofyr judofyr commented Nov 27, 2025

Description

This adds a "pauser" into the descriptor converter which avoids blocking the UI by scheduling idle callbacks. See the comment in the code for justification and potential follow-up work.

What to review

This PR.

Testing

N/A.

Notes for release

N/A. Internal only at the moment.

@vercel
Copy link

vercel bot commented Nov 27, 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 Dec 1, 2025 2:54pm
test-studio Ready Ready Preview Comment Dec 1, 2025 2:54pm
3 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
e2e-studio Ignored Ignored Dec 1, 2025 2:54pm
studio-workshop Ignored Ignored Preview Dec 1, 2025 2:54pm
test-next-studio Ignored Ignored Dec 1, 2025 2:54pm

@github-actions
Copy link
Contributor

github-actions bot commented Nov 27, 2025

🧪 E2E Preview environment

🔑 Environment Variables for Local Testing

This is the preview URL for the E2E tests: https://e2e-studio-1ga9prpa2.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-1ga9prpa2.sanity.dev
  SANITY_E2E_DATASET="update depending the project you want to test (pr-11310-chromium-19826878628 || pr-11310-firefox-19826878628 )"
  SANITY_E2E_DATASET_CHROMIUM=pr-11310-chromium-19826878628
  SANITY_E2E_DATASET_FIREFOX=pr-11310-firefox-19826878628

@github-actions
Copy link
Contributor

github-actions bot commented Nov 27, 2025

📊 Playwright Test Report

Download Full E2E Report

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

@judofyr judofyr self-assigned this Nov 27, 2025
@judofyr judofyr marked this pull request as ready for review November 27, 2025 14:21
@judofyr judofyr requested a review from a team as a code owner November 27, 2025 14:21
@judofyr judofyr requested review from dcilke and pedrobonamin and removed request for a team November 27, 2025 14:21
@github-actions
Copy link
Contributor

github-actions bot commented Nov 27, 2025

⚡️ Editor Performance Report

Updated Mon, 01 Dec 2025 15:08:27 GMT

Benchmark reference
latency of sanity@latest
experiment
latency of this branch
Δ (%)
latency difference
article (title) 23.8 efps (42ms) 21.1 efps (48ms) +6ms (+13.1%)
article (body) 24.1 efps (42ms) 29.0 efps (35ms) -7ms (-17.0%)
article (string inside object) 26.0 efps (39ms) 22.2 efps (45ms) +7ms (+16.9%)
article (string inside array) 21.7 efps (46ms) 19.2 efps (52ms) +6ms (+13.0%)
recipe (name) 41.7 efps (24ms) 39.2 efps (26ms) +2ms (+6.3%)
recipe (description) 55.6 efps (18ms) 55.6 efps (18ms) +0ms (-/-%)
recipe (instructions) 99.9+ efps (7ms) 90.9 efps (11ms) +4ms (-/-%)
singleString (stringField) 50.0 efps (20ms) 52.6 efps (19ms) -1ms (-5.0%)
synthetic (title) 15.9 efps (63ms) 15.7 efps (64ms) +1ms (+0.8%)
synthetic (string inside object) 16.4 efps (61ms) 15.4 efps (65ms) +4ms (+6.6%)

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) 42ms 49ms 58ms 105ms 30ms 10.5s
article (body) 42ms 66ms 106ms 159ms 242ms 7.6s
article (string inside object) 39ms 41ms 55ms 117ms 0ms 6.4s
article (string inside array) 46ms 54ms 87ms 121ms 55ms 6.9s
recipe (name) 24ms 27ms 30ms 46ms 0ms 7.1s
recipe (description) 18ms 21ms 23ms 27ms 0ms 4.3s
recipe (instructions) 7ms 13ms 15ms 44ms 0ms 3.4s
singleString (stringField) 20ms 22ms 24ms 48ms 0ms 6.6s
synthetic (title) 63ms 65ms 72ms 204ms 432ms 16.1s
synthetic (string inside object) 61ms 68ms 118ms 277ms 637ms 8.2s

🧪 Experiment result

The performance result of this branch

Benchmark latency p75 p90 p99 blocking time test duration
article (title) 48ms 54ms 87ms 139ms 60ms 10.3s
article (body) 35ms 40ms 93ms 175ms 161ms 7.3s
article (string inside object) 45ms 52ms 67ms 127ms 31ms 6.8s
article (string inside array) 52ms 57ms 67ms 159ms 52ms 7.1s
recipe (name) 26ms 31ms 44ms 102ms 9ms 7.4s
recipe (description) 18ms 22ms 27ms 40ms 0ms 4.4s
recipe (instructions) 11ms 12ms 15ms 28ms 0ms 3.3s
singleString (stringField) 19ms 22ms 30ms 46ms 0ms 6.4s
synthetic (title) 64ms 68ms 119ms 175ms 603ms 14.5s
synthetic (string inside object) 65ms 69ms 121ms 138ms 435ms 8.1s

📚 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 27, 2025

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 44.46% 64004 / 143945
🔵 Statements 44.46% 64004 / 143945
🔵 Functions 48.35% 3416 / 7065
🔵 Branches 79.28% 13000 / 16397
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/@sanity/schema/src/descriptors/convert.ts 93.45% 88.81% 96.29% 93.45% 105, 423-424, 516-517, 525-533, 553-554, 567-574, 630-631, 645-646, 664, 674, 684, 692, 704, 718, 726, 736, 742, 744, 770-771
packages/@sanity/schema/src/descriptors/scheduler.ts 21.73% 80% 75% 21.73% 16-84
packages/sanity/src/core/config/uploadSchema.ts 38.96% 41.66% 100% 38.96% 21-22, 76-81, 87-135
Generated in workflow #46803 for commit 316b1e2 by the Vitest Coverage Report Action

@judofyr judofyr force-pushed the cldx-4355/avoid-blocking-ui branch from 457a4a7 to 24cc74c Compare November 28, 2025 13:04
@judofyr judofyr requested a review from dcilke November 28, 2025 13:05
@judofyr
Copy link
Contributor Author

judofyr commented Nov 28, 2025

I've now slightly tweaked it:

  • Adding a "scheduler" interface so that outside of the browser (i.e. sanity schema validate) we don't unnecessarily use idle callbacks.
  • Add more higher level methods for "doing work" instead of "pausing".
  • Avoid pausing when it's been too short since the last pause.
  • Fixed a bug with the duration recording.

dcilke
dcilke previously approved these changes Dec 1, 2025
Comment on lines +101 to +106
let idleScheduler: IdleScheduler | undefined
const scheduler =
opts?.scheduler ||
(opts?.pauseDurations
? (idleScheduler = new IdleScheduler(opts.pauseDurations))
: SYNC_SCHEDULER)
Copy link
Member

Choose a reason for hiding this comment

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

Personally, I think having just the scheduler as an option is a cleaner API

@judofyr judofyr force-pushed the cldx-4355/async-descriptor-converter branch from e8af851 to 952b964 Compare December 1, 2025 08:07
@judofyr judofyr force-pushed the cldx-4355/avoid-blocking-ui branch from 24cc74c to 81e3e78 Compare December 1, 2025 08:07
@judofyr judofyr force-pushed the cldx-4355/async-descriptor-converter branch 2 times, most recently from d2f3775 to 8078eab Compare December 1, 2025 14:38
@judofyr judofyr force-pushed the cldx-4355/avoid-blocking-ui branch from 81e3e78 to d0673b2 Compare December 1, 2025 14:38
@judofyr judofyr changed the base branch from cldx-4355/async-descriptor-converter to graphite-base/11310 December 1, 2025 14:53
@judofyr judofyr force-pushed the graphite-base/11310 branch from 8078eab to 7c1fc4d Compare December 1, 2025 14:53
@judofyr judofyr force-pushed the cldx-4355/avoid-blocking-ui branch from d0673b2 to 9dcef2e Compare December 1, 2025 14:53
@graphite-app graphite-app bot changed the base branch from graphite-base/11310 to main December 1, 2025 14:54
@graphite-app graphite-app bot dismissed dcilke’s stale review December 1, 2025 14:54

The base branch was changed.

This adds a "pauser" into the descriptor converter which avoids blocking
the UI by scheduling idle callbacks. See the comment in the code for
justification and potential follow-up work.
@judofyr judofyr merged commit 2826615 into main Dec 1, 2025
63 of 64 checks passed
@judofyr judofyr deleted the cldx-4355/avoid-blocking-ui branch December 1, 2025 15:22
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.

4 participants