From 2a6de19197c70f9b91234dd5391f8af9253cb9f1 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Mon, 3 Feb 2025 15:30:02 -0800 Subject: [PATCH 01/28] Create explainer.md --- fps/explainer.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 fps/explainer.md diff --git a/fps/explainer.md b/fps/explainer.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/fps/explainer.md @@ -0,0 +1 @@ + From 17cce5e537992ec0991509aa593cc40247e8109f Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Mon, 3 Feb 2025 15:39:36 -0800 Subject: [PATCH 02/28] Update explainer.md --- fps/explainer.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/fps/explainer.md b/fps/explainer.md index 8b1378917..08087c3b4 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -1 +1,41 @@ +# An API for a more Precise Measurement of Browser Frame Rate + +[comment]: < ** (*Same-Origin*) > + +Authors: [Jenna Sasson](https://github.com/jenna-sasson) + +## Status of this Document +This document is a starting point for engaging the community and standards bodies in developing collaborative solutions fit for standardization. As the solutions to problems described in this document progress along the standards-track, we will retain this document as an archive and use this section to keep the community up-to-date with the most current standards venue and content location of future work and discussions. +* This document status: **Active** +* Expected venue: [W3C Web Performance Working Group](https://www.w3.org/groups/wg/webperf/) +* **Current version: this document** + +## Introduction +Animation frames are rendered on the screen when there is a change that needs to be updated. Ideally, these frames are completed in a certain amount of time. If they are not updated in time, the browser drops a frame,. For the user, this looks like remaining on the same frame for longer, but it some instances, it may not even be noticeable. + +requestAnimationFrame() polling can help decipher whether or not a frame has been dropped. The method works by having the browser call a function (rAF) to update the animation before the screen refreshes (paint stage). Keeping track of the number of times rAF is called provides a count for the number of frames being shown per second, which helps understand the smoothness of the browser's animation. If the browser does not call the function, that is an indicator that a frame was dropped. + +In the past, Edge had a library for this purpose called fps-emitter. While that is a helpful way to measure events that slow down performance, it is not the most precise way to measure the actual framerate. Using the rAF method can actually slow down performance because it creates more tasks for the browser on the main thread. The extra work can cause the frame to drop by not executing before the deadline. An increase in dropped frames causes a less smooth animation. + +Our goal is to create an API for a more precise measure of browser frame rate. Prototyping an API that measures framerate more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF. + + + +## Goals +* Bullet 1 +* +## Non-goals + +## Use Cases +### Keep it general + + + +## Proposed Solution + + +## Glossary + +## Acknowledgements + From 92adca0e96b9036efb575e2730af4f84b4402af8 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Tue, 4 Feb 2025 13:45:29 -0800 Subject: [PATCH 03/28] Update explainer.md --- fps/explainer.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fps/explainer.md b/fps/explainer.md index 08087c3b4..93bf3506e 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -15,16 +15,21 @@ Animation frames are rendered on the screen when there is a change that needs to requestAnimationFrame() polling can help decipher whether or not a frame has been dropped. The method works by having the browser call a function (rAF) to update the animation before the screen refreshes (paint stage). Keeping track of the number of times rAF is called provides a count for the number of frames being shown per second, which helps understand the smoothness of the browser's animation. If the browser does not call the function, that is an indicator that a frame was dropped. -In the past, Edge had a library for this purpose called fps-emitter. While that is a helpful way to measure events that slow down performance, it is not the most precise way to measure the actual framerate. Using the rAF method can actually slow down performance because it creates more tasks for the browser on the main thread. The extra work can cause the frame to drop by not executing before the deadline. An increase in dropped frames causes a less smooth animation. +In the past, Edge had a library for this purpose called fps-emitter. While that is a helpful way to measure events that slow down performance, it is not the most precise way to measure the actual framerate. This is because there are other processes executing independently to render the animation, which can impact fps and can't be detected just by looking at rAF calls. + +Using the rAF method can actually slow down performance because it creates more tasks for the browser on the main thread. The extra work can cause the frame to drop by not executing before the deadline. An increase in dropped frames causes a less smooth animation. Our goal is to create an API for a more precise measure of browser frame rate. Prototyping an API that measures framerate more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF. ## Goals -* Bullet 1 -* +* Create an API that measures frame rate more accurately +* Ensure that our solution does not slow down performance + ## Non-goals +* Former solutions to calculate fps have used rAF polling. We do not want to rely on rAF polling. +* We are not trying to increase fps, or improve animation, rather measure fps so we can solve other performance issues in the future ## Use Cases ### Keep it general From a4ded23360792df5dad794933aa3e1aa638aa987 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Tue, 4 Feb 2025 13:46:22 -0800 Subject: [PATCH 04/28] Update explainer.md --- fps/explainer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fps/explainer.md b/fps/explainer.md index 93bf3506e..013bd8303 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -1,4 +1,4 @@ -# An API for a more Precise Measurement of Browser Frame Rate +# A More Precise Way to Measure Frames per Second (fps) [comment]: < ** (*Same-Origin*) > From 2b46815226c72818040b185ad917aefe14f1c56e Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Wed, 5 Feb 2025 14:54:10 -0800 Subject: [PATCH 05/28] Update explainer.md --- fps/explainer.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/fps/explainer.md b/fps/explainer.md index 013bd8303..0e360ecbb 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -32,7 +32,21 @@ Our goal is to create an API for a more precise measure of browser frame rate. P * We are not trying to increase fps, or improve animation, rather measure fps so we can solve other performance issues in the future ## Use Cases -### Keep it general + +### 1. Gaming +* Higher frames per second (fps) lead to smoother animations and a more enjoyable gaming experience. However, since (rAF) calls can be affected by how busy the main thread is, this method may overlook animation tasks performed by a compositor thread. Specific metrics can significantly impact gameplay elements, like how quickly characters can move or decisions can be made, which affects the overall user experience. Game developers are constantly striving to make their visuals more consistent and immersive. To guarantee smooth gameplay, developers need to test animations repeatedly. + +### 2. Continuously scrolling or selecting +* FPS can be difficult to measure when relating to user interaction. An average metric isn't always effective because in certain apps, animation begins on a user click. There doesn't need to be a continuous measurement since without a user click, there is no animation. Some examples of this include scrolling a long grid or document, selecting or highlighting large areas of the screen, resizing images, or dragging objects across the screen. + +### 3. Measuring animation and graphics performance of browsers +* The public benchmark, MotionMark, measures how well different browsers render animation. Its score tells users the most complex animation that the browser can render at a certain frame rate. The benchmark is most accurate when it gets the most precise measure of frame rate. Currently, the method using rAF to measure frame rate doesn't reflect the user's actual experience. + +### 4. Testing animation performance on different hardware +* Testing the performance of animation on different hardware/browser combinations may expose performance issues that could not be seem with imprecise metrics. + + + From 0e9a9e0e10988f1d91b622870bd3b89a173f9c23 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Mon, 10 Feb 2025 10:38:26 -0800 Subject: [PATCH 06/28] Update explainer.md --- fps/explainer.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fps/explainer.md b/fps/explainer.md index 0e360ecbb..67394a625 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -24,12 +24,17 @@ Our goal is to create an API for a more precise measure of browser frame rate. P ## Goals -* Create an API that measures frame rate more accurately +* Needs to be queryable from JavaScript +* Capture the user-perceived frame rate accurately * Ensure that our solution does not slow down performance +* Should be able to query the frame rate at any specific point in time, rather than relying on events to indicate changes in frame rate +* Cross-browser compatibility +* Take into account both the main and the compositor thread + ## Non-goals -* Former solutions to calculate fps have used rAF polling. We do not want to rely on rAF polling. -* We are not trying to increase fps, or improve animation, rather measure fps so we can solve other performance issues in the future +* Former solutions to calculate fps have used rAF polling. We do not want to rely on rAF polling. +* We are not trying to increase fps, or improve animation, rather measure fps so we can solve other performance issues in the future ## Use Cases From 4f689ea4414b88a1852f8a25f5502495e81ab352 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Tue, 11 Feb 2025 15:37:56 -0800 Subject: [PATCH 07/28] Update explainer.md --- fps/explainer.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/fps/explainer.md b/fps/explainer.md index 67394a625..27fd3e97c 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -28,9 +28,6 @@ Our goal is to create an API for a more precise measure of browser frame rate. P * Capture the user-perceived frame rate accurately * Ensure that our solution does not slow down performance * Should be able to query the frame rate at any specific point in time, rather than relying on events to indicate changes in frame rate -* Cross-browser compatibility -* Take into account both the main and the compositor thread - ## Non-goals * Former solutions to calculate fps have used rAF polling. We do not want to rely on rAF polling. From 7f8d92b9b2324790baee1aac72be5021563ae4c3 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Tue, 11 Feb 2025 16:07:27 -0800 Subject: [PATCH 08/28] Update explainer.md --- fps/explainer.md | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/fps/explainer.md b/fps/explainer.md index 27fd3e97c..0b43ac24e 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -49,10 +49,27 @@ Our goal is to create an API for a more precise measure of browser frame rate. P - - - -## Proposed Solution +## Proposed Solutions +#### Option 1: Direct Query +This solution would involve querying the frame rate directly. JavaScript would call an API that measures the fps at a specific point in time. To measure the overall frame rate, the API would be called multiple times, using the values to calculate an average frame rate. +* window.framerate() + +#### Option 2: Start and End Markers +JavaScript Performance markers are used to track points in time. In this solution, developers could mark a start and end point on the performance timeline and measure the duration between the two markers, with FPS as a property. +* window.framerate("perfMarker") <- Framerate since that marker +* performance.mark("myMarker") +* performance.measure("myMarker", "endMarker") +* FPS could be a property on performance measure + +#### Option 3: Event Listener +Adding an event listener for frame rate changes would alert developers about large drops in frame rate. Since it would not be necessary to know if the rate drops by a frame or two. Instead, the developer could set the event listener to alert when the frame rate drops by n. Or, similarly to the long task API's duration threshold, the developer could set a min and max fps. The event listener would fire only if the FPS is above the max or below the min. + +## Alternatives Considered +For the event listener scenario, it was determined that using granularity would not give a useful measure of FPS due to lack of detail. The granularity was modeled after the compute pressure API. +* window.addEventListener("frameratechange", (event) =>{doSomething();}) + +## Concerns/Open Questions +1. The user-perceived frame rate is influenced by both the main thread and the compositor thread. Accurate measurement of frame rates must account for both. Since the compositor thread operates independently of the main thread, it can be difficult to get its frame rate data. However, an accurate frame rate measurements needs to take into account both measurements. ## Glossary From 926bbdfaa115884a55d48953d99d91457c09b87e Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Tue, 18 Feb 2025 14:41:20 -0800 Subject: [PATCH 09/28] Update explainer.md --- fps/explainer.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fps/explainer.md b/fps/explainer.md index 0b43ac24e..c599f4dda 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -70,6 +70,8 @@ For the event listener scenario, it was determined that using granularity would ## Concerns/Open Questions 1. The user-perceived frame rate is influenced by both the main thread and the compositor thread. Accurate measurement of frame rates must account for both. Since the compositor thread operates independently of the main thread, it can be difficult to get its frame rate data. However, an accurate frame rate measurements needs to take into account both measurements. +2. Similar to the abandoned [Frame Timing interface](https://wicg.github.io/frame-timing/#introduction). We are currently gathering historical context on how this relates and why it is no longer being pursued. + ## Glossary From 5e653da0e0fe96d10e4e0d1a495c1cb352a2eff3 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Fri, 28 Feb 2025 10:02:30 -0800 Subject: [PATCH 10/28] Update explainer.md --- fps/explainer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fps/explainer.md b/fps/explainer.md index c599f4dda..36f73b95d 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -19,7 +19,7 @@ In the past, Edge had a library for this purpose called fps-emitter. While that Using the rAF method can actually slow down performance because it creates more tasks for the browser on the main thread. The extra work can cause the frame to drop by not executing before the deadline. An increase in dropped frames causes a less smooth animation. -Our goal is to create an API for a more precise measure of browser frame rate. Prototyping an API that measures framerate more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF. +Our goal is to create an API for a more precise measure of browser frame rate, specifically one that captures user-perceived frame rate. Prototyping an API that measures framerate more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF. From cf08754903c5bf3f22a78a0913bc226e6217d321 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Fri, 28 Feb 2025 10:33:44 -0800 Subject: [PATCH 11/28] Update explainer.md --- fps/explainer.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fps/explainer.md b/fps/explainer.md index 36f73b95d..1736108b7 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -42,7 +42,8 @@ Our goal is to create an API for a more precise measure of browser frame rate, s * FPS can be difficult to measure when relating to user interaction. An average metric isn't always effective because in certain apps, animation begins on a user click. There doesn't need to be a continuous measurement since without a user click, there is no animation. Some examples of this include scrolling a long grid or document, selecting or highlighting large areas of the screen, resizing images, or dragging objects across the screen. ### 3. Measuring animation and graphics performance of browsers -* The public benchmark, MotionMark, measures how well different browsers render animation. Its score tells users the most complex animation that the browser can render at a certain frame rate. The benchmark is most accurate when it gets the most precise measure of frame rate. Currently, the method using rAF to measure frame rate doesn't reflect the user's actual experience. +* The public benchmark, MotionMark, measures how well different browsers render animation. For each benchmark test, MotionMark calculates the highest complexity of an animation that the browser can handle at an expected frame rate. The test starts with a very complex animation that makes the frame rate drop to about half of what it should be. Then, MotionMark gradually reduces the animation's complexity until the frame rate returns to the expected level. Through this process, MotionMark can determine the highest complexity that the browser can handle while maintaining the expected frame rate. This value is the benchmark score. +To get an accurate score, it is crucial that MotionMark can measure frame rate precisely. Currently, MotionMark measures frame rate based on rAF calls, which can be impacted other tasks on the main thread besides animation, and doesn't take into account animation on the compositor thread. The method using rAF to measure frame rate doesn't reflect the user's actual experience. ### 4. Testing animation performance on different hardware * Testing the performance of animation on different hardware/browser combinations may expose performance issues that could not be seem with imprecise metrics. From 444496f6b1c793cc38ddf414052f94bc8966eabd Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Fri, 28 Feb 2025 10:38:45 -0800 Subject: [PATCH 12/28] Update explainer.md --- fps/explainer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fps/explainer.md b/fps/explainer.md index 1736108b7..51515504c 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -42,8 +42,8 @@ Our goal is to create an API for a more precise measure of browser frame rate, s * FPS can be difficult to measure when relating to user interaction. An average metric isn't always effective because in certain apps, animation begins on a user click. There doesn't need to be a continuous measurement since without a user click, there is no animation. Some examples of this include scrolling a long grid or document, selecting or highlighting large areas of the screen, resizing images, or dragging objects across the screen. ### 3. Measuring animation and graphics performance of browsers -* The public benchmark, MotionMark, measures how well different browsers render animation. For each benchmark test, MotionMark calculates the highest complexity of an animation that the browser can handle at an expected frame rate. The test starts with a very complex animation that makes the frame rate drop to about half of what it should be. Then, MotionMark gradually reduces the animation's complexity until the frame rate returns to the expected level. Through this process, MotionMark can determine the highest complexity that the browser can handle while maintaining the expected frame rate. This value is the benchmark score. -To get an accurate score, it is crucial that MotionMark can measure frame rate precisely. Currently, MotionMark measures frame rate based on rAF calls, which can be impacted other tasks on the main thread besides animation, and doesn't take into account animation on the compositor thread. The method using rAF to measure frame rate doesn't reflect the user's actual experience. +* The public benchmark, MotionMark, measures how well different browsers render animation. For each test, MotionMark calculates the most complex animation that the browser can render at certain frame rate. The test starts with a very complex animation that makes the frame rate drop to about half of the expected rate. Then, MotionMark gradually reduces the animation's complexity until the frame rate returns to the expected rate. Through this process, MotionMark can determine the most complex animation that the browser can handle while maintaining an appropriate frame rate and uses this information to give the browser a score. +To get an accurate score, it is crucial that MotionMark can measure frame rate precisely. Currently, MotionMark measures frame rate based on rAF calls, which can be impacted by other tasks on the main thread besides animation. It also doesn't take into account animations on the compositor thread. The method using rAF to measure frame rate doesn't reflect the user's actual experience. ### 4. Testing animation performance on different hardware * Testing the performance of animation on different hardware/browser combinations may expose performance issues that could not be seem with imprecise metrics. From ee13f7038d4662b9f6a438472753451ec07b6427 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Mon, 3 Mar 2025 14:43:01 -0800 Subject: [PATCH 13/28] Update explainer.md --- fps/explainer.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fps/explainer.md b/fps/explainer.md index 51515504c..200ec3ddf 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -72,6 +72,14 @@ For the event listener scenario, it was determined that using granularity would ## Concerns/Open Questions 1. The user-perceived frame rate is influenced by both the main thread and the compositor thread. Accurate measurement of frame rates must account for both. Since the compositor thread operates independently of the main thread, it can be difficult to get its frame rate data. However, an accurate frame rate measurements needs to take into account both measurements. 2. Similar to the abandoned [Frame Timing interface](https://wicg.github.io/frame-timing/#introduction). We are currently gathering historical context on how this relates and why it is no longer being pursued. +3. Questions to Consider: + * Should content missing from the compositor frame due to delayed tile rasterization be tracked? + * Should the fps be something that a web page can query anytime? Or only reported out when the browser misses some target? + * How will this API work with variable rate monitors or on screens with higher refresh rates? + * How will this API take into account situations where the compositor thread produces frames that are missing content from the main thread? + * How will this API measure both the compositor and the main thread when they may have differing frame rates. The compositor thread can usually run at a higher frame rate than the main thread due to its simpler tasks. + * Should a developer be able to target a subset of time based on an interaction triggering an animation? + From dbcd99b59a2f6c770e9fcecc68fde37c016bfee6 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Tue, 4 Mar 2025 10:40:45 -0800 Subject: [PATCH 14/28] Update explainer.md --- fps/explainer.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fps/explainer.md b/fps/explainer.md index 200ec3ddf..633173e1e 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -62,9 +62,13 @@ JavaScript Performance markers are used to track points in time. In this solutio * performance.measure("myMarker", "endMarker") * FPS could be a property on performance measure +This option works similarly to the [Frame Timing API](https://wicg.github.io/frame-timing/#dom-performanceframetiming) by using start and end markers. Frame startTime and frame endTime are returned by the Performance object's now() method; the distance between the two points is frame duration. When the duration of a frame is too long, it is clear that there was a rendering issue. A PerformanceFrameTiming object is created and added to the performance entry buffer of each active web page, which developers can then access for information. + #### Option 3: Event Listener Adding an event listener for frame rate changes would alert developers about large drops in frame rate. Since it would not be necessary to know if the rate drops by a frame or two. Instead, the developer could set the event listener to alert when the frame rate drops by n. Or, similarly to the long task API's duration threshold, the developer could set a min and max fps. The event listener would fire only if the FPS is above the max or below the min. +This options works similarly to both [LoAF API](https://github.com/w3c/long-animation-frames) and the [Paint Timing API](https://www.w3.org/TR/paint-timing/), which both use the performance observer and follow a pattern that developers expect to use when improving performance. When observing long animation frames, developers can specify the entry types they want to the performance observer to processes. Like the performance observer reports which animation frames are too long, the event listener would send an alert when the frame rate drops by a certain amount. The two APIs differ in the amount of information given. The LoAF API can give more specific metrics for long animations, while event listeners provide a more general way of monitoring frame rate. + ## Alternatives Considered For the event listener scenario, it was determined that using granularity would not give a useful measure of FPS due to lack of detail. The granularity was modeled after the compute pressure API. * window.addEventListener("frameratechange", (event) =>{doSomething();}) From 7f41415de8f1405eeb37c4a06b2ad895dce13501 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Tue, 4 Mar 2025 11:24:33 -0800 Subject: [PATCH 15/28] Update explainer.md --- fps/explainer.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fps/explainer.md b/fps/explainer.md index 633173e1e..fe61038c4 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -47,7 +47,9 @@ To get an accurate score, it is crucial that MotionMark can measure frame rate ### 4. Testing animation performance on different hardware * Testing the performance of animation on different hardware/browser combinations may expose performance issues that could not be seem with imprecise metrics. - + +### 5. Improving animation libraries +* Animation libraries measure frame rate in different ways. For example, GSAP and PixiJS use tickers to measure FPS, but the developer have to add custom logic to run each tick to measure frame rate. Three.js uses a second library, stats.js, to measure frame rate, and anime.js and Motion libraries use rAF calling. It would be beneficial for libraries to have a built-in way to measure FPS. A built-in method would be more convenient and allow for a more seamless integration with each library's animation loop, leading to more accurate results. Immediate feedback would make debugging and resolving issues easier. Ideally, this would also standardize a way to measure FPS leading to consistency across libraries. ## Proposed Solutions From 17b4225bc8eaffde759acb81f53584811fc5a76f Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Wed, 12 Mar 2025 11:24:05 -0700 Subject: [PATCH 16/28] Update explainer.md --- fps/explainer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fps/explainer.md b/fps/explainer.md index fe61038c4..621ea1989 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -1,4 +1,4 @@ -# A More Precise Way to Measure Frames per Second (fps) +# A More Precise Way to Measure Animation Smoothness [comment]: < ** (*Same-Origin*) > From 90cb1828e9662fcac6c28da973313d8b9f1eb953 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Wed, 12 Mar 2025 11:40:11 -0700 Subject: [PATCH 17/28] Update explainer.md --- fps/explainer.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/fps/explainer.md b/fps/explainer.md index 621ea1989..73f004c62 100644 --- a/fps/explainer.md +++ b/fps/explainer.md @@ -15,13 +15,11 @@ Animation frames are rendered on the screen when there is a change that needs to requestAnimationFrame() polling can help decipher whether or not a frame has been dropped. The method works by having the browser call a function (rAF) to update the animation before the screen refreshes (paint stage). Keeping track of the number of times rAF is called provides a count for the number of frames being shown per second, which helps understand the smoothness of the browser's animation. If the browser does not call the function, that is an indicator that a frame was dropped. -In the past, Edge had a library for this purpose called fps-emitter. While that is a helpful way to measure events that slow down performance, it is not the most precise way to measure the actual framerate. This is because there are other processes executing independently to render the animation, which can impact fps and can't be detected just by looking at rAF calls. +In the past, Edge had a library for this purpose called fps-emitter. While that is a helpful way to measure events that slow down performance, it is not the most precise way to measure the actual smoothness of the animation. This is because there are other processes executing independently to render the animation, which can impact the user perceived frame rate and can't be detected just by looking at rAF calls. Using the rAF method can actually slow down performance because it creates more tasks for the browser on the main thread. The extra work can cause the frame to drop by not executing before the deadline. An increase in dropped frames causes a less smooth animation. -Our goal is to create an API for a more precise measure of browser frame rate, specifically one that captures user-perceived frame rate. Prototyping an API that measures framerate more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF. - - +Our goal is to create an API for a more precise measure of animation smoothness, specifically one that captures user-perceived frame rate. Prototyping an API that measures animation smoothness more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF. ## Goals * Needs to be queryable from JavaScript @@ -31,15 +29,15 @@ Our goal is to create an API for a more precise measure of browser frame rate, s ## Non-goals * Former solutions to calculate fps have used rAF polling. We do not want to rely on rAF polling. -* We are not trying to increase fps, or improve animation, rather measure fps so we can solve other performance issues in the future +* We are not trying to improve animation, rather smoothness so we can solve other performance issues in the future ## Use Cases ### 1. Gaming -* Higher frames per second (fps) lead to smoother animations and a more enjoyable gaming experience. However, since (rAF) calls can be affected by how busy the main thread is, this method may overlook animation tasks performed by a compositor thread. Specific metrics can significantly impact gameplay elements, like how quickly characters can move or decisions can be made, which affects the overall user experience. Game developers are constantly striving to make their visuals more consistent and immersive. To guarantee smooth gameplay, developers need to test animations repeatedly. +* Higher frames per second (fps) lead to smoother animations and a more enjoyable gaming experience. However, since rAF calls can be affected by how busy the main thread is, this method may overlook animation tasks performed by a compositor thread. Specific metrics can significantly impact gameplay elements, like how quickly characters can move or decisions can be made, which affects the overall user experience. Game developers are constantly striving to make their visuals more consistent and immersive. To guarantee smooth gameplay, developers need to test animations repeatedly. Knowing their animation metrics will allow developers to increase or decrease animation quality based on user experience. ### 2. Continuously scrolling or selecting -* FPS can be difficult to measure when relating to user interaction. An average metric isn't always effective because in certain apps, animation begins on a user click. There doesn't need to be a continuous measurement since without a user click, there is no animation. Some examples of this include scrolling a long grid or document, selecting or highlighting large areas of the screen, resizing images, or dragging objects across the screen. +* Animation smoothness can be difficult to measure when relating to user interaction. An average metric isn't always effective because in certain apps, animation begins on a user click. There doesn't need to be a continuous measurement since without a user click, there is no animation. Some examples of this include scrolling a long grid or document, selecting or highlighting large areas of the screen, resizing images, or dragging objects across the screen. ### 3. Measuring animation and graphics performance of browsers * The public benchmark, MotionMark, measures how well different browsers render animation. For each test, MotionMark calculates the most complex animation that the browser can render at certain frame rate. The test starts with a very complex animation that makes the frame rate drop to about half of the expected rate. Then, MotionMark gradually reduces the animation's complexity until the frame rate returns to the expected rate. Through this process, MotionMark can determine the most complex animation that the browser can handle while maintaining an appropriate frame rate and uses this information to give the browser a score. From ea2715f588f7890140dbff30ee74e540f5eec1b6 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Wed, 12 Mar 2025 11:42:55 -0700 Subject: [PATCH 18/28] Rename explainer.md to explainer.md --- {fps => AnimationSmoothness}/explainer.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {fps => AnimationSmoothness}/explainer.md (100%) diff --git a/fps/explainer.md b/AnimationSmoothness/explainer.md similarity index 100% rename from fps/explainer.md rename to AnimationSmoothness/explainer.md From 4d33f079cc86873232f6e994186a83b71915addf Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Fri, 14 Mar 2025 10:42:28 -0700 Subject: [PATCH 19/28] Update explainer.md --- AnimationSmoothness/explainer.md | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/AnimationSmoothness/explainer.md b/AnimationSmoothness/explainer.md index 73f004c62..41d1f9d1f 100644 --- a/AnimationSmoothness/explainer.md +++ b/AnimationSmoothness/explainer.md @@ -10,16 +10,27 @@ This document is a starting point for engaging the community and standards bodie * Expected venue: [W3C Web Performance Working Group](https://www.w3.org/groups/wg/webperf/) * **Current version: this document** -## Introduction -Animation frames are rendered on the screen when there is a change that needs to be updated. Ideally, these frames are completed in a certain amount of time. If they are not updated in time, the browser drops a frame,. For the user, this looks like remaining on the same frame for longer, but it some instances, it may not even be noticeable. - -requestAnimationFrame() polling can help decipher whether or not a frame has been dropped. The method works by having the browser call a function (rAF) to update the animation before the screen refreshes (paint stage). Keeping track of the number of times rAF is called provides a count for the number of frames being shown per second, which helps understand the smoothness of the browser's animation. If the browser does not call the function, that is an indicator that a frame was dropped. +##Introduction +Smooth animation of the web is critical to a positive user experience. In order to improve the smoothness of animation, we need to first be able to measure the frames produced by the GPU and their completeness. There are multiple metrics that may play a role in measuring this: + +* Frame rate: the number of frames displayed per second of animation +* Frame Latency: the time it takes to render a single frame in an animation. Essentially, it's the delay between starting to create a frame and finishing it. +* Other smoothness metrics: +* Time between an interaction (Ex: clicking to start the animation) and the update on the screen +* Consistency of the animation: One average fps value may not represent the animation smoothness if there are long periods of jank +* High frame rate variations: This could be a positive or negative experience depending on the range of variations. For example an animation running between 120 and 240 fps may not be noticeable to the user or impact perceived smoothness +* Completeness of content (Checkerboarding): Even if an animation has a high frame rate, the animation may be poor if the content isn't fully rendered due to checkerboarding. While fps ensures a smooth motion, if the quality of image is low, the overall user experience will not be satisfactory. + +Our goal is to use one or more of these metrics to create an API to more precisely measure animation smoothness as perceived by the user. + +One of the current ways to measure frame rate (frames per second or fps) is by using requestAnimationFrame() polling. Animation frames are rendered on the screen when there is a change that needs to be updated. Ideally, these frames are completed in a certain amount of time. If they are not updated in time, the browser drops a frame,. For the user, this looks like remaining on the same frame for longer, but it some instances, it may not even be noticeable. +requestAnimationFrame() polling can help decipher whether or not a frame has been dropped. The method works by having the browser call a function (rAF) to update the animation before the screen refreshes (paint stage). Keeping track of the number of times rAF is called provides a count for the number of frames being shown per second, which helps understand the smoothness of the browser's animation. If the browser does not call the function, that is an indicator that a frame was dropped. In the past, Edge had a library for this purpose called fps-emitter. While that is a helpful way to measure events that slow down performance, it is not the most precise way to measure the actual smoothness of the animation. This is because there are other processes executing independently to render the animation, which can impact the user perceived frame rate and can't be detected just by looking at rAF calls. Using the rAF method can actually slow down performance because it creates more tasks for the browser on the main thread. The extra work can cause the frame to drop by not executing before the deadline. An increase in dropped frames causes a less smooth animation. -Our goal is to create an API for a more precise measure of animation smoothness, specifically one that captures user-perceived frame rate. Prototyping an API that measures animation smoothness more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF. +Our goal is to create an API for a more precise measure of animation smoothness. Specifically, we want to create one that captures user-perceived frame rate, which could measure more than just frames per second. Prototyping an API that measures animation smoothness more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF.![image](https://github.com/user-attachments/assets/e83115e0-a4ee-44c1-a569-ca14e1401b93) ## Goals * Needs to be queryable from JavaScript From 51dcb3ea96cdcdfa55da1962d1eaf146defc3d4c Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Fri, 14 Mar 2025 10:43:04 -0700 Subject: [PATCH 20/28] Update explainer.md --- AnimationSmoothness/explainer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AnimationSmoothness/explainer.md b/AnimationSmoothness/explainer.md index 41d1f9d1f..5a62da178 100644 --- a/AnimationSmoothness/explainer.md +++ b/AnimationSmoothness/explainer.md @@ -10,7 +10,7 @@ This document is a starting point for engaging the community and standards bodie * Expected venue: [W3C Web Performance Working Group](https://www.w3.org/groups/wg/webperf/) * **Current version: this document** -##Introduction +## Introduction Smooth animation of the web is critical to a positive user experience. In order to improve the smoothness of animation, we need to first be able to measure the frames produced by the GPU and their completeness. There are multiple metrics that may play a role in measuring this: * Frame rate: the number of frames displayed per second of animation @@ -30,7 +30,7 @@ In the past, Edge had a library for this purpose called fps-emitter. While that Using the rAF method can actually slow down performance because it creates more tasks for the browser on the main thread. The extra work can cause the frame to drop by not executing before the deadline. An increase in dropped frames causes a less smooth animation. -Our goal is to create an API for a more precise measure of animation smoothness. Specifically, we want to create one that captures user-perceived frame rate, which could measure more than just frames per second. Prototyping an API that measures animation smoothness more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF.![image](https://github.com/user-attachments/assets/e83115e0-a4ee-44c1-a569-ca14e1401b93) +Our goal is to create an API for a more precise measure of animation smoothness. Specifically, we want to create one that captures user-perceived frame rate, which could measure more than just frames per second. Prototyping an API that measures animation smoothness more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF. ## Goals * Needs to be queryable from JavaScript From 8216e9fe1a8458011a89d42887a08cf80c52d198 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Fri, 14 Mar 2025 10:44:22 -0700 Subject: [PATCH 21/28] Update explainer.md --- AnimationSmoothness/explainer.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AnimationSmoothness/explainer.md b/AnimationSmoothness/explainer.md index 5a62da178..780ac03a7 100644 --- a/AnimationSmoothness/explainer.md +++ b/AnimationSmoothness/explainer.md @@ -16,10 +16,10 @@ Smooth animation of the web is critical to a positive user experience. In order * Frame rate: the number of frames displayed per second of animation * Frame Latency: the time it takes to render a single frame in an animation. Essentially, it's the delay between starting to create a frame and finishing it. * Other smoothness metrics: -* Time between an interaction (Ex: clicking to start the animation) and the update on the screen -* Consistency of the animation: One average fps value may not represent the animation smoothness if there are long periods of jank -* High frame rate variations: This could be a positive or negative experience depending on the range of variations. For example an animation running between 120 and 240 fps may not be noticeable to the user or impact perceived smoothness -* Completeness of content (Checkerboarding): Even if an animation has a high frame rate, the animation may be poor if the content isn't fully rendered due to checkerboarding. While fps ensures a smooth motion, if the quality of image is low, the overall user experience will not be satisfactory. + * Time between an interaction (Ex: clicking to start the animation) and the update on the screen + * Consistency of the animation: One average fps value may not represent the animation smoothness if there are long periods of jank + * High frame rate variations: This could be a positive or negative experience depending on the range of variations. For example an animation running between 120 and 240 fps may not be noticeable to the user or impact perceived smoothness + * Completeness of content (Checkerboarding): Even if an animation has a high frame rate, the animation may be poor if the content isn't fully rendered due to checkerboarding. While fps ensures a smooth motion, if the quality of image is low, the overall user experience will not be satisfactory. Our goal is to use one or more of these metrics to create an API to more precisely measure animation smoothness as perceived by the user. From 50f119cee0b0333b67f51a64b86d1665bb2e4c6b Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Mon, 17 Mar 2025 15:01:19 -0700 Subject: [PATCH 22/28] Update explainer.md --- AnimationSmoothness/explainer.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/AnimationSmoothness/explainer.md b/AnimationSmoothness/explainer.md index 780ac03a7..f9292acd3 100644 --- a/AnimationSmoothness/explainer.md +++ b/AnimationSmoothness/explainer.md @@ -23,7 +23,7 @@ Smooth animation of the web is critical to a positive user experience. In order Our goal is to use one or more of these metrics to create an API to more precisely measure animation smoothness as perceived by the user. -One of the current ways to measure frame rate (frames per second or fps) is by using requestAnimationFrame() polling. Animation frames are rendered on the screen when there is a change that needs to be updated. Ideally, these frames are completed in a certain amount of time. If they are not updated in time, the browser drops a frame,. For the user, this looks like remaining on the same frame for longer, but it some instances, it may not even be noticeable. +One of the current ways to measure smoothness is by measuring frames per second (fps) using requestAnimationFrame() polling. Animation frames are rendered on the screen when there is a change that needs to be updated. Ideally, these frames are completed in a certain amount of time. If they are not updated in time, the browser drops a frame,. For the user, this looks like remaining on the same frame for longer, but it some instances, it may not even be noticeable. requestAnimationFrame() polling can help decipher whether or not a frame has been dropped. The method works by having the browser call a function (rAF) to update the animation before the screen refreshes (paint stage). Keeping track of the number of times rAF is called provides a count for the number of frames being shown per second, which helps understand the smoothness of the browser's animation. If the browser does not call the function, that is an indicator that a frame was dropped. In the past, Edge had a library for this purpose called fps-emitter. While that is a helpful way to measure events that slow down performance, it is not the most precise way to measure the actual smoothness of the animation. This is because there are other processes executing independently to render the animation, which can impact the user perceived frame rate and can't be detected just by looking at rAF calls. @@ -45,20 +45,20 @@ Our goal is to create an API for a more precise measure of animation smoothness. ## Use Cases ### 1. Gaming -* Higher frames per second (fps) lead to smoother animations and a more enjoyable gaming experience. However, since rAF calls can be affected by how busy the main thread is, this method may overlook animation tasks performed by a compositor thread. Specific metrics can significantly impact gameplay elements, like how quickly characters can move or decisions can be made, which affects the overall user experience. Game developers are constantly striving to make their visuals more consistent and immersive. To guarantee smooth gameplay, developers need to test animations repeatedly. Knowing their animation metrics will allow developers to increase or decrease animation quality based on user experience. +Higher frames per second (fps) lead to smoother animations and a more enjoyable gaming experience. However, since rAF calls can be affected by how busy the main thread is, this method may overlook animation tasks performed by a compositor thread. Specific metrics can significantly impact gameplay elements, like how quickly characters can move or decisions can be made, which affects the overall user experience. Game developers are constantly striving to make their visuals more consistent and immersive. To guarantee smooth gameplay, developers need to test animations repeatedly. Knowing their animation metrics will allow developers to increase or decrease animation quality based on user experience. ### 2. Continuously scrolling or selecting -* Animation smoothness can be difficult to measure when relating to user interaction. An average metric isn't always effective because in certain apps, animation begins on a user click. There doesn't need to be a continuous measurement since without a user click, there is no animation. Some examples of this include scrolling a long grid or document, selecting or highlighting large areas of the screen, resizing images, or dragging objects across the screen. +Animation smoothness can be difficult to measure when relating to user interaction. An average metric isn't always effective because in certain apps, animation begins on a user click. There doesn't need to be a continuous measurement since without a user click, there is no animation. Some examples of this include scrolling a long grid or document, selecting or highlighting large areas of the screen, resizing images, or dragging objects across the screen. ### 3. Measuring animation and graphics performance of browsers -* The public benchmark, MotionMark, measures how well different browsers render animation. For each test, MotionMark calculates the most complex animation that the browser can render at certain frame rate. The test starts with a very complex animation that makes the frame rate drop to about half of the expected rate. Then, MotionMark gradually reduces the animation's complexity until the frame rate returns to the expected rate. Through this process, MotionMark can determine the most complex animation that the browser can handle while maintaining an appropriate frame rate and uses this information to give the browser a score. +The public benchmark, MotionMark, measures how well different browsers render animation. For each test, MotionMark calculates the most complex animation that the browser can render at certain frame rate. The test starts with a very complex animation that makes the frame rate drop to about half of the expected rate. Then, MotionMark gradually reduces the animation's complexity until the frame rate returns to the expected rate. Through this process, MotionMark can determine the most complex animation that the browser can handle while maintaining an appropriate frame rate and uses this information to give the browser a score. To get an accurate score, it is crucial that MotionMark can measure frame rate precisely. Currently, MotionMark measures frame rate based on rAF calls, which can be impacted by other tasks on the main thread besides animation. It also doesn't take into account animations on the compositor thread. The method using rAF to measure frame rate doesn't reflect the user's actual experience. ### 4. Testing animation performance on different hardware -* Testing the performance of animation on different hardware/browser combinations may expose performance issues that could not be seem with imprecise metrics. +Testing the performance of animation on different hardware/browser combinations may expose performance issues that could not be seem with imprecise metrics. ### 5. Improving animation libraries -* Animation libraries measure frame rate in different ways. For example, GSAP and PixiJS use tickers to measure FPS, but the developer have to add custom logic to run each tick to measure frame rate. Three.js uses a second library, stats.js, to measure frame rate, and anime.js and Motion libraries use rAF calling. It would be beneficial for libraries to have a built-in way to measure FPS. A built-in method would be more convenient and allow for a more seamless integration with each library's animation loop, leading to more accurate results. Immediate feedback would make debugging and resolving issues easier. Ideally, this would also standardize a way to measure FPS leading to consistency across libraries. +Animation libraries measure frame rate in different ways. For example, GSAP and PixiJS use tickers to measure FPS, but the developer have to add custom logic to run each tick to measure frame rate. Three.js uses a second library, stats.js, to measure frame rate, and anime.js and Motion libraries use rAF calling. It would be beneficial for libraries to have a built-in way to measure FPS. A built-in method would be more convenient and allow for a more seamless integration with each library's animation loop, leading to more accurate results. Immediate feedback would make debugging and resolving issues easier. Ideally, this would also standardize a way to measure FPS leading to consistency across libraries. ## Proposed Solutions From 5f9bc1e4966355674edfa6267fdc2319725f3f5f Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Mon, 17 Mar 2025 15:08:58 -0700 Subject: [PATCH 23/28] Update explainer.md --- AnimationSmoothness/explainer.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/AnimationSmoothness/explainer.md b/AnimationSmoothness/explainer.md index f9292acd3..a4d6d2dd0 100644 --- a/AnimationSmoothness/explainer.md +++ b/AnimationSmoothness/explainer.md @@ -23,8 +23,8 @@ Smooth animation of the web is critical to a positive user experience. In order Our goal is to use one or more of these metrics to create an API to more precisely measure animation smoothness as perceived by the user. -One of the current ways to measure smoothness is by measuring frames per second (fps) using requestAnimationFrame() polling. Animation frames are rendered on the screen when there is a change that needs to be updated. Ideally, these frames are completed in a certain amount of time. If they are not updated in time, the browser drops a frame,. For the user, this looks like remaining on the same frame for longer, but it some instances, it may not even be noticeable. -requestAnimationFrame() polling can help decipher whether or not a frame has been dropped. The method works by having the browser call a function (rAF) to update the animation before the screen refreshes (paint stage). Keeping track of the number of times rAF is called provides a count for the number of frames being shown per second, which helps understand the smoothness of the browser's animation. If the browser does not call the function, that is an indicator that a frame was dropped. +One of the current ways to measure smoothness is by measuring frames per second (fps) using `requestAnimationFrame()` polling. Animation frames are rendered on the screen when there is a change that needs to be updated. Ideally, these frames are completed in a certain amount of time. If they are not updated in time, the browser drops a frame,. For the user, this looks like remaining on the same frame for longer, but it some instances, it may not even be noticeable. +`requestAnimationFrame()` polling can help decipher whether or not a frame has been dropped. The method works by having the browser call a function (rAF) to update the animation before the screen refreshes (paint stage). Keeping track of the number of times rAF is called provides a count for the number of frames being shown per second, which helps understand the smoothness of the browser's animation. If the browser does not call the function, that is an indicator that a frame was dropped. In the past, Edge had a library for this purpose called fps-emitter. While that is a helpful way to measure events that slow down performance, it is not the most precise way to measure the actual smoothness of the animation. This is because there are other processes executing independently to render the animation, which can impact the user perceived frame rate and can't be detected just by looking at rAF calls. @@ -64,16 +64,20 @@ Animation libraries measure frame rate in different ways. For example, GSAP and ## Proposed Solutions #### Option 1: Direct Query This solution would involve querying the frame rate directly. JavaScript would call an API that measures the fps at a specific point in time. To measure the overall frame rate, the API would be called multiple times, using the values to calculate an average frame rate. -* window.framerate() + +`window.framerate()` #### Option 2: Start and End Markers JavaScript Performance markers are used to track points in time. In this solution, developers could mark a start and end point on the performance timeline and measure the duration between the two markers, with FPS as a property. -* window.framerate("perfMarker") <- Framerate since that marker -* performance.mark("myMarker") -* performance.measure("myMarker", "endMarker") + +`window.framerate("perfMarker")` <- Framerate since that marker + +`performance.mark("myMarker")` + +`performance.measure("myMarker", "endMarker")` * FPS could be a property on performance measure -This option works similarly to the [Frame Timing API](https://wicg.github.io/frame-timing/#dom-performanceframetiming) by using start and end markers. Frame startTime and frame endTime are returned by the Performance object's now() method; the distance between the two points is frame duration. When the duration of a frame is too long, it is clear that there was a rendering issue. A PerformanceFrameTiming object is created and added to the performance entry buffer of each active web page, which developers can then access for information. +This option works similarly to the [Frame Timing API](https://wicg.github.io/frame-timing/#dom-performanceframetiming) by using start and end markers. Frame startTime and frame endTime are returned by the Performance object's `now()` method; the distance between the two points is frame duration. When the duration of a frame is too long, it is clear that there was a rendering issue. A PerformanceFrameTiming object is created and added to the performance entry buffer of each active web page, which developers can then access for information. #### Option 3: Event Listener Adding an event listener for frame rate changes would alert developers about large drops in frame rate. Since it would not be necessary to know if the rate drops by a frame or two. Instead, the developer could set the event listener to alert when the frame rate drops by n. Or, similarly to the long task API's duration threshold, the developer could set a min and max fps. The event listener would fire only if the FPS is above the max or below the min. @@ -82,7 +86,8 @@ This options works similarly to both [LoAF API](https://github.com/w3c/long-anim ## Alternatives Considered For the event listener scenario, it was determined that using granularity would not give a useful measure of FPS due to lack of detail. The granularity was modeled after the compute pressure API. -* window.addEventListener("frameratechange", (event) =>{doSomething();}) + +`window.addEventListener("frameratechange", (event) =>{doSomething();})` ## Concerns/Open Questions 1. The user-perceived frame rate is influenced by both the main thread and the compositor thread. Accurate measurement of frame rates must account for both. Since the compositor thread operates independently of the main thread, it can be difficult to get its frame rate data. However, an accurate frame rate measurements needs to take into account both measurements. From fe49a00d64011a996a4e801a7f002e30803bd6f0 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Thu, 27 Mar 2025 16:13:50 -0700 Subject: [PATCH 24/28] Update explainer.md --- AnimationSmoothness/explainer.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/AnimationSmoothness/explainer.md b/AnimationSmoothness/explainer.md index a4d6d2dd0..2e8bc0f6b 100644 --- a/AnimationSmoothness/explainer.md +++ b/AnimationSmoothness/explainer.md @@ -30,6 +30,12 @@ In the past, Edge had a library for this purpose called fps-emitter. While that Using the rAF method can actually slow down performance because it creates more tasks for the browser on the main thread. The extra work can cause the frame to drop by not executing before the deadline. An increase in dropped frames causes a less smooth animation. +There are two additional APIs that were investigated regarding animation smoothness: the Long animation frames API and `requestVideoFrameCallback()`. + +A long animation frame (LoAF) occurs when a frame is delayed by more than 50ms. The Long Animation Frames API allows developers to identify long animation frames by keeping track of the time it takes for frames to complete. If the frame takes longer than the threshold, it is flagged. The metrics provided and the frequency of calls are different than rAF. Use cases between the two APIs are also distinct. LoAF is used to pinpoint specific causes of performance issues and responsiveness, but not necessarily smooth animation. While the API's seem similar, neither allows for the precision of measurement ideal for observing animation smoothness. + +`requestVideoFrameCallback()` is a method used with `HTMLVideoElement`. It allows a developer to run a callback every time a new frame of video is about to appear. It functions similarly to `requestAnimationFrame()`, but `requestVideoFrameCallback()` is for video elements, while `requestAnimationFrame()` is used for simpler animations. `requestVideoFrameCallback()` is called based on the video's frame rate, while rAF is called based on the display's refresh rate. Lastly, `requestVideoFrameCallback()` takes in the time the callback was called as well as the metadata for the video frame, while rAF only takes in a timestamp parameter.`requestVideoFrameCallback()` can offer developers metrics like video frame render delays and Real-Time Transport Protocol (RTP) timestamps, and it's relatively easy to implement, but there are some limitations. `requestVideoFrameCallback()` may be inconsistent between browsers. Different browsers can show varying timestamp references for the same video frame. Additionally, it may be unreliable for precisely measuring frame times. This is because the callback can be delayed or skipped if the system is busy. On slower machines, the frequency of callback can decrease, further impacting performance. + Our goal is to create an API for a more precise measure of animation smoothness. Specifically, we want to create one that captures user-perceived frame rate, which could measure more than just frames per second. Prototyping an API that measures animation smoothness more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF. ## Goals From a5b9e0c22fefac04029300ee85dd67d3e8e7cda0 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Mon, 31 Mar 2025 14:20:12 -0700 Subject: [PATCH 25/28] Update explainer.md --- AnimationSmoothness/explainer.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/AnimationSmoothness/explainer.md b/AnimationSmoothness/explainer.md index 2e8bc0f6b..28604410b 100644 --- a/AnimationSmoothness/explainer.md +++ b/AnimationSmoothness/explainer.md @@ -69,19 +69,19 @@ Animation libraries measure frame rate in different ways. For example, GSAP and ## Proposed Solutions #### Option 1: Direct Query -This solution would involve querying the frame rate directly. JavaScript would call an API that measures the fps at a specific point in time. To measure the overall frame rate, the API would be called multiple times, using the values to calculate an average frame rate. +This solution would involve querying the frame rate directly. JavaScript would call an API that measures some frame information at a specific point in time. To measure the overall frame rate, the API would be called multiple times, using the values to calculate an average frame rate. -`window.framerate()` +`window.frameinfo()` #### Option 2: Start and End Markers -JavaScript Performance markers are used to track points in time. In this solution, developers could mark a start and end point on the performance timeline and measure the duration between the two markers, with FPS as a property. +JavaScript Performance markers are used to track points in time. In this solution, developers could mark a start and end point on the performance timeline and measure the duration between the two markers, with frame information as a property. -`window.framerate("perfMarker")` <- Framerate since that marker +`window.frameinfo("perfMarker")` <- Framerate since that marker `performance.mark("myMarker")` `performance.measure("myMarker", "endMarker")` -* FPS could be a property on performance measure +* Frame info could be a property on performance measure This option works similarly to the [Frame Timing API](https://wicg.github.io/frame-timing/#dom-performanceframetiming) by using start and end markers. Frame startTime and frame endTime are returned by the Performance object's `now()` method; the distance between the two points is frame duration. When the duration of a frame is too long, it is clear that there was a rendering issue. A PerformanceFrameTiming object is created and added to the performance entry buffer of each active web page, which developers can then access for information. @@ -91,12 +91,12 @@ Adding an event listener for frame rate changes would alert developers about lar This options works similarly to both [LoAF API](https://github.com/w3c/long-animation-frames) and the [Paint Timing API](https://www.w3.org/TR/paint-timing/), which both use the performance observer and follow a pattern that developers expect to use when improving performance. When observing long animation frames, developers can specify the entry types they want to the performance observer to processes. Like the performance observer reports which animation frames are too long, the event listener would send an alert when the frame rate drops by a certain amount. The two APIs differ in the amount of information given. The LoAF API can give more specific metrics for long animations, while event listeners provide a more general way of monitoring frame rate. ## Alternatives Considered -For the event listener scenario, it was determined that using granularity would not give a useful measure of FPS due to lack of detail. The granularity was modeled after the compute pressure API. +For the event listener scenario, it was determined that using granularity would not give a useful measure of frame info due to lack of detail. The granularity was modeled after the compute pressure API. `window.addEventListener("frameratechange", (event) =>{doSomething();})` ## Concerns/Open Questions -1. The user-perceived frame rate is influenced by both the main thread and the compositor thread. Accurate measurement of frame rates must account for both. Since the compositor thread operates independently of the main thread, it can be difficult to get its frame rate data. However, an accurate frame rate measurements needs to take into account both measurements. +1. The user-perceived smoothness is influenced by both the main thread and the compositor thread. Accurate measurement of frame rates must account for both. Since the compositor thread operates independently of the main thread, it can be difficult to get its frame rate data. However, an accurate frame rate measurements needs to take into account both measurements. 2. Similar to the abandoned [Frame Timing interface](https://wicg.github.io/frame-timing/#introduction). We are currently gathering historical context on how this relates and why it is no longer being pursued. 3. Questions to Consider: * Should content missing from the compositor frame due to delayed tile rasterization be tracked? From e86904e134cb696ca6662dfd6aa409964e9a516e Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Mon, 31 Mar 2025 14:25:07 -0700 Subject: [PATCH 26/28] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8a4f83849..ef1ad2487 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ These are proposals that are still really early in their lifecycle. We might jus | ---- | ---- | ---- | ---- | | [Materials in Web Applications](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Materials/explainer.md) | ![GitHub issues by-label](https://img.shields.io/github/issues/MicrosoftEdge/MSEdgeExplainers/Materials?label=issues) | [New Issue...](https://github.com/MicrosoftEdge/MSEdgeExplainers/issues/new?assignees=diekus&labels=Materials&title=%5BMaterials%5D+%3CTITLE+HERE%3E) | PWA | | [Performance Control of Embedded Content](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/PerformanceControlOfEmbeddedContent/explainer.md) | ![GitHub issues by-label](https://img.shields.io/github/issues/MicrosoftEdge/MSEdgeExplainers/PerformanceControlOfEmbeddedContent?label=issues) | [New Issue...](https://github.com/MicrosoftEdge/MSEdgeExplainers/issues/new?assignees=nishitha-burman&labels=PerformanceControlOfEmbeddedContent&title=%5BPerformanceControlOfEmbeddedContent%5D+%3CTITLE+HERE%3E) | Web Perf | +| [Animation Smoothness](AnimationSmoothness/explainer.md) | ![GitHub issues by-label](https://img.shields.io/github/issues/MicrosoftEdge/MSEdgeExplainers/AnimationSmoothness?label=issues) | [New Issue...](https://github.com/MicrosoftEdge/MSEdgeExplainers/issues/new?assignees=jenna-sasson&labels=AnimationSmoothness&title=%5BAnimationSmoothness%5D+%3CTITLE+HERE%3E) | Web Perf | # Alumni 🎓 From 3539edaf93afc82e6bd93b1494a84649c02b8e4c Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Fri, 25 Apr 2025 14:56:41 -0700 Subject: [PATCH 27/28] Update explainer.md --- AnimationSmoothness/explainer.md | 153 +++++++++++++++++++------------ 1 file changed, 94 insertions(+), 59 deletions(-) diff --git a/AnimationSmoothness/explainer.md b/AnimationSmoothness/explainer.md index 28604410b..5f7f05dcf 100644 --- a/AnimationSmoothness/explainer.md +++ b/AnimationSmoothness/explainer.md @@ -11,84 +11,123 @@ This document is a starting point for engaging the community and standards bodie * **Current version: this document** ## Introduction -Smooth animation of the web is critical to a positive user experience. In order to improve the smoothness of animation, we need to first be able to measure the frames produced by the GPU and their completeness. There are multiple metrics that may play a role in measuring this: +Smooth web animation is essential for a positive user experience. To understand the user’s experience with animation, quantifying their experience is an important initial step that allows web and browser developers to optimize their pages/engines and generate a more pleasing user experience. -* Frame rate: the number of frames displayed per second of animation -* Frame Latency: the time it takes to render a single frame in an animation. Essentially, it's the delay between starting to create a frame and finishing it. -* Other smoothness metrics: - * Time between an interaction (Ex: clicking to start the animation) and the update on the screen - * Consistency of the animation: One average fps value may not represent the animation smoothness if there are long periods of jank - * High frame rate variations: This could be a positive or negative experience depending on the range of variations. For example an animation running between 120 and 240 fps may not be noticeable to the user or impact perceived smoothness - * Completeness of content (Checkerboarding): Even if an animation has a high frame rate, the animation may be poor if the content isn't fully rendered due to checkerboarding. While fps ensures a smooth motion, if the quality of image is low, the overall user experience will not be satisfactory. +Various metrics have been used in the past to try and understand the user’s experience in this space. Some of these were accessible to the webpage, while others were internal browser metrics. Examples of these include: -Our goal is to use one or more of these metrics to create an API to more precisely measure animation smoothness as perceived by the user. - -One of the current ways to measure smoothness is by measuring frames per second (fps) using `requestAnimationFrame()` polling. Animation frames are rendered on the screen when there is a change that needs to be updated. Ideally, these frames are completed in a certain amount of time. If they are not updated in time, the browser drops a frame,. For the user, this looks like remaining on the same frame for longer, but it some instances, it may not even be noticeable. -`requestAnimationFrame()` polling can help decipher whether or not a frame has been dropped. The method works by having the browser call a function (rAF) to update the animation before the screen refreshes (paint stage). Keeping track of the number of times rAF is called provides a count for the number of frames being shown per second, which helps understand the smoothness of the browser's animation. If the browser does not call the function, that is an indicator that a frame was dropped. +* Framerate – the number of frames displayed to the user over time. +* Frame latency – the time it takes for a single frame to work through a browser’s pipelines and display to the user. +* Interaction to Next Paint – the time from a user interaction until the result of that interaction is displayed to the user. +* Consistency of the animation – a measure of how consistent the framerate is over time. +* High framerate variations – framerate classifications that differentiate between changes the user may not notice (variations but still high framerates) and those they may notice (variations involving transitions between high and low framerates). +* Completeness of content – frame classification that includes information about whether the frame includes updates from all desired sources for a given display update or only a subset (or none) of them. -In the past, Edge had a library for this purpose called fps-emitter. While that is a helpful way to measure events that slow down performance, it is not the most precise way to measure the actual smoothness of the animation. This is because there are other processes executing independently to render the animation, which can impact the user perceived frame rate and can't be detected just by looking at rAF calls. +This proposal attempts to define an API that offers a comprehensive quantification of the user’s experience regarding animation smoothness, enabling developers to create better user experiences. -Using the rAF method can actually slow down performance because it creates more tasks for the browser on the main thread. The extra work can cause the frame to drop by not executing before the deadline. An increase in dropped frames causes a less smooth animation. +## Goals +* Webpage accessible API that captures user-perceived framerate accurately, taking into account both the main and compositor threads. +* An approach that doesn’t cause webpage performance regressions. +* Enabling a web developer to control what time interval is considered. +* The solution will measure as many of the above properties as possible -There are two additional APIs that were investigated regarding animation smoothness: the Long animation frames API and `requestVideoFrameCallback()`. +## Non-goals +* Improving/controlling animation smoothness. This proposal is purely for an API to better understand existing behavior. +* Evaluate an individual animation’s smoothness. The API is focused on the user’s overall experience for entire browser window’s content. -A long animation frame (LoAF) occurs when a frame is delayed by more than 50ms. The Long Animation Frames API allows developers to identify long animation frames by keeping track of the time it takes for frames to complete. If the frame takes longer than the threshold, it is flagged. The metrics provided and the frequency of calls are different than rAF. Use cases between the two APIs are also distinct. LoAF is used to pinpoint specific causes of performance issues and responsiveness, but not necessarily smooth animation. While the API's seem similar, neither allows for the precision of measurement ideal for observing animation smoothness. +## User Research +## Use Cases -`requestVideoFrameCallback()` is a method used with `HTMLVideoElement`. It allows a developer to run a callback every time a new frame of video is about to appear. It functions similarly to `requestAnimationFrame()`, but `requestVideoFrameCallback()` is for video elements, while `requestAnimationFrame()` is used for simpler animations. `requestVideoFrameCallback()` is called based on the video's frame rate, while rAF is called based on the display's refresh rate. Lastly, `requestVideoFrameCallback()` takes in the time the callback was called as well as the metadata for the video frame, while rAF only takes in a timestamp parameter.`requestVideoFrameCallback()` can offer developers metrics like video frame render delays and Real-Time Transport Protocol (RTP) timestamps, and it's relatively easy to implement, but there are some limitations. `requestVideoFrameCallback()` may be inconsistent between browsers. Different browsers can show varying timestamp references for the same video frame. Additionally, it may be unreliable for precisely measuring frame times. This is because the callback can be delayed or skipped if the system is busy. On slower machines, the frequency of callback can decrease, further impacting performance. +### 1. Web Developers Understanding On-demand Animations -Our goal is to create an API for a more precise measure of animation smoothness. Specifically, we want to create one that captures user-perceived frame rate, which could measure more than just frames per second. Prototyping an API that measures animation smoothness more accurately would help developers gain insights about performance issues they can improve without slowing down their performance using rAF. +Animation smoothness can be difficult to measure when relating to user interaction. An average metric isn't always effective because in certain apps, animation begins on a user click. There doesn't need to be a continuous measurement since without a user click, there is no animation. Some examples of this include scrolling a long grid or document, selecting or highlighting large areas of the screen, resizing images, dragging objects across the screen, or animations triggered by mouse movement or clicks. -## Goals -* Needs to be queryable from JavaScript -* Capture the user-perceived frame rate accurately -* Ensure that our solution does not slow down performance -* Should be able to query the frame rate at any specific point in time, rather than relying on events to indicate changes in frame rate +### 2. Measuring animation and graphics performance of browsers -## Non-goals -* Former solutions to calculate fps have used rAF polling. We do not want to rely on rAF polling. -* We are not trying to improve animation, rather smoothness so we can solve other performance issues in the future +The public benchmark, MotionMark, measures how well different browsers render animation. For each test, MotionMark calculates the most complex animation that the browser can render at certain frame rate. The test starts with a very complex animation that makes the frame rate drop to about half of the expected rate. Then, MotionMark gradually reduces the animation's complexity until the frame rate returns to the expected rate. Through this process, MotionMark can determine the most complex animation that the browser can handle while maintaining an appropriate frame rate and uses this information to give the browser a score. To get an accurate score, it is crucial that MotionMark can measure frame rate precisely. Currently, MotionMark measures frame rate based on rAF calls, which can be impacted by other tasks on the main thread besides animation. It also doesn't take into account animations on the compositor thread. The method using rAF to measure frame rate doesn't reflect the user's actual experience. -## Use Cases +### 3. Gaming + +Higher frames per second (fps) lead to smoother animations and a more enjoyable gaming experience. Additionally, poor animation can significantly impact gameplay elements, like how quickly characters can move or decisions can be made, which affects the overall user experience. In continual tension with the desire for smooth animations, game developers are constantly striving to make their visuals higher quality and immersive. To guarantee smooth gameplay, developers need a way to understand how their game’s animations are performing. + +### 4. Testing animation performance on different hardware + +Testing the performance of animation on different hardware/browser combinations may expose performance issues that could not be seen with existing metrics. + +### 5. Improving animation libraries + +Animation libraries measure frame rate in different ways. For example, GSAP and PixiJS use tickers to measure FPS, but the developer must add custom logic to run each tick to measure frame rate. Three.js uses a second library, stats.js, to measure frame rate, and anime.js and Motion libraries use rAF calling. It would be beneficial for libraries to have a built-in way to measure FPS. A built-in method would be more convenient and allow for more seamless integration with each library's animation loop, leading to more accurate results. Immediate feedback would make debugging and resolving issues easier. Ideally, this would also standardize a way to measure FPS leading to consistency across libraries. + +## Prior Art + +The below prior art exists for understanding animation smoothness today. + +### RAF +#### Description +One of the current ways to measure smoothness is by measuring frames per second (fps) using `requestAnimationFrame()` polling. + +Animation frames are rendered on the screen when there is a change that needs to be updated. If they are not updated in a certain amount of time, the browser drops a frame, which may affect animation smoothness. + +The rAF method has the browser call a function (rAF) to update the animation before the screen refreshes. By counting how often rAF is called, you can determine the FPS. If the browser skips calling rAF, it means a frame was dropped. This method helps understand how well the browser handles animations and whether any frames are being dropped. -### 1. Gaming -Higher frames per second (fps) lead to smoother animations and a more enjoyable gaming experience. However, since rAF calls can be affected by how busy the main thread is, this method may overlook animation tasks performed by a compositor thread. Specific metrics can significantly impact gameplay elements, like how quickly characters can move or decisions can be made, which affects the overall user experience. Game developers are constantly striving to make their visuals more consistent and immersive. To guarantee smooth gameplay, developers need to test animations repeatedly. Knowing their animation metrics will allow developers to increase or decrease animation quality based on user experience. - -### 2. Continuously scrolling or selecting -Animation smoothness can be difficult to measure when relating to user interaction. An average metric isn't always effective because in certain apps, animation begins on a user click. There doesn't need to be a continuous measurement since without a user click, there is no animation. Some examples of this include scrolling a long grid or document, selecting or highlighting large areas of the screen, resizing images, or dragging objects across the screen. - -### 3. Measuring animation and graphics performance of browsers -The public benchmark, MotionMark, measures how well different browsers render animation. For each test, MotionMark calculates the most complex animation that the browser can render at certain frame rate. The test starts with a very complex animation that makes the frame rate drop to about half of the expected rate. Then, MotionMark gradually reduces the animation's complexity until the frame rate returns to the expected rate. Through this process, MotionMark can determine the most complex animation that the browser can handle while maintaining an appropriate frame rate and uses this information to give the browser a score. -To get an accurate score, it is crucial that MotionMark can measure frame rate precisely. Currently, MotionMark measures frame rate based on rAF calls, which can be impacted by other tasks on the main thread besides animation. It also doesn't take into account animations on the compositor thread. The method using rAF to measure frame rate doesn't reflect the user's actual experience. +#### Limitations +Using rAF to determine the FPS can be energy intensive and inaccurate. This approach can negatively impact battery life by preventing the skipping of unnecessary steps in the rendering pipeline. While this is not usually the case, using rAF inefficiently can lead to dropped or partially presented frames, making the animation less smooth. It’s not the best method for understanding animation smoothness because it does not take into account factors like compositor offload and offscreen canvas. While rAF can be useful, it isn’t the most accurate and relying on it too heavily can lead to energy waste and suboptimal performance. -### 4. Testing animation performance on different hardware -Testing the performance of animation on different hardware/browser combinations may expose performance issues that could not be seem with imprecise metrics. +#### [Reference](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame) -### 5. Improving animation libraries -Animation libraries measure frame rate in different ways. For example, GSAP and PixiJS use tickers to measure FPS, but the developer have to add custom logic to run each tick to measure frame rate. Three.js uses a second library, stats.js, to measure frame rate, and anime.js and Motion libraries use rAF calling. It would be beneficial for libraries to have a built-in way to measure FPS. A built-in method would be more convenient and allow for a more seamless integration with each library's animation loop, leading to more accurate results. Immediate feedback would make debugging and resolving issues easier. Ideally, this would also standardize a way to measure FPS leading to consistency across libraries. +### Long Animation Frames API +#### Description +A long animation frame (LoAF) occurs when a frame takes more than 50ms to render. The Long Animation Frames API allows developers to identify long animation frames by keeping track of the time it takes for frames to complete. If the frame exceeds the threshold, it is flagged. -## Proposed Solutions -#### Option 1: Direct Query -This solution would involve querying the frame rate directly. JavaScript would call an API that measures some frame information at a specific point in time. To measure the overall frame rate, the API would be called multiple times, using the values to calculate an average frame rate. +#### Limitations +Unlike requestAnimationFrame() (rAF), which measures FPS, LoAF focuses on pinpointing performance issues and responsiveness. The two APIs provide different metrics and are called at different frequencies. While both APIs track animation frames, neither provides the precision needed for measuring animation smoothness. -`window.frameinfo()` - -#### Option 2: Start and End Markers +#### [Reference](https://github.com/w3c/long-animation-frames) + +### RequestVideoFrameCallback + +#### Description +requestVideoFrameCallback() is a method used with HTMLVideoElement. It allows a developer to run a callback every time a new frame of video is about to appear. It functions similarly to requestAnimationFrame() but is specific to video elements. requestVideoFrameCallback() is called based on the video's frame rate, while rAF is called based on the display's refresh rate. Additionally, requestVideoFrameCallback() provides the callback time and video frame metadata, whereas rAF only provides a timestamp. + +#### Limitations +requestVideoFrameCallback() can offer developers metrics like video frame render delays and Real-Time Transport Protocol (RTP) timestamps, and it's relatively easy to implement, but there are some limitations. requestVideoFrameCallback() may be inconsistent between browsers, with varying timestamp references for the same video frame. It may also be unreliable for precisely measuring frame times, as callbacks can be delayed or skipped if the system is busy, especially on slower machines. + +#### [Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/requestVideoFrameCallback) + +### FPS-Emitter + +#### Description +In the past, Edge had a library called fps-emitter that emits an update event. Once a new instance of FPS-emitter is called, it starts tracking frames per second via the rAF method. When the FPS changes, the result is returned as an EventEmitter. This method builds off the rAF method described above and faces similar limitations. + +#### Limitations +While FPS-emitter is a helpful way to measure events that slow down performance, it is not the most precise way to measure the actual smoothness of the animation. This is because there are other processes in addition to UI-blocking events executing independently to render the animation, which can impact the user perceived frame rate and can't be detected just by looking at rAF calls. + +#### [Reference](https://github.com/MicrosoftEdge/fps-emitter) + +## Proposed Approach +There is no proposed approach yet identified by this explainer. Instead, there are a variety of alternatives that we would like to discuss with the broader community. + +### Option 1: Direct Query +This solution would involve querying the animation smoothness data directly. JavaScript would call an API that measures some frame information at a specific point in time. To measure the frame information, the API would be called multiple times, using the values to calculate an average frame rate. + +`window.frameinfo() ` + +### Option 2: Start and End Markers JavaScript Performance markers are used to track points in time. In this solution, developers could mark a start and end point on the performance timeline and measure the duration between the two markers, with frame information as a property. -`window.frameinfo("perfMarker")` <- Framerate since that marker +`window.frameinfo("perfMarker")` <- Framerate since that marker -`performance.mark("myMarker")` +`performance.mark("myMarker") ` -`performance.measure("myMarker", "endMarker")` -* Frame info could be a property on performance measure +`performance.measure("myMarker", "endMarker") ` + +This option works similarly to the [Frame Timing API](https://wicg.github.io/frame-timing/#dom-performanceframetiming) by using start and end markers. Frame startTime and frame endTime are returned by the Performance object's now() method; the distance between the two points is frame duration. When the duration of a frame is too long, it is clear that there was a rendering issue. A PerformanceFrameTiming object is created and added to the performance entry buffer of each active web page, which developers can then access for information. -This option works similarly to the [Frame Timing API](https://wicg.github.io/frame-timing/#dom-performanceframetiming) by using start and end markers. Frame startTime and frame endTime are returned by the Performance object's `now()` method; the distance between the two points is frame duration. When the duration of a frame is too long, it is clear that there was a rendering issue. A PerformanceFrameTiming object is created and added to the performance entry buffer of each active web page, which developers can then access for information. +### Option 3: Event Listener -#### Option 3: Event Listener -Adding an event listener for frame rate changes would alert developers about large drops in frame rate. Since it would not be necessary to know if the rate drops by a frame or two. Instead, the developer could set the event listener to alert when the frame rate drops by n. Or, similarly to the long task API's duration threshold, the developer could set a min and max fps. The event listener would fire only if the FPS is above the max or below the min. +Adding an event listener for frame rate changes would alert developers about large drops in frame rate. Since it would not be necessary to know if the rate drops by a frame or two. Instead, the developer could set the event listener to alert when the frame rate drops by n. Or, similarly to the long task API's duration threshold, the developer could set a min and max fps. The event listener would fire only if the FPS is above the max or below the min. -This options works similarly to both [LoAF API](https://github.com/w3c/long-animation-frames) and the [Paint Timing API](https://www.w3.org/TR/paint-timing/), which both use the performance observer and follow a pattern that developers expect to use when improving performance. When observing long animation frames, developers can specify the entry types they want to the performance observer to processes. Like the performance observer reports which animation frames are too long, the event listener would send an alert when the frame rate drops by a certain amount. The two APIs differ in the amount of information given. The LoAF API can give more specific metrics for long animations, while event listeners provide a more general way of monitoring frame rate. +This option works similarly to both [LoAF API](https://github.com/w3c/long-animation-frames) and the [Paint Timing API](https://www.w3.org/TR/paint-timing/), which both use the performance observer and follow a pattern that developers expect to use when improving performance. When observing long animation frames, developers can specify the entry types they want to the performance observer to processes. Like the performance observer reports which animation frames are too long, the event listener would send an alert when the frame rate drops by a certain amount. The two APIs differ in the amount of information given. The LoAF API can give more specific metrics for long animations, while event listeners provide a more general way of monitoring frame rate. ## Alternatives Considered For the event listener scenario, it was determined that using granularity would not give a useful measure of frame info due to lack of detail. The granularity was modeled after the compute pressure API. @@ -107,10 +146,6 @@ For the event listener scenario, it was determined that using granularity would * Should a developer be able to target a subset of time based on an interaction triggering an animation? - - -## Glossary - ## Acknowledgements - +Thank you to Sam Fortiner, Olga Gerchikov, and Andy Luhrs for their valuable feedback. From 6e1ecd833c21f393812af5049d85137e089c0ac9 Mon Sep 17 00:00:00 2001 From: jenna-sasson Date: Wed, 30 Apr 2025 13:39:34 -0700 Subject: [PATCH 28/28] Update explainer.md --- AnimationSmoothness/explainer.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/AnimationSmoothness/explainer.md b/AnimationSmoothness/explainer.md index 5f7f05dcf..e0476fabc 100644 --- a/AnimationSmoothness/explainer.md +++ b/AnimationSmoothness/explainer.md @@ -110,12 +110,20 @@ There is no proposed approach yet identified by this explainer. Instead, there a ### Option 1: Direct Query This solution would involve querying the animation smoothness data directly. JavaScript would call an API that measures some frame information at a specific point in time. To measure the frame information, the API would be called multiple times, using the values to calculate an average frame rate. -`window.frameinfo() ` +`window.frameinfo() ` or `performance.frameinfo()` ### Option 2: Start and End Markers JavaScript Performance markers are used to track points in time. In this solution, developers could mark a start and end point on the performance timeline and measure the duration between the two markers, with frame information as a property. -`window.frameinfo("perfMarker")` <- Framerate since that marker + +2a + +`performance.mark("myMarker") ` + +`window.frameinfo("myMarker")` <- Framerate since that marker + + +2b `performance.mark("myMarker") ` @@ -127,11 +135,27 @@ This option works similarly to the [Frame Timing API](https://wicg.github.io/fra Adding an event listener for frame rate changes would alert developers about large drops in frame rate. Since it would not be necessary to know if the rate drops by a frame or two. Instead, the developer could set the event listener to alert when the frame rate drops by n. Or, similarly to the long task API's duration threshold, the developer could set a min and max fps. The event listener would fire only if the FPS is above the max or below the min. +`window.addEventListener("frameratechange", (event) =>{doSomething();}) ` + +### Option 4: Performance Observer + This option works similarly to both [LoAF API](https://github.com/w3c/long-animation-frames) and the [Paint Timing API](https://www.w3.org/TR/paint-timing/), which both use the performance observer and follow a pattern that developers expect to use when improving performance. When observing long animation frames, developers can specify the entry types they want to the performance observer to processes. Like the performance observer reports which animation frames are too long, the event listener would send an alert when the frame rate drops by a certain amount. The two APIs differ in the amount of information given. The LoAF API can give more specific metrics for long animations, while event listeners provide a more general way of monitoring frame rate. +```javascript +function perfObserver(list, observer) { + list.getEntries().forEach((entry) => { + if (entry.entryType === "frameSmoothness") { + console.log(${entry.name}'s startTime: ${entry.startTime}); + } + }); +} +const observer = new PerformanceObserver(perfObserver); +observer.observe({ entryTypes: ["frameSmoothness"] }); + +``` + ## Alternatives Considered For the event listener scenario, it was determined that using granularity would not give a useful measure of frame info due to lack of detail. The granularity was modeled after the compute pressure API. - `window.addEventListener("frameratechange", (event) =>{doSomething();})` ## Concerns/Open Questions