Chromium Code Reviews| Index: tools/telemetry/telemetry/web_perf/metrics/layout.py |
| diff --git a/tools/telemetry/telemetry/web_perf/metrics/layout.py b/tools/telemetry/telemetry/web_perf/metrics/layout.py |
| index baa5295a7aa2a35b73531b03dd292c87b8b76074..a8494e17e72dd40bd4888874ef2d3eafac991b4b 100644 |
| --- a/tools/telemetry/telemetry/web_perf/metrics/layout.py |
| +++ b/tools/telemetry/telemetry/web_perf/metrics/layout.py |
| @@ -3,55 +3,53 @@ |
| # found in the LICENSE file. |
| import math |
| -from telemetry.value import scalar |
| +from telemetry.value import list_of_scalar_values |
| from telemetry.web_perf.metrics import timeline_based_metric |
| class LayoutMetric(timeline_based_metric.TimelineBasedMetric): |
| - """Computes metrics that measure layout performance, specifically, |
| - avg and stddev of CPU time of layout-related trace events: |
| + """Reports directly durations of FrameView::performLayout events. |
| - layout_total_{avg,stddev}: FrameView::layout |
| - layout_{avg,stddev}: FrameView::performLayout |
| - pre_layout_{avg,stddev}: FrameView::performPreLayoutTasks |
| - post_layout_{avg,stddev}: FrameView::performPostLayoutTasks |
| - layer_positions_{avg,stddev}: RenderLayer::updateLayerPositionsAfterLayout |
| + layout_load: Layout events caused by page load. |
| + layout_animation: Layout events caused by user interaction. |
| Layout happens no more than once per frame, so per-frame-ness is implied. |
| - Not all pages have interactions, so interaction records are not required. |
| """ |
| - EVENTS = { |
| - 'FrameView::layout': 'layout_total', |
| - 'FrameView::performLayout': 'layout', |
| - 'FrameView::performPreLayoutTasks': 'pre_layout', |
| - 'FrameView::performPostLayoutTasks': 'post_layout', |
| - 'RenderLayer::updateLayerPositionsAfterLayout': 'layer_positions', |
| - } |
| def __init__(self): |
| super(LayoutMetric, self).__init__() |
| - def AddResults(self, _model, renderer_thread, _interaction_records, results): |
| - self._AddResults(renderer_thread.parent.IterAllSlices(), results) |
| - |
| - def _AddResults(self, events, results): |
| - metrics = dict((long_name, (short_name, [])) for long_name, short_name in |
| - self.EVENTS.iteritems()) |
| + def AddResults(self, _model, renderer_thread, interactions, results): |
| + self._AddResultsInternal(renderer_thread.parent.IterAllSlices(), |
| + interactions, results) |
| + def _AddResultsInternal(self, events, interactions, results): |
| + layouts = [] |
| for event in events: |
| - if event.name in metrics: |
| - metrics[event.name][1].append(event.end - event.start) |
| - |
| - for long_name, (short_name, durations) in metrics.iteritems(): |
| - count = len(durations) |
| - avg = 0.0 |
| - stddev = 0.0 |
| - if count: |
| - avg = sum(durations) / count |
| - stddev = math.sqrt(sum((d - avg) ** 2 for d in durations) / count) |
| - results.AddValue(scalar.ScalarValue(results.current_page, |
| - short_name + '_avg', 'ms', avg, |
| - description='Average duration of %s events' % long_name)) |
| - results.AddValue(scalar.ScalarValue(results.current_page, |
| - short_name + '_stddev', 'ms', stddev, |
| - description='stddev of duration of %s events' % long_name)) |
| + if ((event.name == 'FrameView::performLayout') and |
| + ((not interactions) or any( |
| + interaction.start <= event.start < interaction.end |
| + for interaction in interactions))): |
| + layouts.append(event.end - event.start) |
| + if not layouts: |
| + return |
| + description = 'List of durations of layouts' |
| + label = 'layout' |
| + if interactions: |
| + if interactions[0].label == 'load': |
|
nednguyen
2015/03/31 22:49:03
This sounds about right. However, to check whether
benjhayden
2015/04/01 20:22:45
Let's punt the load event to another CL.
nednguyen
2015/04/01 20:25:50
I like this. Fixing the TODO is add the Load inter
|
| + # Loading a page should take no more than 1000ms, so load layout may |
| + # take some hundreds of ms total. |
| + label += '_load' |
|
nednguyen
2015/03/31 22:49:03
label is supposed to be just interaction record la
benjhayden
2015/04/01 20:22:45
It sounds like you're saying that the result label
nednguyen
2015/04/01 20:25:50
label is interaction record label, name is for the
|
| + else: |
| + # We don't care if the interactions are Smoothness or Click or Swipe or |
| + # Scroll or whatever, all we care about is that the layout events were |
| + # caused by user interaction rather than load. |
| + # Animations should take no more than 150ms to paint the first frame |
| + # after an interaction begins, then no more than 16ms for each frame |
| + # after that. So the first layout after an interaction begins should |
| + # cost no more than 100ms or so, and every layout after that should cost |
| + # no more than 5ms or so. |
| + label += '_animation' |
| + description += ' that start in response to user interaction' |
| + results.AddValue(list_of_scalar_values.ListOfScalarValues( |
| + results.current_page, label, 'ms', layouts, description=description)) |