Intent to Experiment: Increased max nesting level for setTimeout(0)

475 views
Skip to first unread message

Etienne Pierre-doray

unread,
Mar 28, 2022, 3:36:30 PM3/28/22
to blink-dev, Scott Haseley

Contact emails

etie...@chromium.org

Explainer

None

Specification

https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html

Design docs


https://docs.google.com/document/d/1boT0k8BQjl7mXXzvI9SdN4XJPSza27vE8T0CNxmMhCI

Summary

Increase the nesting threshold before which setTimeout(..., <4ms) start being clamped, from 5 to 100. setTimeout(..., 0) is commonly used to break down long Javascript tasks and let other internal tasks run, which prevents the browser from hanging. setTimeouts and setIntervals with an interval < 4ms are not clamped as aggressively as they were before. This improves short horizon performance, but websites abusing the API will still eventually have their set setTimeouts clamped



Blink component

Blink

TAG review



TAG review status

Not applicable

Risks



Interoperability and Compatibility

setTimeout is a well established and mature API. This change poses a risk of breaking websites and tests that rely on the current timing caused by clamping and the subtle task ordering that it entails. As an example, this change breaks assumptions about the ordering between setTimeout(0) and unrelated tasks in at least one case in Chrome tests (crbug.com/1302309). On the flip side, the implementation in Chrome is already non compliant (crbug.com/1108877). There's also a similar experiment on beta that is ongoing (crbug.com/1263190). Devs can use chrome://flags#unthrottled-nested-timeout to test their sites for compatibility issues.



Gecko: No signal

WebKit: No signal

Web developers: No signals

Other signals:

WebView Application Risks

Does this intent deprecate or change behavior of existing APIs, such that it has potentially high risk for Android WebView-based applications?



Goals for experimentation

Gain insight on potential compatibility issues and evaluate impact on guardian metrics (page load, latency).



Ongoing technical constraints

None



Debuggability

setTimeout() and setInterval() have an associated trace event in DevTools. https://developer.chrome.com/docs/devtools/evaluate-performance/performance-reference/



Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?

Yes

Is this feature fully tested by web-platform-tests?

No

Flag name

unthrottled-nested-timeout

Requires code in //chrome?

False

Tracking bug

https://crbug.com/1108877

Estimated milestones

OriginTrial desktop last102
OriginTrial desktop first101
DevTrial on desktop101
OriginTrial android last102
OriginTrial android first101
DevTrial on android101

Targeting Beta 50% for at least 8 weeks for more chance of teasing out breakage. I'll send a follow-up with what we learn prior to experimenting on Stable.

Link to entry on the Chrome Platform Status

https://chromestatus.com/feature/5710690097561600

Links to previous Intent discussions

Ready for Trial: https://groups.google.com/a/chromium.org/g/blink-dev/c/-TjeYs7shTQ/m/FhJq0mQyDAAJ


This intent message was generated by Chrome Platform Status.

Yoav Weiss

unread,
Mar 30, 2022, 6:00:43 AM3/30/22
to blink-dev, Etienne Pierre-doray, Scott Haseley
LGTM to experiment M101-102 inclusive
Thanks for working on this!! 
What's the plan for finding sites this breaks? Monitor bug reports? Or is there something more proactive we could do?

Etienne Pierre-doray

unread,
Mar 30, 2022, 1:42:04 PM3/30/22
to Yoav Weiss, blink-dev, Scott Haseley
Thanks!
What's the plan for finding sites this breaks? Monitor bug reports? Or is there something more proactive we could do?
I'm thinking about bug reports and guardian metrics. shaseley@ might have additional insight from running a similar experiment crbug.com/1263190

Scott Haseley

unread,
Mar 30, 2022, 2:19:53 PM3/30/22
to Etienne Pierre-doray, Yoav Weiss, blink-dev
On Wed, Mar 30, 2022 at 10:41 AM Etienne Pierre-doray <etie...@chromium.org> wrote:
Thanks!
What's the plan for finding sites this breaks? Monitor bug reports? Or is there something more proactive we could do?
I'm thinking about bug reports and guardian metrics. shaseley@ might have additional insight from running a similar experiment crbug.com/1263190

Yeah that's what I was thinking; that's the approach we're taking for removing setTimeout(0) 1 ms clamping. It would be helpful if devs could try this out and report issues (it's enabled behind a flag). Maybe a console warning message if we hit the nesting level that we plan to increase? I'm not sure how effective that would be in helping get folks to try it.

Etienne Pierre-doray

unread,
May 25, 2022, 2:59:30 PM5/25/22
to Scott Haseley, Yoav Weiss, blink-dev

Hi all,

I'm sharing an update with results of the experiments over 21 days on Chrome Beta M102.

The results below are mostly small percentages changes, and the finch guidelines says to trust results on Stable. Given no issue have been raised AFAIK I would like to roll out a 1% finch experiment on Stable and I'm wondering what would be the required steps to do this (besides flipping boxes on the launch crbug.com/1298967) without amending what the spec says just yet.


The experiment MaxUnthrottledTimeoutNestingLevel has been running on canary/dev/beta M101 and M102.

Another experiment SetTimeoutZeroWithoutClamping which removes setTimeout(,0) clamping to 1 ms is running at Enabled(25%) and Default(50%) on Beta. Analyzing the results for both experiments together makes sense because our goal is to avoid delayed tasks for immediate setTimeout()s.

MaxUnthrottledTimeoutNestingLevel (50% enabled / 50% control) + SetTimeoutZeroWithoutClamping (Default + Enabled is 75%)

Finch Win

No impact on Guiding Metrics

Finch Mac

-15.85% Time To Paint For Each Ad Frame @ 95%ile 2-diamonds

Finch Android

-1.78% First Input Delay @ 99%ile 1-diamonds

-0.74% Time to Largest Contentful Paint @ 99%ile 1-diamonds

-0.79% Cumulative Layout Shift @ 95%ile 2-diamonds

-1.45 / 1.26% Startup Time @ 95 / 99%ile 1 / 2-diamonds

+1.93% Scroll Latency Count 1-diamonds

+0.32% Memory: Renderer@ 50%ile 1-diamonds


MaxUnthrottledTimeoutNestingLevel ignoring SetTimeoutZeroWithoutClamping

Note: Results here are less interesting since our goal is to avoid delayed tasks for immediate setTimeout()s, which is only achieved under SetTimeoutZeroWithoutClamping.

Finch Win

+1.73% Time to First Contentful Paint @ 95%ile 2-diamonds

-1.28% Frame Drawing Interval @ 95%ile 1-diamonds

-1.44% Startup Time @ 99%ile 1-diamonds


Note: the downside of experimenting on Stable is that the intersection of both 1% experiments is very small and we probably won't be able to analyze results alongside before SetTimeoutZeroWithoutClamping ships (this should happen soon though).


Maybe a console warning message if we hit the nesting level that we plan to increase? I'm not sure how effective that would be in helping get folks to try it.
I'm trying this out here.

François Doray

unread,
Feb 16, 2023, 4:18:41 PM2/16/23
to blink-dev, Etienne Pierre-doray, Yoav Weiss, blink-dev, Scott Haseley, Jake Archibald
The change to the nesting level at which 4ms clamping kicks in (MaxUnthrottledTimeoutNestingLevel) never shipped, because Speedometer 2.1 is not affected by it like Speedometer 2.0 was. However, WebKit did implement this change: https://sourcegraph.com/github.com/WebKit/WebKit/-/commit/786e3e0b252e38fb01c8db97a94d52cb0f57891e and Chrome updated its documentation: https://github.com/GoogleChrome/developer.chrome.com/commit/b6529b1cc8fdd9b2cb3496f446ee332207ab40b2 even though it did not ship the change.

What do Blink owners recommend as next step for this?

Yoav Weiss

unread,
Feb 20, 2023, 2:38:12 AM2/20/23
to François Doray, blink-dev, Etienne Pierre-doray, Scott Haseley, Jake Archibald
Did the experimentation show any positive or negative impact on real-life content?

On Thu, Feb 16, 2023 at 10:18 PM François Doray <fdo...@google.com> wrote:
The change to the nesting level at which 4ms clamping kicks in (MaxUnthrottledTimeoutNestingLevel) never shipped, because Speedometer 2.1 is not affected by it like Speedometer 2.0 was. However, WebKit did implement this change: https://sourcegraph.com/github.com/WebKit/WebKit/-/commit/786e3e0b252e38fb01c8db97a94d52cb0f57891e and Chrome updated its documentation: https://github.com/GoogleChrome/developer.chrome.com/commit/b6529b1cc8fdd9b2cb3496f446ee332207ab40b2 even though it did not ship the change.

What do Blink owners recommend as next step for this?

Does the current spec match reality? (where this value is UA defined)
If not, maybe that's the easiest way to provide clarity on this point, if WebKit is shipping one thing and Chromium does another. Also - where does Gecko stand on this?

Etienne Pierre-doray

unread,
Feb 20, 2023, 12:46:17 PM2/20/23
to Yoav Weiss, François Doray, blink-dev, Scott Haseley, Jake Archibald
Did the experimentation show any positive or negative impact on real-life content?
On windows, the only significant impact we saw in the field is a regression on Input Delay (Page Load), 5.20% at 95th %ile. No improvement otherwise, so I don't see any benefits of going forward with this anymore.

Does the current spec match reality? (where this value is UA defined)
No. The spec seems to say "if > 5", Blink and Gecko do "if >= 4" which is off by 2 (crbug.com/1108877).
WebKit used to do "if >= 5", but recently changed it to "if >= 10".

where does Gecko stand on this
I tested this with the code snippet from crbug.com/1108877. This gives me the same result as Chrome.

If not, maybe that's the easiest way to provide clarity on this point, if WebKit is shipping one thing and Chromium does another.
Does this mean changing the spec to make it looser re. the threshold value? 

Yoav Weiss

unread,
Feb 20, 2023, 12:56:08 PM2/20/23
to Etienne Pierre-doray, Domenic Denicola, François Doray, blink-dev, Scott Haseley, Jake Archibald
On Mon, Feb 20, 2023 at 6:46 PM Etienne Pierre-doray <etie...@chromium.org> wrote:
Did the experimentation show any positive or negative impact on real-life content?
On windows, the only significant impact we saw in the field is a regression on Input Delay (Page Load), 5.20% at 95th %ile. No improvement otherwise, so I don't see any benefits of going forward with this anymore.

Does the current spec match reality? (where this value is UA defined)
No. The spec seems to say "if > 5", Blink and Gecko do "if >= 4" which is off by 2 (crbug.com/1108877).
WebKit used to do "if >= 5", but recently changed it to "if >= 10".

where does Gecko stand on this
I tested this with the code snippet from crbug.com/1108877. This gives me the same result as Chrome.

If not, maybe that's the easiest way to provide clarity on this point, if WebKit is shipping one thing and Chromium does another.
Does this mean changing the spec to make it looser re. the threshold value? 

+Domenic Denicola can correct me if I'm wrong here, but it seems like we may want to make that value implementer-defined.
Alternatively, we can modify the spec to match what Chrome and Gecko are doing, and try to convince WebKit folks to align.

Gregg Tavares

unread,
Feb 21, 2023, 1:37:19 PM2/21/23
to Yoav Weiss, Etienne Pierre-doray, Domenic Denicola, François Doray, blink-dev, Scott Haseley, Jake Archibald
What is the point of this throttling given the workarounds (postMessage?) or maybe postMessage is going to be throttled?

I've used this to make something that takes a long time not freeze the browser

const wait = _ => new Promise(resolve => setTimeout(resolve));

for (many-operations) {
   doOperation();
   await wait();
}

When I found out setTimeout slowed things down too much I first changed it to only call wait every N operations. That sucked since what to set N do was ambiguous. I thought about changing to only calling `wait` if so much time had passed. Eventually I just changed `wait` call `postMessage` and resolve on receiving the message. The throttling disappeared, which made me wonder what the point of the throttling was in the first place given it's trivial to workaround.








--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CAL5BFfWAZZbGjJpLAAc6C3ohZ4ChJZioPt1vG3wqBPxE5ViLZA%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages