Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: tools/perf/metrics/speedindex.py

Issue 185413005: [Telemetry] Move page quiescence test to WebContents (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/perf/metrics/speedindex.js ('k') | tools/telemetry/telemetry/core/network_quiescence.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import collections 5 import collections
6 import os
7 6
8 from metrics import Metric 7 from metrics import Metric
9 from telemetry.core import bitmap 8 from telemetry.core import bitmap
10 9
11 10
12 class SpeedIndexMetric(Metric): 11 class SpeedIndexMetric(Metric):
13 """The speed index metric is one way of measuring page load speed. 12 """The speed index metric is one way of measuring page load speed.
14 13
15 It is meant to approximate user perception of page load speed, and it 14 It is meant to approximate user perception of page load speed, and it
16 is based on the amount of time that it takes to paint to the visual 15 is based on the amount of time that it takes to paint to the visual
17 portion of the screen. It includes paint events that occur after the 16 portion of the screen. It includes paint events that occur after the
18 onload event, and it doesn't include time loading things off-screen. 17 onload event, and it doesn't include time loading things off-screen.
19 18
20 This speed index metric is based on WebPageTest.org (WPT). 19 This speed index metric is based on WebPageTest.org (WPT).
21 For more info see: http://goo.gl/e7AH5l 20 For more info see: http://goo.gl/e7AH5l
22 """ 21 """
23 def __init__(self): 22 def __init__(self):
24 super(SpeedIndexMetric, self).__init__() 23 super(SpeedIndexMetric, self).__init__()
25 self._impl = None 24 self._impl = None
26 self._script_is_loaded = False
27 self._is_finished = False
28 with open(os.path.join(os.path.dirname(__file__), 'speedindex.js')) as f:
29 self._js = f.read()
30 25
31 @classmethod 26 @classmethod
32 def CustomizeBrowserOptions(cls, options): 27 def CustomizeBrowserOptions(cls, options):
33 options.AppendExtraBrowserArgs('--disable-infobars') 28 options.AppendExtraBrowserArgs('--disable-infobars')
34 29
35 def Start(self, _, tab): 30 def Start(self, _, tab):
36 """Start recording events. 31 """Start recording events.
37 32
38 This method should be called in the WillNavigateToPage method of 33 This method should be called in the WillNavigateToPage method of
39 a PageMeasurement, so that all the events can be captured. If it's called 34 a PageMeasurement, so that all the events can be captured. If it's called
40 in DidNavigateToPage, that will be too late. 35 in DidNavigateToPage, that will be too late.
41 """ 36 """
42 self._impl = (VideoSpeedIndexImpl() if tab.video_capture_supported else 37 self._impl = (VideoSpeedIndexImpl() if tab.video_capture_supported else
43 PaintRectSpeedIndexImpl()) 38 PaintRectSpeedIndexImpl())
44 self._impl.Start(tab) 39 self._impl.Start(tab)
45 self._script_is_loaded = False
46 self._is_finished = False
47 40
48 def Stop(self, _, tab): 41 def Stop(self, _, tab):
49 """Stop timeline recording.""" 42 """Stop timeline recording."""
50 assert self._impl, 'Must call Start() before Stop()' 43 assert self._impl, 'Must call Start() before Stop()'
51 assert self.IsFinished(tab), 'Must wait for IsFinished() before Stop()' 44 assert self.IsFinished(tab), 'Must wait for IsFinished() before Stop()'
52 self._impl.Stop(tab) 45 self._impl.Stop(tab)
53 46
54 # Optional argument chart_name is not in base class Metric. 47 # Optional argument chart_name is not in base class Metric.
55 # pylint: disable=W0221 48 # pylint: disable=W0221
56 def AddResults(self, tab, results, chart_name=None): 49 def AddResults(self, tab, results, chart_name=None):
(...skipping 14 matching lines...) Expand all
71 A page may repeatedly request resources in an infinite loop; a timeout 64 A page may repeatedly request resources in an infinite loop; a timeout
72 should be placed in any measurement that uses this metric, e.g.: 65 should be placed in any measurement that uses this metric, e.g.:
73 def IsDone(): 66 def IsDone():
74 return self._speedindex.IsFinished(tab) 67 return self._speedindex.IsFinished(tab)
75 util.WaitFor(IsDone, 60) 68 util.WaitFor(IsDone, 60)
76 69
77 Returns: 70 Returns:
78 True if 2 seconds have passed since last resource received, false 71 True if 2 seconds have passed since last resource received, false
79 otherwise. 72 otherwise.
80 """ 73 """
81 if self._is_finished: 74 return tab.HasReachedQuiescence()
82 return True
83
84 # The script that provides the function window.timeSinceLastResponseMs()
85 # needs to be loaded for this function, but it must be loaded AFTER
86 # the Start method is called, because if the Start method is called in
87 # the PageMeasurement's WillNavigateToPage function, then it will
88 # not be available here. The script should only be re-loaded once per page
89 # so that variables in the script get reset only for a new page.
90 if not self._script_is_loaded:
91 tab.ExecuteJavaScript(self._js)
92 self._script_is_loaded = True
93
94 time_since_last_response_ms = tab.EvaluateJavaScript(
95 "window.timeSinceLastResponseAfterLoadMs()")
96 self._is_finished = time_since_last_response_ms > 2000
97 return self._is_finished
98 75
99 76
100 class SpeedIndexImpl(object): 77 class SpeedIndexImpl(object):
101 78
102 def Start(self, tab): 79 def Start(self, tab):
103 raise NotImplementedError() 80 raise NotImplementedError()
104 81
105 def Stop(self, tab): 82 def Stop(self, tab):
106 raise NotImplementedError() 83 raise NotImplementedError()
107 84
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 frame = paint_event.args['frameId'] 295 frame = paint_event.args['frameId']
319 return (frame,) + GetBox(paint_event.args['data']['clip']) 296 return (frame,) + GetBox(paint_event.args['data']['clip'])
320 297
321 def _GroupEventByRectangle(self, paint_events): 298 def _GroupEventByRectangle(self, paint_events):
322 """Group all paint events according to the rectangle that they update.""" 299 """Group all paint events according to the rectangle that they update."""
323 result = collections.defaultdict(list) 300 result = collections.defaultdict(list)
324 for event in paint_events: 301 for event in paint_events:
325 assert event.name == 'Paint' 302 assert event.name == 'Paint'
326 result[self._GetRectangle(event)].append(event) 303 result[self._GetRectangle(event)].append(event)
327 return result 304 return result
OLDNEW
« no previous file with comments | « tools/perf/metrics/speedindex.js ('k') | tools/telemetry/telemetry/core/network_quiescence.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698