1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 * @fileoverview This file provides a JavaScript helper function that
9 * determines when network quiescence has been reached based on the time since
10 * the last resource was received.
14 // Make executing this code idempotent.
15 if (window.__telemetry_testHasReachedNetworkQuiescence) {
19 // Some benchmarks patch window.performance to make it deterministic.
20 // Save the original performance object before it is patched.
21 var real_performance = window.performance;
23 // Set the Resource Timing interface functions that will be used below
24 // to use whatever version is available currently regardless of vendor
26 real_performance.clearResourceTimings =
27 (real_performance.clearResourceTimings ||
28 real_performance.mozClearResourceTimings ||
29 real_performance.msClearResourceTimings ||
30 real_performance.oClearResourceTimings ||
31 real_performance.webkitClearResourceTimings);
33 real_performance.getEntriesByType =
34 (real_performance.getEntriesByType ||
35 real_performance.mozGetEntriesByType ||
36 real_performance.msGetEntriesByType ||
37 real_performance.oGetEntriesByType ||
38 real_performance.webkitGetEntriesByType);
40 // This variable will available to the function below and it will be
41 // persistent across different function calls. It stores the last
42 // entry in the list of PerformanceResourceTiming objects returned by
43 // real_performance.getEntriesByType('resource').
45 // The reason for doing it this way is because the buffer for
46 // PerformanceResourceTiming objects has a limit, and once it's full,
47 // new entries are not added. We're only interested in the last entry,
48 // so we can clear new entries when they're added.
51 // True when no resource has been loaded from the network for
52 //|QUIESCENCE_TIMEOUT_MS| milliseconds. This value is sticky.
53 var hasReachedQuiesence = false;
55 // Time to wait before declaring network quiescence in milliseconds.
56 var QUIESCENCE_TIMEOUT_MS = 2000;
59 * This method uses the Resource Timing interface, which is described at
60 * http://www.w3.org/TR/resource-timing/. It determines whether the time
61 * since lodading any resources such as images and script files (including
62 * resources requested via XMLHttpRequest) has exceeded a threshold defined
63 # by |QUIESCENCE_TIMEOUT_MS|.
65 * @return {boolean} True if the time since either the load event, or the last
66 * resource was received after the load event exceeds the aforementioned
67 * threshold. This state is sticky, so once this function returns true for a
68 * given page, it will always return true.
70 window.__telemetry_testHasReachedNetworkQuiescence = function() {
71 if (hasReachedQuiesence) {
75 if (window.document.readyState !== 'complete') {
79 var resourceTimings = real_performance.getEntriesByType('resource');
80 if (resourceTimings.length > 0) {
81 lastEntry = resourceTimings.pop();
82 real_performance.clearResourceTimings();
85 // The times for performance.now() and in the PerformanceResourceTiming
86 // objects are all in milliseconds since performance.timing.navigationStart,
87 // so we must also get load time in the same terms.
88 var timing = real_performance.timing;
89 var loadTime = timing.loadEventEnd - timing.navigationStart;
90 var lastResponseTimeMs = 0;
92 // If there have been no resource timing entries, or the last entry was
93 // before the load event, then use the time since the load event.
94 if (!lastEntry || lastEntry.responseEnd < loadTime) {
95 lastResponseTimeMs = real_performance.now() - loadTime;
97 lastResponseTimeMs = real_performance.now() - lastEntry.responseEnd;
100 if (lastResponseTimeMs >= QUIESCENCE_TIMEOUT_MS) {
101 hasReachedQuiesence = true;
104 return hasReachedQuiesence;