[whatwg] Timing API proposal for measuring intervals

James Robinson jamesr at google.com
Thu Jul 7 18:57:57 PDT 2011

On Thu, Jul 7, 2011 at 6:47 PM, Ojan Vafai <ojan at chromium.org> wrote:

> On Thu, Jul 7, 2011 at 6:15 PM, James Robinson <jamesr at google.com> wrote:
>> It is not possible to accurately measure time intervals using existing web
>> platform APIs, or to specify times at a given interval from the current
>> time.  Date.now() and DOM timestamps are inadequate for this purpose, see
>> <sectiontitle> below for reasons why this is so.
>> 1.) When updating an imperative animation state from script, authors need
>> to
>> know how much time has elapsed in the animation so far in order to
>> properly
>> update the animation.
>> 2.) When synchronizing imperative animation updates with audio, authors
>> need
>> to know how much time has elapsed in the animation and in the audio
>> sample's
>> progression and be able to schedule future audio cues to specific points
>> in
>> the animation.
>> 3.) When measuring the time that a given operation has taken (for example,
>> a
>> network request or a application process), authors need to be able to
>> measure the amount of time elapsed from script.
>> In ECMAScript the Date object is typically used for timing.  It is defined
>> (in ES-262 5th edition section as representing milliseconds
>> since
>> the unix epoch, Jan 1 1970 00:00:00 UTC, ignoring leap seconds.  DOM
>> timestamps are defined in a similar way, although it doesn't seem to
>> specify
>> anything about leap seconds.  In practice, implementations depend on the
>> system clock for these APIs and are likely to use the same implementation
>> for both.  This poses a problem whenever the system clock is adjusted.  In
>> all implementations I tested, Date.now() varies whenever the system clock
>> is
>> adjusted.  This means that, for example, the following snippet:
>> var start = Date.now();
>> dosomething();
>> window.alert(Date.now() - start);
>> may alert a positive number, negative number, or zero if the system clock
>> is
>> adjusted in between the two calls to Date.now().  Similarly, timestamps
>> from
>> a series of DOM events may be increasing, decreasing, or unchanging if the
>> system clock adjusts in between event dispatches.  System clock
>> adjustments
>> are not as rare as you might thing, many systems are configured to receive
>> clock updates over the network via NTP or similar systems.  When
>> developing
>> and implementing the navigation timing spec we ran in to many reported
>> time
>> intervals from users in the wild that were bogus in one way or another,
>> either negative (easily detectable) or artificially inflated (very
>> difficult
>> to detect).  I've put a simple test page up here:
>> http://webstuff.nfshost.com/timers.html.
>> Additionally, there's a practical concern that querying the system clock
>> on
>> some systems is more expensive and/or less reliable than other timing
>> APIs.
>>  On windows, for instance, GetSystemTimeAsFileTime() has a resolution of
>> ~15.5ms, so browsers use a combination of GetSystemTimeAsFileTime() with
>> higher-resolution timing APIs like QueryPerformanceCounter() that provide
>> better resolution but are not affected by adjustments to the system clock.
>>  See http://drdobbs.com/windows/184416651?pgno=1 and
>> https://bugzilla.mozilla.org/show_bug.cgi?id=363258 for some background
>> information.
>> I propose that we add a new attribute to the Window interface that
>> provides
>> a monotonic, uniformly increasing timestamp suitable for interval
>> measurements.
>> <bikeshed-topic>
>> partial interface Window {
>>  readonly attribute double monotonicTime;
>> };
>> </bikeshed-topic>
>> <bikeshed-topic>
>> I propose that monotonicTime be defined as the number of milliseconds
> <bikeshed-nit>
> Is milliseconds sufficient? Could we use seconds and encourage
> implementations to do decimal values? Would be nice to support microseconds
> on most modern hardware.
> </bikeshed-nit>

It's a double, so implementations can provide higher resolution if they
like.  setTimeout() and setInterval() clamp to milliseconds, so that seems
to be the de-factor resolution of the platform today, but I don't have any
issue with supporting higher resolution times.

- James

>> elapsed since the window creation.  There is likely to be no meaningful
>> relationship between the value exposed by this interval and a date and
>> time
>> in the past (such as the unix epoch), so starting at zero seems a good at
>> choice as any.
>> </bikeshed-topic>
>> I do not believe we can change the meaning of Date.now() in ECMAScript
>> since
>> the current behavior has existing for a very long time and is genuinely
>> useful when the author wants to know the system clock's current value, for
>> example in a calendar type application.
>> The setTimeout() and setInterval() algorithms (
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#timers
>> )
>> implicitly depend on a uniformly monotonic clock in the various "wait for
>> X
>> milliseconds" phase, since there is no allowance in this text for
>> adjustments to the system clock to change when the timer actually fires.
>>  All browsers except for WebKit ignore system clock changes for timer
>> scheduling, and the WebKit behavior is a bug which I plan to fix.
>> The Web Perf WG has run into similar issues and defined a monotonic clock
>> as
>> part of the Navigation Timing API:
>> http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html#mono-clock
>> .
>>  This clock is very similar to the above proposal but is not exposed
>> directly to authors.  I expect that implementations of the Navigation
>> Timing
>> API would use the same mechanism to implement this proposal.
>> The proposed Web Audio API (
>> http://chromium.googlecode.com/svn/trunk/samples/audio/specification/specification.html#AudioContext-section
>> )
>> exposes
>> a timestamp on the AudioContext interface that is defined to map to a
>> monotonic uniformly increasing hardware timestamp.
>> - James

More information about the whatwg mailing list