requestAnimationFrame [now] vs performance.now() time discrepancy

后端 未结 2 1806
面向向阳花
面向向阳花 2021-01-02 05:57

Assumptions: rAF now time is calculated at the time the set of callbacks are all triggered. Therefore any blocking that happens before the first callback of th

2条回答
  •  时光说笑
    2021-01-02 06:37

    The timestamp passed in to the requestAnimationFrame() callback is the time of the beginning of the animation frame. Multiple callbacks being invoked during the same frame all receive the same timestamp. Thus, it would be really weird if performance.now() returned a time before the parameter value, but not really weird for it to be after that.

    Here's the relevant specification:

    When the user agent is to run the animation frame callbacks for a Document document with a timestamp now, it must run the following steps:

    1. If the value returned by the document object’s hidden attribute is true, abort these steps. [PAGE-VISIBILITY]

    2. Let callbacks be a list of the entries in document’s list of animation frame callbacks, in the order in which they were added to the list.

    3. Set document’s list of animation frame callbacks to the empty list.

    4. For each entry in callbacks, in order: invoke the Web IDL callback function, passing now as the only argument, and if an exception is thrown, report the exception.

    So you've registered a callback (let's say just one) for the next animation frame. Tick tick tick, BOOM, time for that animation frame to happen:

    1. The JavaScript runtime makes a note of the time and labels that now.
    2. The runtime makes a temporary copy of the list of registered animation frame callbacks, and clears the actual list (so that they're not accidentally invoked if things take so long that the next animation frame comes around).
    3. The list has just one thing in it: your callback. The system invokes that with now as the parameter.
    4. Your callback starts running. Maybe it's never been run before, so the JavaScript optimizer may need to do some work. Or maybe the operating system switches threads to some other system process, like starting up a disk buffer flush or handling some network traffic, or any of dozens of other things.
    5. Oh right, your callback. The browser gets the CPU again and your callback code starts running.
    6. Your code calls performance.now() and compares it to the now value passed in as a parameter.

    Because a brief but non-ignorable amount of time may pass between step 1 and step 6, the return value from performance.now() may indicate that a couple of microseconds, or even more than a couple, have elapsed. That is perfectly normal behavior.

提交回复
热议问题