Shopify main-thread yielding and the Core Web Vitals
No yielding API, requestIdleCallback(), scheduler.yield(), isInputPending(), or scheduler.postTask(): how JavaScript-heavy sites break up long tasks and keep Interaction to Next Paint (INP) fast.
On Shopify, 0.3% of sites call no main-thread yielding API. 95.5% use requestIdleCallback() and 4.2% use scheduler.yield(). Across all Shopify sites, 100% without a yielding API have a good INP, compared with 99% for scheduler.yield() and 99% for requestIdleCallback(). Sites without a yielding API load a median of 24 scripts, while scheduler.yield() sites load 98 scripts. Even with that workload, scheduler.yield() holds median Total Blocking Time to 187 ms, against 84 ms for requestIdleCallback().
INP pass rate
Sites with requestIdleCallback() have a good INP most often at 99%, followed by scheduler.yield() at 99%. Both isInputPending() and scheduler.postTask() appear on fewer than 50 sites across the dataset. Pages with little JavaScript do not need a yielding helper, so the raw pass rates mostly reflect how much script each page loads.
Main-thread yielding usage
99.7% of Shopify sites call a main-thread yielding API, while 0.3% run scripts without one. Among the sites that yield, 96% (7,878 sites) use requestIdleCallback() and 4% (343 sites) use scheduler.yield().
JavaScript workload by yielding strategy
Yielding APIs appear on pages with heavy JavaScript bundles. Sites with no yielding API load a median of 24 scripts and spend 629 ms in CPU scripting (31 ms Total Blocking Time). Sites using requestIdleCallback() load 83 scripts and spend 1035 ms in scripting, which pushes median Total Blocking Time to 84 ms. Sites using scheduler.yield() load a median of 98 scripts (1845 ms scripting). Breaking up those tasks keeps median Total Blocking Time at 187 ms, and 99% have a good INP.
INP pass rate by total script count
Six in ten scheduler.yield() sites load 66 or more scripts. On those heavy pages, 99% of scheduler.yield() sites have a good INP with a 220 ms median Total Blocking Time. Sites on requestIdleCallback() drop to 99% (142 ms TBT), and sites without yielding sit at 100% (34 ms TBT).
| Scripts on page | scheduler.yield() | requestIdleCallback() | No yielding API |
|---|---|---|---|
| 1 to 15 scripts | few sites | few sites | few sites |
| 16 to 35 scripts | few sites | 100% 21 sites | few sites |
| 36 to 65 scripts | 100% 34 sites | 100% 2,030 sites | few sites |
| 66 or more scripts | 99% 309 sites | 99% 5,817 sites | few sites |
Main-thread yielding per framework
jQuery uses requestIdleCallback() on 95% of its sites, and 99% of jQuery sites have a good INP.
Main-thread yielding or the framework
Why scheduler.yield() resumes faster than setTimeout or requestIdleCallback()
When a script yields with setTimeout(fn, 0) or requestIdleCallback(), the remaining work goes to the back of the task queue. Any queued timer, third-party tracker, or network callback runs before your function continues. scheduler.yield() pauses the current task so the browser can handle input and paint the next frame, then resumes your code ahead of regular tasks. On script-heavy sites (98 median scripts), that holds median Total Blocking Time to 187 ms, against 84 ms on sites using requestIdleCallback().
Understanding main-thread yielding
Break up long JavaScript tasks (over 50 ms) with await scheduler.yield(), and fall back to setTimeout(resolve, 0) in browsers that do not support it yet. Keep requestIdleCallback() for background work like analytics batching, never inside an interaction handler. Across this dataset, sites with no yielding API score 100% good INP because they only load a median of 24 scripts (31 ms Total Blocking Time). Sites using scheduler.yield() load a median of 98 scripts. On pages with 66 or more scripts, scheduler.yield() reaches 99% good INP and 220 ms TBT, ahead of requestIdleCallback() at 99% good INP (142 ms TBT) and 34 ms TBT without yielding.
By Arjen Karel · 8,246 crawled Shopify sites (3,818 with desktop Chrome field data, October 2026). How we measured.