"VSYNC synchronization" Tester Manual
How the VSYNC synchronization tester works


  Index

1. The VSYNC verification problem
2. A novel new VSYNC test
3. vsynctester.com test options
  4. Mouse 'input lag' detector
5. How to stress test a web browser
6. My test setup
  7. VSYNC bug reports
8. Future research / Observations
9. References

  1. The VSYNC verification problem
How frequently is your web browser sending frames to your display? Your web browser should match the Hz of your display (and update frames during VSYNC). However, how can web browser VSYNC synchronization be easily and objectively validated?

Because validation is typically very difficult as it requires a high-speed video camera and inspection of the resulting video, frame by frame.
As a result, many tests resort to only reporting how many frames per second are being rendered inside the web browser — assuming that each rendered frame will actually be displayed/presented to the end user in the proper (unique) VSYNC display frame.

Or, an animation is presented and the determination of 'smoothness' (no dropped frames) is left as a subjective opinion for the viewer.
All modern web browsers can easily generate hundreds of frames per second (on desktop, and high end tablets and phones) for simple <canvas> animations -- meaning that there is typically plenty of CPU/GPU headroom. So you would think that placing one (and only one) rendered frame in one display VSYNC interval would be incredibly easy for web browsers -- but for some unknown reason, that is not the case!
The problem for web browsers is not producing frames in a timely manner (that is easy!). Rather, the problem for all web browsers is properly synchronizing those frames to your display's VSYNC interval.
Under Windows, Chrome 38+, Firefox 32+, and Internet Explorer DO NOT properly synchronize rendered frames to a display's VSYNC refresh signal. Multiple software rendered frames end up in one VSYNC frame, and the visual result is dropped frames, yielding a visual effect on the display of 'jerky graphics', or jank.
Chrome 40 (on Windows desktop) used to work great, but as of 40.0.2214.115, Chrome is once again busted. Chrome Canary works great (there was an issue for about two weeks). One remaining annoying bug in Chrome on Windows 7 using DirectX 9 is that the Chrome application window must be manually resized before VSYNC works properly Bug 465356. Chromium as of Dec 9 2015 is again broken. Bug 631166

Watch Firefox 33 render at 60fps, but display at 30fps (every two rendered frames end up in every other VSYNC frame). Still seen even in Firefox 44.
There has to be a much easier way to objectively verify web browser VSYNC synchronization.

  2. A novel new VSYNC test
The solution is to take advantage of (1) requestAnimationFrame() in HTML5 and (2) additive color mixing (eg: red+cyan=white, or FF0000+00FFFF=FFFFFF) that virtually all computer displays use.
ALL modern web browsers support requestAnimationFrame() (RAF), which is part of HTML5 -- and internally, all web browsers attempt to synchronize the RAF callbacks to the monitor's VSYNC signal. As a result, by closely monitoring the RAF callback rate, we can discover the underlying VSYNC hertz (provided the web browser does not have any bugs).
Display a red 'VSYNC' image for one frame (1/60 of a second) followed by a cyan 'VSYNC' image for the next frame (1/60 of a second), and repeat over and over.

Even frames
+
 

Odd frames
=
 

Visual Result
As long as there is NO interruption in this alternating frequency to the displaywhich can only happen when a browser IS properly VSYNC aligned — the end result is that 'VSYNC' appears to your eyes on the display as a flickering gray. See Persistence of vision. If even a single frame is missed/dropped, your eyes easily detect/see the red/cyan color.
High speed photos clearly show that the display is in fact alternating between displaying red and displaying cyan. But at 60Hz, your eyes interpret that as (flickering) gray! The precise level of gray your eyes see depends upon the pixel response times of your display, and your viewing angle. Please note that viewing angle can also affect the amount of flickering seen.
In summary, for a web browser that is easily producing 60 fps, if you look at 'VSYNC' and only see (flickering) gray, you absolutely know that rendered frames are being displayed properly aligned to VSYNC. However, if you look at 'VSYNC' and you sometimes see a flickering red or cyan, then you absolutely know that the web browser is not properly VSYNC aligned. Easy!

  3. vsynctester.com test options
Click on the 'gear' icon at the top of the vsynctester.com web page and the following test options will be presented (or hidden). All test options are fully interactive, and take immediate effect.
VSYNC synchronized indicator: When the 'VSYNC' indicator (word) appears as a flickering gray, that indicates proper VSYNC synchronization. However, when you see either red or cyan for a brief moment, then the web browser is NOT properly synchronized to the display's VSYNC signal (or not rendering frames fast enough; see the performance graph below).
rgb: Customizes the indicator background gray level (where 0 is black; 255 is white) -- so that the word 'VSYNC' you see will blend into the indicator background.

A very interesting side effect is that this actually allows you to compare the relative pixel 'response time' between two displays. The display with a lower 'rgb' value (that causes 'VSYNC' to blend into the background) has the faster pixel response times (as pixels are transitioning from 'on' to 'black/off' faster).

TIP: Only rely upon this indicator when the performance graph (below) shows NO late inter-frame callbacks (no red line). In other words, when there is a red spike in the performance graph, it is likely that any color flickering in this indicator was caused by a frame being rendered late. Whereas, when the performance graph is green (indicating ALL frames are being generated on time) and this indicator shows red/cyan, then you know that the web browser has a VSYNC synchronization problem.

The VSYNC indicator will automatically switch to multiple VSYNC indicators to support higher display frequencies (120Hz, 180Hz, 240Hz). But it does become harder to notice single skipped frames. This feature is currently being tested. The far majority of all computers will have a display with a Hz 'around' 60.
Performance graph: A millisecond timing graph for the last 300 frames. The graph displays these metrics:
Please note the separate left and right scales. The left scale goes negative a little because in my testing, some browsers call setTimeout() callbacks early, causing the 'late' line to go negative.


frame VSYNC offset (blue): Displays each frame's offset from the measured VSYNC location (how this works) A subtle drift initially is normal, as the display Hz must first be very accurately computed -- and it continues to be recalculated and refined over time. When 'locked' is checked, the Hertz is NOT recalculated over time. While the absolute value of this line is informative, the offset relative to other offsets is far more important. Namely, if you see a sudden jump to a new offset, this reveals an internal web browser timing problem (example seen below right).
TIP: In Chrome, a sudden jump indicates an internal transition from "low latency mode" to "high latency mode" (or vise versa). Internet Explorer has major jumps and phase shifts from true VSYNC.

phase shift example
'late' / vsync offset per rAF time (purple): Operates in one of two modes. FIRST, in rAF (non custom hz) mode, the late line graphs the difference in time between the actual time, and the time argument passed to the rAF callback. SECOND, in 'Custom Hz' mode, graphs how late the web browser calls the setTimeout() callback.
TIP: In 'Custom Hz' mode, turn off all GUI components, except for the performance graph and turn off all other graph lines -- and you now have a setTimeout() accuracy tester, revealing how (in)accurate a web browser is able to time events.
inter-frame (green/red): The inter-frame millisecond times (right scale). The line turns red when the total jitter is more than 6ms. The line is centered vertically to the computed inter-frame time (displayed centered on the right scale).
WARNING: inter-frame times should NO LONGER BE USED as a primary measure of VSYNC accuracy -- because these times HIDE phase shift adjustments. Instead, use 'frame VSYNC offset' as the primary measure. A case in point is the graph to the right. There is a phase shift in the red 'inter-frame' timing line, and it is not obvious! But the phase shift becomes crazy easy to spot in the 'frame VSYNC offset' line.
render time (brown): The millisecond time spent in the JavaScript animation callback (left scale), self timed. Please note that this line almost NEVER includes actual GPU rendering time, which in most modern browsers, happens in another thread.
NOTE: Due to how the Intel processor works (the clock frequency slows down when the processor is not very active), this 'render time' line can actually be artificially high. Strangely, adding work for the CPU (see 'RT' link at the bottom of the vsynctester.com page) causes the processor to do more work, increasing the clock frequency, and causing this line to dramatically reduce. See 'JavaScript initially runs slowly' far below for more details.
spin-wait line (gray): For 'Custom Hz' mode only. Adds the millisecond time spent spin-waiting due to (a) early setTimeout() callback, plus (b) any intentional precise time waiting -- as a gray line to the performance graph.
TIP: with precise timing off, this gray line graphs only how early the web browser calls the setTimeout() callback. This 'should' always be zero. It not, this indicates that there are timing problems with a browser's setTimeout() implementation.
graph title: The title of the performance graph provides two key metrics:
fps: The average software rendered FPS based upon the last 300 callbacks. This should closely match the display's VSYNC frequency (when there are no missed frames; otherwise a browser bug). Missed frames will cause this metric to 'jump around' -- so only rely on this fps number when the inter-frame timings graph is green (not red).

display Hz: Keeps track of the callback times long term to provide an accurate estimate of Hertz of your display (on the presumption that requestAnimationFrame is called at the VSYNC frequency, even if not properly VSYNC aligned). The estimate gets more accurate the longer the test is run, even when frames are missed (how this works).
A Hz of exactly 60.00 Hz is almost certainly a web browser bug, and causes the title of the performance graph to turn red as a warning. The previous older display HZ test may be better for some mobile devices.

Please note that whenever Custom Hz is checked or unchecked (or the Hz is changed), the long term Hz statistics are reset and again take a little time to ramp up to an accurate value.
vsyncmark: A benchmark score of how well the web browser is (1) aligning to true vsync and (2) rendering the test animation. The benchmark is based upon the time from true vsync until the rAF callback returns. Very simple. And then that time is made relative to Chrome running on a 2nd gen i7 Dell XPS 17 notebook from 2011 (which is a score of 100).

Firefox computes vsync incorrectly
Use rAF time arg as frame time: Web browsers pass a time argument to the requestAnimationFrame() callback. Usually this time is just the current 'now' time. However some browsers (Chrome) are starting to report the actual vsync time via this time argument. So checking this option is a great way to peek into web browser timing internals.
TIP: If your goal is to quickly find the exact Hertz of your display (Windows OS), using this option in Chrome will very quickly find the exact Hertz of your display! In about 30 seconds on many systems, the computed inter-frame time will be accurate to nanoseconds!

On April 14, 2015, I suggested on the [email protected] group (covers the RequestAnimationFrame specification) that "The 'time' in the rAF callback (Processing Model) should be altered in the spec to allow (encourage) a web browser to pass the known begin time of the frame (the vsync timebase) as the 'time', rather than performance.now()."

Chrome: As of 2015/05/28, Chrome 45.0.2415.0 (or later) passes "true vsync" time as the rAF callback time.

Firefox: Firefox tries to do this, but fails, since vsync in Firefox is broken (seen upper right).

Safari/IE/Edge: Still pass in the 'now' time.

Custom Hz: Replaces the web browser's native requestAnimationFrame() implementation with a JavaScript based implementation using setTimeout() that operates at the requested (custom) Hz.
Hz: For best results, use a multiple (or fraction) of your exact display Hz, which is displayed in the title of the performance graph.
TIP: For the most accurate results, let the test run without a custom Hz for a minute or two, which allows the 'display Hz' to become more accurate. Then copy that Hz into the Custom Hz, check the option, and use.
skew: Custom Hz attempts to fire at the exact same time that requestionAnimationFrame would have (when 'Hz' matches your display Hz). 'skew' delays that firing by the specified number of milliseconds.
Some web browsers have problems rendering frames precisely VSYNC aligned -- and where simply delaying several ms fixes the (unknown) problem!
Precise timing: Instead of relying upon web browser setTimeout() timer accuracy (presumed to be around 1ms), this option will request an early call back by the specified number of milliseconds, and then spin-wait for the exact time. Using this option requires a fast CPU/GPU setup to work properly, as CPU time is wasted spin waiting.

Maximum setTimeout() ms of XX: Internet Explorer will not increase the system timer resolution unless there is an outstanding timer 10ms or less. Checking this option 'should' make 'Custom Hz' work better under Internet Explorer.

See also the 'late' and 'spin-wait' lines in the performance graph, which have special meaning when 'Custom Hz' is used.
Background image: Includes a scrolling pano in the animation. It is NOT enough for a web browser to simply maintain VSYNC under NO load -- rather, it is critical that a web browser also be able to VSYNC 'under load', and a great way to test this is by manipulating a number of images every single frame that add up to a large megapixel value.
MP: Allows you to precisely set how many megapixels will be used by all the background images. Please note that actual bytes used internally (by the web browser or GPU) will be approximately MP*1024*1024*4.

Use up to XX images: Attempts to split the megapixels between multiple images, but with a minimum of around 5MP per image. Set to 1 to place all megapixels in a single image.

This test was made more strict, and tougher to pass, after it was discovered that Chrome has trouble VSYNC'ing while manipulating a larger number of megapixels (but that Safari, Firefox, Internet Explorer, and Edge all handle larger megapixels very well). details

Also note that it is faily common for older video drivers to have bugs and not work properly with larger images (like, only displaying the first 8192 pixels and none after that). If you see red, you are running into this problem. Simply switching to a newer computer (with newer device drivers) fixes the problem.
Mouse input lag detector XX frames: Please see the next section, where this is discussed in great detail.

Odd/Even frame delays: Spin waits either before (a pre-delay) or after (a post-delay) the JavaScript animation code is executed, eating up a portion of a frame's time.
Vendors state that their web browsers should be able to tolerate the JavaScript animation callback using up around 1/3 of a frames time. These options allow you to verify that. In reality, most desktop web browsers are now good and fast enough to tolerate the JavaScript animation code using up to around 3/4 of a frames time.

TIP: If a web browser is updating the display at the wrong Hz (eg: blindly generating exactly 60 fps), an odd frame delay will cause the VSYNC synchronized indicator to show more red VSYNC failures and an even frame delay will show more cyan VSYNC failures. This is simply taking advantage of the interference pattern caused by two frequencies that are close to each other.
Tear helper/bar: Makes it really easy to see screen tearing (where a display shows part of one frame and part of second frame in a single VSYNC display refresh; example seen right).
Please note that the Windows Aero desktop window manager uses double buffering synchronized to VSYNC so you will never see tearing (an OS level feature). However, in Windows 7, the double buffering can be disabled by selecting the "Windows 7 Basic" desktop theme (right click on Desktop and select 'Personalize'). Please note that screen captures will never show tearing (as tearing is only a visual effect caused by how a display is updated). This double buffering can not be disabled in Windows 8.x [Source]

TIP: Using 'Custom Hz' and 'skew', you will be able to precisely place (vertically) the tear location.

Please note that it appears that Chrome 40.0.2214.0 and later always has internal double buffering turned on, which means you will not see tearing. Whereas in Chrome 38, you will see tearing with Aero off. This issue is being investigated.
Drop 1 in every XX frames: On fast computers, the VSYNC indicator will always be flickering gray. This option forces entire frames to be dropped so that you can confirm that the VSYNC indicator is in fact 'working' -- namely, that when a frame is dropped, that you will see red/cyan color.
TIP: Setting XX to 1 allows you to drop ALL frames, suspending all canvas/display updates, while all internal timing and measurements continue. Hopefully, when there are browser VSYNC problems, this will help isolate the problem to either the timing subsystem, or the graphics/canvas subsystem.
Frames indicator: The boxes represent the last 60 frames (even frames top row; odd frames bottom row), with the current frame drawn in a solid red box. Use this option if you are going to video record the animation.

  4. Mouse 'input lag' detector
Input lag is the delay from a user initiating input, until a response to that input is seen on the display. For example, when you move the mouse, delays come from:
  1. Mouse: 0ms to 8ms - Most consumer mice update at 125Hz (or once every 8ms), which explains why gamers want mice that update at 500Hz (every 2ms) or 1000Hz (every 1ms). It is interesting to note that many trackpads on notebooks update at a slightly slower Hz (around 10ms to 12ms).
  2. USB: <1ms - USB transmission time should be incredibly small.
  3. OS/CPU: <1ms - on modern fast multi-core hardware, the CPU and OS should contribute almost nothing.
  4. Application: - The web browser is the key unknown that we want to measure.
  5. DWM: 0ms to 16ms - The Windows OS (Win7 with Aero on; all Win8/Win10) eliminates all screen tearing by using a compositing DWM (desktop window manager). That means applications no longer draw directly to display memory, but rather, first draw to a (OS maintained) memory buffer, which is then sent to the display once every Hz (aligned to VSYNC by the DWM). At 60Hz, that is once every 1/60, or 16.6 ms.
  6. Display Hz: 0ms to 16ms - An entire display is updated one pixel at a time, one row at a time from top to bottom. This takes time. In fact, it takes around 1/Hz, or at 60Hz, 1/60 or 16.6ms to update all rows. So a pixel, no matter where it is on the screen, is updated once every 16.6ms. So it is all about timing. When an application updates the display, it will take anywhere from 0ms to 16.6ms for the pixel to even be updated on the display. This explains why gamers prefer high Hz displays.
  7. Display Response Time: 2ms to 16ms - Once a display pixel is actually updated, that pixel does not change color instantly, but actually takes time to transition to the new color, which explains why gamers want displays with fast pixel 'response times'.
  8. External display: 9ms to 100ms - If you are using an external display, that will cause additional lag. Lag database This is as opposed to an internal notebook display, which will not add lag.
The trick for measuring only the web browser lag: We are interested in measuring only how much the web browser adds to the lag. The solution is to implement a software based mouse cursor in the web browser, and because all other lag factors remaining the same, the difference in position on the display of the hardware cursor vs the software cursor identifies the amount of lag introduced by the web browser alone!

The lag detector: Enable the 'Mouse input lag detector XX frames' option at vsynctester.com and move the mouse consistently (moderately fast) left/right until you find an 'XX' (1, 2, 3, etc) that causes the red dot to position itself under the crosshair cursor — and that 'XX' is the number of 'frames' of input lag caused by the web browser.
In the example seen upper right, the red dot is one frame away from the black dot, but the cursor is still well ahead of that. Changing XX from 1 to 2 causes the red dot to be positioned under the cursor, and reveals a two frame input delay for the web browser.
The black crosshair cursor is the hardware cursor. The black dot is the software cursor (shows the last mouse X/Y seen by the browser; The difference is the input lag.). The red dot is a prediction for where the software cursor will be 'XX' frames in the future (set 'XX' to 0 to remove the red dot). The blue line represents the last display frame.
TIP: turn off all other options (like the performance graph and background image) to make it easier to see the indicator. Many web browsers have an input lag of two frames. Firefox/Windows and Safari/OSX appear to only have a one frame input lag. Modern web browsers should have no more than one frame of input lag, especially for 'simple' animations.
Bug 460919 was reported against Chrome for their two frame input delay.

  5. How to stress test a web browser
Here are some basic steps for stress testing a web browser to see if it is properly VSYNC aligned...
  1. New and Old PCs: Run vsynctester.com from a PC that is several years old, but one that still has a decent CPU and GPU.
    When I first noticed the VSYNC problem, and authored this test, I walked into Best Buy and tested on various desktop and notebook systems, but not a single system failed the test. This is because most computers made in the last two years produce great results (and an invalid test), due to the sheer GPU power of the system, which masks and covers up most browser timing problems.

    TIP: So, test on a 2nd generation i7 Intel system from 2011. The entire point is to stress test a web browser's VSYNC implementation under stressful conditions -- not test how fast a PC is.
  2. DirectX v9 and v11: Under Windows, test under BOTH DirectX 9 and Direct X 11. Done via "--disable-d3d11" under Chrome.

  3. AC Power + Battery: On a notebook, make sure you test under both AC power and on battery.
    In Chrome on battery power, timer accuracy is reduced from 1ms to 4ms (which the Windows OS may then map to 2.5ms).
  4. Power Plan: Make sure that you test under ALL 'power plans' under Windows -- like "High performance", "Balanced", "Power saver", etc. Various power plans can actually have a dramatic effect (up to 3.5x was measured) on performance, because when a thread 'wakes up' (like for every frame in a requestAnimationFrame animation), it actually takes a very measureable time for that thread to 'ramp up' to the full Hz of the processor.
    I have a test case showing a 3.5x performance slowdown using my default 'Dell' power plan. When the power plan is changed to 'High performance', all of a sudden, all timings are 3.5 times FASTER! This affects all web browsers.
  5. Validate PC power: Validate that your PC has enough power to perform the test -- that it is not too slow. For example, the graph seen right is for a Dell L702X, from 2011, where I see: (a) The brown line in the performance graph (render times; left scale) should be under 2ms. (b) The green/red line (inter-frame times; right scale) in the performance graph should be very consistent, and be green (it is normal for the line to be red when the browser starts the test, but it should turn green as the web browser 'settles down'). (c) The 'fps' displayed above the graph should be around 60 or 120 (or whatever the Hz of your display is).

  6. Be aware of background activity: Before benchmarking a web browser: (a) Sign off all other users, (b) Close all other running applications that you can, and (c) Close all other web browser tabs. Because under Windows, 'timer resolution' is a global concept -- so timer settings in one application can affect ALL other applications. Google "powercfg /energy -duration 5" (in quotation marks) if you are interested in learning more about this Windows quirk.
    Verify that your computer is not running anything (that is using CPU time): Under Windows, right click on the task bar, select 'Start Task Manager', click on the 'Performance' tab, and confirm that 'CPU usage' is 0%. If not, close the offending application.

    Also, if you are going to run the test long term, don't allow the computer to turn the display off during your test (Edit power plan under Control Panel).
  7. Validate VSYNC indicator: The "VSYNC synchronized indicator" should be flickering gray. If you see the indicator flicker red/cyan (and no sudden jumps in the inter-frame graph) at all, then your web browser is not properly VSYNC aligned.
    Ignore the first couple of seconds that a web browser starts up. But after that, you should not see any red/cyan at all in a web browser that is properly VSYNC aligned.

    Seeing red/cyan for a slit second once every couple of seconds is not a passing grade, but rather is a failure, and a strong indication that there is a VSYNC frequency mismatch. more info

    In fact, the VSYNC indicator should be so solid gray (no red/cyan seen at all) that you are left wondering if the VSYNC indicator is even working -- seriously! So play around with the 'Drop 1 frame in XX frames' option to confirm that it is.

    If you see a red/cyan flicker only when the inter-frame graph spikes, that strongly suggests that the web browser was 'busy' doing something else and preempted (did not even render) the requested (and missed) frame.
  8. 'frame VSYNC offset' test: Let the test run for a little while until the 'Display Hz' estimate settles down (around three decimal places is OK). Then turn on the 'frame VSYNC offset' performance line. This line should be almost perfectly flat around 0ms.
    The good: Chrome Canary (Windows) is currently the only web browser that passes this test (as of 43.0.2353.0). Firefox nightly (with 'Silk' turned on) comes close, but needs significant improvement (likely implementation bugs). Chrome release achieves a variation within a millisecond, caused by OS timer (in)accuracy.

    The bad: Firefox release achieves a variation within several milliseconds.

    The ugly: Internet Explorer is an outright failure, with has significant variation, along with significant phase shift adjustments.
  9. Odd frame pre-delay stress tests: Check the "Odd frame pre-delay", and play around with ms values from 0 to 6. The "VSYNC synchronized indicator" must remain gray. Uncheck when finished. Do the same for "Odd frame post-delay".
    This option is a great way to stress test internal web browser timing. The larger the millisecond delay can be set before the VSYNC indicator starts the fail, the better. On my test system, Chrome can tolerate a 12ms delay, which is fantastic, given that the entire frame time is 16.721ms. Whereas, Firefox fails with just a 4ms delay, which is rather bad.

    TIP: This option also helps to reveal web browser Hz mismatch problems (refer to description far above for more details).

    For this stress test, do NOT check both pre and post delay at the same time. Having the asymmetric frame times helps to stress the web browser.
  10. 'late' test: Turn on the 'Late' performance line. This is the time difference between when the rAF callback was actually called, and the time when the web browser started to prepare to call the rAF callback. This should match the computed vsync offset. If not, this reveals problems with a web browser's implementation.
    WARNING: If your web browser displays 'late' as a flat line, the web browser is NOT following the new standard of passing in the vsync time to the rAF callback, but is passing in the older 'now' time.

    UPDATE: Expect Firefox to fail this test. details

    TIP: In fact, after this test was added, it immediately revealed a bug in Chrome regarding something called "high latency mode". Bug 465105
  11. Double frame rate stress test: Let the www.vsynctester.com test run for a minute or two and take note of the Hz of your display (above the graph). Double that rate, and enter that doubled number into the 'Custom Hz', with a skew of 1ms, and precise timing off. For most PC's, this doubles the frame rate to something around 120Hz. The "VSYNC synchronized indicator" will adjust and display two VSYNC indicators, each running at an alternating 60Hz. But both indicators should stay gray. If you see any red/cyan color in either indicator, that indicates failure. This really stresses web browser timing internals as inter-frame times are now around a very small 8.3ms! On both of my test systems (even an older system from 2011), Chrome passes this test (watch Chrome pass this test) -- but both IE and FF fail the test (even on my faster test system).
    TIP: Experiement with different 'skew' values. If you find a value (greater than one; like two or three) that causes the test to work, this indicates problems with the accuracy of the web browser timer implementation. See the web browser timer accuracy test below to confirm.
  12. Triple frame rate stress test: Interestingly, even on my old notebook from 2011, Chrome supports a triple frame rate. I need to investigate this issue more, but Chrome clearly beats other web browsers by a wide margin!

  13. Validate browser timer accuracy: Check the 'Custom Hz' option, and turn off 'Precise timing'. Next, turn on the 'late' performance graph line (and turn off all other lines). The resulting performance graph will reveal the setTimeout() timer accuracy of the web browser. Try different 'skew' values from 1 to 15. Try different Hz values. The resulting line should always be tightly grouped together within one millisecond. This stress tests how accurately a web browser can schedule an event wake up time. On my test system, Chrome passes this test with flying colors, but Firefox fails the test, horribly, and is unable to accurately schedule wake up times:

    Google Chrome WORKS great
     
    Firefox FAILS horribly
    UPDATE: Canary 45.0.2427.0 introduced a new 2ms timer inaccuracy and timer drift, which was fixed in Canary 46.0.2472.0, but then reverted in just after 46.0.2478.0. See crbug.com/328700.

  14. Validate that rAF callback time argument is 'accurate': Check the 'late' line in the performance graph. It should either be flat (time arg is current time), or match the blue vsync offset line (time arg is vsync time; likely phase shifted slightly). Chrome passes this test. Firefox fails this test due to internal bugs. See Bug 1315230 (but FF will not fix since FF does not understand the issue). Details

    Firefox fakes the rAF callback time argument
  15. Test under mild system load: Run the Microsoft Fish Bowl HTML5 demo in a different web browser at the same time. How does the web browser running vsynctester.com deal with this mild extra load on the system? Chrome works very well (no impact), but Firefox fails this test, and is no longer vsync aligned. Details.

  6. My test setup
System One: The VSYNC problem was originally found in 2014 using a Dell L702X notebook (XPS 17, Intel i7 2630QM 2.00Ghz with 4 cores (8 threads), Intel HD Graphics 3000, 8GB, Windows 7, Aero Glass ON), with a known measured display refresh rate of 59.803Hz.

System Two: The VSYNC problem was then replicated with a Dell Inspiron 15R notebook (Intel i7-4500U 1.80Ghz with 2 cores (4 threads), Intel HD Graphics 4400, 12GB, Windows 8.1), with a known measured display refresh rate of 60.107Hz.

Tested under 60Hz and 40Hz displays.

If you have a 120Hz display and are willing to help test, please contact me.

  7. VSYNC Bug Reports
Chrome Bug Report: Bug 422000 was filed October 9, 2014 against Chrome 38. Google has taken this issue very seriously and as of November 10, 2014, already has a fix in Chrome Canary 40.0.2214.0. The good news is that the fix works very well -- the new Chrome is rock solid synchronized to VSYNC (now much better than IE).
UPDATE: The revision was backed out of Canary, so Canary again has problems! A workaround in Canary when using DirectX 9 was found -- resize the browser window, and then VSYNC works. Bug 465356

UPDATE: Chrome Canary 42.0.2286.0 (from r312916 to r312924) totally busted VSYNC by introducing an unknown graphics performance regression. Turning off the GPU for canvas fixes the problem! But then 42.0.2298.0 (from r315096 to r315107) resolved the issue.
Firefox Bug Report: Bug 1080869 was filed October 9, 2014 against Firefox 32. The bad news is that Mozilla is clueless and has shown no interest in finding the ultimate cause of this bug -- instead insisting that Mozilla may "accidentally fix" the bug sometime in the future. We recommend that anyone needing a web browser synchronized to VSYNC to stop using Firefox, and switch to either Chrome or IE.
UPDATE: Mozilla is working on a new 'Project Silk' for Firefox that promises to fix VSYNC problems. Only time will tell...

Don't use Firefox: Mozilla's Project Silk has failed. Firefox is STILL broken. Also, rather than Mozilla fixing a serious OMTC (off main thread compositing) bug #1083071 in Firefox, Mozilla decided that it was far easier for them to just blacklist my video driver (Chrome and IE both still use my video driver just fine). It is no wonder that Firefox market share is tanking to nothing. I don't test under the Firefox web browser anymore, because by blacklisting my video driver, Mozilla itself has made that impossible. And frankly, Firefox does not matter anymore. With such a small market share (and getting smaller fast), Mozilla is making Firefox irrelevant. UPDATE: 2015/12/26 As further proof that Firefox is NOT a viable web browser, TouchEvent's in Firefox simply do not work on the desktop. You can't use touch on a touch display! In fact, Mozilla's own touch examples work in Chrome, but do not work in Firefox. Crazy. Especially since Mozilla has known about this since 2012 and STILL has been unable to fix the problem (Mozilla bug 806805). Worst of all, touch on Firefox on an Android tablet is crazy busted too! If no one at Mozilla is minding the store for such simple features (touch on a tablet is pretty critical to get right), what about security bugs? Avoid!
IE Bug Report: IE supports VSYNC at 60Hz, but not at 40Hz. The 40Hz problem with IE was reported to Microsoft on October 17, 2014.

  8. Future research / Observations
Crazy fast (low) input lag: I wonder how long it will take for the major web browsers to figure out that for the vast majority of Windows desktop/notebook systems running a display at 60Hz, that an input lag of 1/2 the frame rate is very doable for many animations. TIP: This trick will work for any animation that could have run at 120Hz (and that is a huge clue as to 'how').

Chrome app window resize issues: In Chrome under Windows 7 (and DirectX 9), resizing the Chrome app window causes all sorts of strange things to happen: (1) VSYNC starts working, (2) any "--disable-gpu-vsync" command line switch stops working, and (3) on battery, causes timers to switch from 'on battery' mode back to 'on AC' mode. Google needs to fix this.

Chrome swap buffers: Under Chrome with Windows AERO off, there it a tear position a couple of pixels from the top of the display -- which indicates that Chrome's swap buffers is not properly aligned to VSYNC. Found in Google Canary 41.0.2219.0. Reported to Google

JavaScript initially runs slowly: The render time graph sometimes jumps around a LOT. Ironically, adding significant overhead to the system (running another program that maxes out all cores), actually caused render times to lower by 3.5x and flatten out significantly. This 'problem' was ultimately tracked down to the Intel processor itself! Apparently on some Intel processors, there is a significant delay (up to around 30ms) before the processor will 'ramp up' the processor frequency, which means that periodic JavaScript code (like animations) can run up to 3.5x slower (which for many animations, is just fine and saves power).
However, the startling conclusion is that for some animations, the Intel processor itself causes a strange yo-yo effect (captured in graph right for a very specially crafted real-world animation) -- the processor starts ramped down (slower), but then frames are missed, the CPU becomes saturated, and the Hz is ramped up (faster). As a result, frames are no longer missed, but then the CPU becomes idle, and the Hz is ramped down (slower), and the yo-yo cycle repeats. Web browsers should compensate for this. But if you run into this issue try running your computer under the "High performance" power plan for the duration of your 'animation'. But I have seen situations where even the "High performance" power plan still has a slight yo-yo effect. This needs more research.

Reported to Google, but Google blamed everything else but the true cause (they don't understand the issue).
How to see backend internal browser jitter in real time: Run under Windows 7 with AERO off, use the custom Hz option, synced to the Hz of your display, and use 'skew' to place the tear location in the center of the screen. The tear location from frame to frame should stay within a few pixels of the center of the screen. The inter-frame graph should be perfectly flat, and when it is, any deviation in the tearing location on the screen is the result of internal web browser jitter. Interestingly, even though VSYNC is busted under Firefox, Firefox results in a perfectly fixed tear location. However, under Chrome 38, on a periodic basic, the tear location is pushed down the screen by what equates to around 4-6ms. That indicates that Chrome has internal jitter that is causing problems. Reported to Google

The 'render time' graph does NOT include GPU time: Note that under all modern web browsers, that the time spent in the animation callback is always (with a GPU) very small. This is because the actual graphics processing takes place in another thread (or process), using the GPU. If you disable the GPU for canvas, the animation callback timing dramatically increases.
This is no longer seen in the latest Chrome, strongly suggesting that now, even non-GPU software rendering is in its own thread.
Internet Explorer (in)accuracy: Inter-frame callback times in IE are sometimes all over the place, but the browser (most of the time) is still VSYNC aligned. This needs to be investigated. Is this simply timer (in)accuracy, or something else? Also, 'frame VSYNC offset' in IE is all over the place, which is not good. This indicates an implementation problem.

A laptop on battery power means more timer jitter: On a laptop, switching from AC to battery power in Chrome under Windows results in reduced PC timer accuracy, which translates to more jitter in the inter-frame times.
Google was informed and provided source code on how to obtain perfect VSYC synchronization, even without playing around with Windows timer accuracy. Hopefully, this will be added to a future version of Chrome.
Firefox timer accuracy: setTimeout() accuracy under Firefox is hopelessly busted -- making it nearly impossible to use the 'custom hz' option. Interestingly, adding overhead, by increasing the spin wait time from 1 to 4 ms sometimes works around the Firefox bug. See the section above on how to test a web browser for more information. Also, this bug appears alignment related. The 'Custom Hz' attempts to align to the known (if possible) VSYNC alignment -- the fact that a setTimeout() fires on/around the VSYNC interval is problematic in Firefox. When 'skew' is set to change the timer alignment, all of a sudden setTimeout() works much better. Very strange, and hopefully something FF will fix.

Internet Explorer timer accuracy: On my Windows 8.1 test machine, IE 11 does NOT adjust the system timer resolution, meaning that it is limited to the OS default 15.625ms -- which explains why setTimeout() accuracy under IE is so terrible. Only if the setTimeout() ms value is 10 or less, does IE appear to set the system-wide timer resolution to 4ms (which the Windows OS may then map to 2.5ms).

Fully multi-threaded futures: What web browsers (all/none/some?) allow for the animation callback to use nearly 100% of the inter-frame time, and still have no dropped frames? With multi-threaded CPU's, and GPU processing (possibly) delayed by a frame, this is actually very possible. However, the disadvantage is an additional frame of input lag.
Chrome is using this model. The requestAnimationFrame() JavaScript callback can use the majority of a frame's time, and Chrome is still VSYNC synchronized.
Chrome page zoom affects VSYNC: On my test system, under Windows 7, when Chrome's page zoom is set to 150% (or higher), VSYNC fails. VSYNC works great at lower page zooms.
Noticed in Canary 44.0.2369.0 that this issue is now fixed. Not sure how long it was fixed prior to that.
Chrome+JavaScript+Windows=fast: On my old Dell from 2011 (Windows 7), the time spent in the JavaScript animation callback under Chrome (the render time) is crazy fast (around 0.45ms) compared to other web browsers and platforms (IE and Firefox are at least double that!). Why does this combination appear to have a significant speed advantage over other combinations (is it the CPU, memory speed, threading, JavaScript engine, or something else)? UPDATE: After some canvas fillText() changes, Chrome is now 'just as slow' as other web browsers.

  9. References
This section is under construction...
  • PMVR - The panorama viewer where I first noticed 'jank', causing me to research and find the VSYNC issue
  • Jank Free - a website dedicated to helping developers eliminate jank, by Chromium's Nat Duca and Paul Lewis
  • Jank Busting Tutorial - Jank Busting for Better Rendering Performance, by Google's Tom Wiltzius
  • Project Silk - a project by Mozilla to improve smoothness in Firefox, by Mozilla's Mason Chang
  • LCD monitor tests - A number of very nice tests for your display
  • TFT Central - News / Reviews / Articles / parts DB / etc
  • Test UFO - Many interesting motion tests (but it missed my VSYNC problems), by Mark Rejhon

Copyright © 2017 Jerry Jongerius