Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / tools / perf / measurements / blink_style.py
blobb46eab153b22eefb22cca4767c92ec8a170d936f
1 # Copyright 2015 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.
5 from itertools import starmap
6 from collections import defaultdict
7 from telemetry.core import util
8 from telemetry.core import exceptions
9 from telemetry.page import action_runner
10 from telemetry.page import page_test
11 from telemetry.value import scalar
13 from measurements import timeline_controller
16 class BlinkStyle(page_test.PageTest):
17 def __init__(self):
18 super(BlinkStyle, self).__init__()
19 self._controller = None
21 def WillNavigateToPage(self, page, tab):
22 self._controller = timeline_controller.TimelineController()
23 self._controller.trace_categories = 'blink_style,blink.console'
24 self._controller.SetUp(page, tab)
25 self._controller.Start(tab)
27 def CleanUpAfterPage(self, page, tab):
28 if self._controller:
29 self._controller.CleanUp(tab)
31 def ValidateAndMeasurePage(self, page, tab, results):
32 runner = action_runner.ActionRunner(tab)
33 with runner.CreateInteraction('wait-for-quiescence'):
34 tab.ExecuteJavaScript('console.time("");')
35 try:
36 util.WaitFor(tab.HasReachedQuiescence, 15)
37 except exceptions.TimeoutException:
38 # Some sites never reach quiesence. As this benchmark normalizes/
39 # categories results, it shouldn't be necessary to reach the same
40 # state on every run.
41 pass
43 tab.ExecuteJavaScript(
44 'console.time("style-update");'
45 # Occasionally documents will break the APIs we need.
46 'try {'
47 # Invalidate style for the whole document.
48 ' document && (document.documentElement.lang += "z");'
49 # Force a style update (but not layout).
50 ' getComputedStyle(document.documentElement).color;'
51 '} catch (e) {}'
52 'console.timeEnd("style-update");'
55 self._controller.Stop(tab, results)
56 renderer = self._controller.model.GetRendererThreadFromTabId(tab.id)
57 markers = [event for event in renderer.async_slices
58 if event.name == 'style-update'
59 and event.category == 'blink.console']
60 assert len(markers) == 1
61 marker = markers[0]
63 def duration(event):
64 if event.has_thread_timestamps:
65 return event.thread_duration
66 else:
67 return event.duration
69 for event in renderer.all_slices:
70 if (event.name == 'Document::updateStyle'
71 and event.start >= marker.start
72 and event.end <= marker.end):
73 access_count = event.args.get('resolverAccessCount')
74 if access_count is None:
75 # absent in earlier versions
76 continue
77 min_access_count = 50
79 if access_count >= min_access_count:
80 result = 1000 * (duration(event) / access_count)
81 results.AddValue(scalar.ScalarValue(
82 page, 'update_style', 'ms/1000 elements', result))
84 class ParserEvent(object):
85 def __init__(self, summary_event, tokenize_event, parse_event):
86 min_sheet_length = 1000
87 ua_sheet_mode = 5
88 enormous_token_threshold = 100
89 large_token_threshold = 5
91 self.mode = summary_event.args.get('mode')
92 self.length = summary_event.args.get('length')
93 self.tokens = summary_event.args.get('tokenCount')
94 self.tokenize_duration = duration(tokenize_event)
95 self.parse_duration = duration(parse_event)
96 self.chars_per_token = 0
97 if self.tokens:
98 self.chars_per_token = self.length / float(self.tokens)
99 if self.mode == ua_sheet_mode or self.length < min_sheet_length:
100 self.category = 'ignored'
101 elif self.chars_per_token > enormous_token_threshold:
102 self.category = 'enormous_tokens'
103 elif self.chars_per_token > large_token_threshold:
104 self.category = 'large_tokens'
105 else:
106 self.category = 'regular'
108 parser_events = [event for event in renderer.all_slices
109 if event.name == 'CSSParserImpl::parseStyleSheet'
110 or event.name == 'CSSParserImpl::parseStyleSheet.tokenize'
111 or event.name == 'CSSParserImpl::parseStyleSheet.parse']
113 merged_events = starmap(ParserEvent, zip(*[iter(parser_events)]*3))
115 events_by_category = defaultdict(list)
116 for event in merged_events:
117 if event.category != 'ignored':
118 events_by_category[event.category].append(event)
120 for category, events in events_by_category.items():
121 parse_duration = sum(event.parse_duration for event in events)
122 tokenize_duration = sum(event.tokenize_duration for event in events)
123 tokens = sum(event.tokens for event in events)
124 length = sum(event.length for event in events)
126 results.AddValue(
127 scalar.ScalarValue(page, ('parse_css_%s' % category),
128 'tokens/s', 1000 / (parse_duration / tokens)))
130 results.AddValue(
131 scalar.ScalarValue(page, ('tokenize_css_%s' % category),
132 'char/s', 1000 / (tokenize_duration / length)))