Skip to content

Add styleDuration, layoutDuration, forcedStyleDuration, and forcedLayoutDuration#30

Open
yoavweiss wants to merge 2 commits intomainfrom
style_duration
Open

Add styleDuration, layoutDuration, forcedStyleDuration, and forcedLayoutDuration#30
yoavweiss wants to merge 2 commits intomainfrom
style_duration

Conversation

@yoavweiss
Copy link
Copy Markdown
Contributor

@yoavweiss yoavweiss commented Jan 19, 2026

This PR adds the styleDuration and layoutDuration attributes to PerformanceLongAnimationFrameTiming and the forcedStyleDuration and forcedLayoutDuration attributes to PerformanceScriptTiming.

This would enable developers to distinguish between the style calculation times and their layout times, which typically have very distinct reasons, and therefore different solutions.

It also includes a couple of tiny unrelated bikeshed fixes.

Currently developers can collect their overall style+layout costs using something like the following:

const totalStyleCost = async () => {
  return new Promise(resolve => {
    let total = 0;
    (new PerformanceObserver(entryList => {
      const entries = entryList.getEntries();
      for (const entry of entries) {
          if (entry.paintTime) {
              total += entry.paintTime - entry.styleAndLayoutStart;
          } else {
              total += entry.startTime + entry.duration - entry.styleAndLayoutStart;
          }
          for (const script of entry.scripts) {
              total += script.forcedStyleAndLayoutDuration;
          }
      }
      resolve(total);
    })).observe({type: "long-animation-frame", buffered: true});
  });
}

This feature will enable developers to collect their overall style calculation time and layout time separately, using:

const totalStyleAndLayoutCost = async () => {                                              
    return new Promise(resolve => {                                                                                                                                                                                 
      let totalStyle = 0;                                                                                                                                                                                           
      let totalLayout = 0;                                                                                                                                                                                          
      (new PerformanceObserver(entryList => {                                                                                                                                                                       
        const entries = entryList.getEntries();                                                                                                                                                                     
        for (const entry of entries) {                                                                                                                                                                              
            totalStyle += entry.styleDuration;                                                                                                                                                                      
            totalLayout += entry.layoutDuration;                                                                                                                                                                    
                                                                                                                                                                                                                    
            for (const script of entry.scripts) {                                                                                                                                                                   
                totalStyle += script.forcedStyleDuration;                                                                                                                                                           
                totalLayout += script.forcedLayoutDuration;                                                                                                                                                         
            }                                                                                                                                                                                                       
        }                                                                                                                                                                                                           
        resolve({totalStyle, totalLayout});                                                                                                                                                                         
      })).observe({type: "long-animation-frame", buffered: true});                                                                                                                                                  
    });                                                                                                                                                                                                             
  }

That would enable them to evaluate e.g. if they need to opt in for cheaper/simpler CSS selectors and reduce their overall number of delivered rules (high style costs), or simplify their DOM structure and
reduce layout-triggering property usage (high layout costs).


Preview | Diff

@yoavweiss yoavweiss requested a review from noamr January 19, 2026 09:44
Comment thread index.bs

The {{PerformanceScriptTiming/forcedStyleDuration}} attribute's getter step is to return an [=implementation-defined=] value that represents time spent performing style recalculation synchronously (without layout), e.g. by calling {{Window/getComputedStyle()}}.

Issue: Find a way to make this interoperable/normative.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hmm need a bit more to go on here.

Copy link
Copy Markdown
Contributor Author

@yoavweiss yoavweiss Jan 19, 2026

Choose a reason for hiding this comment

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

Agree!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thoughts on how we can do that, given the vagueness of the load-bearing "resolved value computed" in https://drafts.csswg.org/cssom/#dom-window-getcomputedstyle?

@emilio
Copy link
Copy Markdown

emilio commented Jan 29, 2026

@yoavweiss This would be a bit weird, I think, with some of the new features that interleave style and layout, right? E.g., consider a container query.

Should the layout we need to do to figure out the container size be counted as style or layout?

Similarly, should the styling we do as a result of a container resize be counted as style or layout?

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Feb 1, 2026
I2P: https://groups.google.com/a/chromium.org/g/blink-dev/c/34JZ4Z_XPXk
Spec PR: w3c/long-animation-frames#30

Change-Id: I7017e3c1ca1443239f19110e708b9841424f666c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7487373
Reviewed-by: Noam Rosenthal <nrosenthal@google.com>
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
Commit-Queue: Yoav Weiss (@Shopify) <yoavweiss@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1577858}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Feb 1, 2026
I2P: https://groups.google.com/a/chromium.org/g/blink-dev/c/34JZ4Z_XPXk
Spec PR: w3c/long-animation-frames#30

Change-Id: I7017e3c1ca1443239f19110e708b9841424f666c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7487373
Reviewed-by: Noam Rosenthal <nrosenthal@google.com>
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
Commit-Queue: Yoav Weiss (@Shopify) <yoavweiss@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1577858}
jenkins-chromium-github-sync Bot pushed a commit to armarok/chromium that referenced this pull request Feb 1, 2026
I2P: https://groups.google.com/a/chromium.org/g/blink-dev/c/34JZ4Z_XPXk
Spec PR: w3c/long-animation-frames#30

Change-Id: I7017e3c1ca1443239f19110e708b9841424f666c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7487373
Reviewed-by: Noam Rosenthal <nrosenthal@google.com>
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
Commit-Queue: Yoav Weiss (@Shopify) <yoavweiss@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1577858}
lando-worker Bot pushed a commit to mozilla-firefox/firefox that referenced this pull request Feb 5, 2026
…uration, a=testonly

Automatic update from web-platform-tests
LoAF: add styleDuration and forcedStyleDuration

I2P: https://groups.google.com/a/chromium.org/g/blink-dev/c/34JZ4Z_XPXk
Spec PR: w3c/long-animation-frames#30

Change-Id: I7017e3c1ca1443239f19110e708b9841424f666c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7487373
Reviewed-by: Noam Rosenthal <nrosenthal@google.com>
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
Commit-Queue: Yoav Weiss (@Shopify) <yoavweiss@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1577858}

--

wpt-commits: 5f73ca676a8df682982723228050896bf8167f84
wpt-pr: 57474
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Mar 5, 2026
Following a WG discussion on
w3c/long-animation-frames#30
The feedback was that layoutDuration exposure is also warranted.

This CL implements that.

I2P: https://groups.google.com/a/chromium.org/g/blink-dev/c/34JZ4Z_XPXk

Change-Id: I0b60908e53a394540307a63fb14b7b36eb53fc46
Bug: 476826067
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7544978
Reviewed-by: Scott Haseley <shaseley@chromium.org>
Commit-Queue: Yoav Weiss (@Shopify) <yoavweiss@chromium.org>
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1594478}
beckysiegel pushed a commit to chromium/chromium that referenced this pull request Mar 5, 2026
Following a WG discussion on
w3c/long-animation-frames#30
The feedback was that layoutDuration exposure is also warranted.

This CL implements that.

I2P: https://groups.google.com/a/chromium.org/g/blink-dev/c/34JZ4Z_XPXk

Change-Id: I0b60908e53a394540307a63fb14b7b36eb53fc46
Bug: 476826067
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7544978
Reviewed-by: Scott Haseley <shaseley@chromium.org>
Commit-Queue: Yoav Weiss (@Shopify) <yoavweiss@chromium.org>
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1594478}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Mar 5, 2026
Following a WG discussion on
w3c/long-animation-frames#30
The feedback was that layoutDuration exposure is also warranted.

This CL implements that.

I2P: https://groups.google.com/a/chromium.org/g/blink-dev/c/34JZ4Z_XPXk

Change-Id: I0b60908e53a394540307a63fb14b7b36eb53fc46
Bug: 476826067
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7544978
Reviewed-by: Scott Haseley <shaseley@chromium.org>
Commit-Queue: Yoav Weiss (@Shopify) <yoavweiss@chromium.org>
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1594478}
shubhamg13 pushed a commit to shubhamg13/wpt that referenced this pull request Mar 6, 2026
Following a WG discussion on
w3c/long-animation-frames#30
The feedback was that layoutDuration exposure is also warranted.

This CL implements that.

I2P: https://groups.google.com/a/chromium.org/g/blink-dev/c/34JZ4Z_XPXk

Change-Id: I0b60908e53a394540307a63fb14b7b36eb53fc46
Bug: 476826067
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7544978
Reviewed-by: Scott Haseley <shaseley@chromium.org>
Commit-Queue: Yoav Weiss (@Shopify) <yoavweiss@chromium.org>
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1594478}
@yoavweiss yoavweiss changed the title Add styleDuration and forcedStyleDuration Add styleDuration, layoutDuration, forcedStyleDuration, and forcedLayoutDuration Mar 6, 2026
@yoavweiss
Copy link
Copy Markdown
Contributor Author

Should the layout we need to do to figure out the container size be counted as style or layout?

I think it should count as layout.

If we increased the duration of layout (e.g. by introducing more complex styling outside the container), this number is likely to go up. Therefore it should be accounted for as "layout".

Similarly, should the styling we do as a result of a container resize be counted as style or layout?

It should count as style, with similar reasoning.

lando-worker Bot pushed a commit to mozilla-firefox/firefox that referenced this pull request Mar 12, 2026
…nd forcedLayoutDuration, a=testonly

Automatic update from web-platform-tests
LongAnimationFrame: add layoutDuration and forcedLayoutDuration

Following a WG discussion on
w3c/long-animation-frames#30
The feedback was that layoutDuration exposure is also warranted.

This CL implements that.

I2P: https://groups.google.com/a/chromium.org/g/blink-dev/c/34JZ4Z_XPXk

Change-Id: I0b60908e53a394540307a63fb14b7b36eb53fc46
Bug: 476826067
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7544978
Reviewed-by: Scott Haseley <shaseley@chromium.org>
Commit-Queue: Yoav Weiss (@Shopify) <yoavweiss@chromium.org>
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1594478}

--

wpt-commits: b6587948af46aba88921f95e87ddb3622eef40f8
wpt-pr: 58279
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