Commit 683608bf authored by Yuheng Huang's avatar Yuheng Huang Committed by Commit Bot

Tab Search: Implement performance benchmark

Doc:
https://docs.google.com/document/d/1-1ijT7wt05hlBZmSKjX_DaTCzVqpxbfTM1y-j7kYHlc
Usage:
tools/perf/run_benchmark run UNSCHEDULED_tab_search --browser-executable=out/Default/chrome --story-filter=tab_search:top10:2020
tools/perf/run_benchmark run UNSCHEDULED_tab_search --browser-executable=out/Default/chrome --story-filter=tab_search:top50:2020
tools/perf/run_benchmark run UNSCHEDULED_tab_search --browser-executable=out/Default/chrome --story-filter=tab_search:top100:2020

Change-Id: I684024f9cf3264ac2ed4feca15c6059342a493c2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2461224
Commit-Queue: Yuheng Huang <yuhengh@chromium.org>
Reviewed-by: default avatarJohn Chen <johnchen@chromium.org>
Reviewed-by: default avatarThomas Lukaszewicz <tluk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824599}
parent 17f1907c
......@@ -3,6 +3,7 @@ See the following link for directions for making changes to this data:,https://b
Googlers can view additional information about internal perf infrastructure at,https://goto.google.com/chrome-benchmarking-sheet
Benchmark name,Individual owners,Component,Documentation,Tags
UNSCHEDULED_blink_perf.service_worker,"shimazu@chromium.org, falken@chromium.org, ting.shao@intel.com",Blink>ServiceWorker,https://bit.ly/blink-perf-benchmarks,
UNSCHEDULED_tab_search,"yuhengh@chromium.org, tluk@chromium.org, romanarora@chromium.org",UI>Browser>TabSearch,,
base_perftests,"skyostil@chromium.org, gab@chromium.org",Internals>SequenceManager,https://chromium.googlesource.com/chromium/src/+/HEAD/base/README.md#performance-testing,
blink_perf.accessibility,dmazzoni@chromium.org,Blink>Accessibility,https://bit.ly/blink-perf-benchmarks,all
blink_perf.bindings,"jbroman@chromium.org, yukishiino@chromium.org, haraken@chromium.org",Blink>Bindings,https://bit.ly/blink-perf-benchmarks,all
......
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from core import perf_benchmark
from core import platforms
from telemetry import benchmark
from telemetry import story
from telemetry.timeline import chrome_trace_category_filter
from telemetry.web_perf import timeline_based_measurement
import page_sets
TAB_SEARCH_BENCHMARK_UMA = [
'Tabs.TabSearch.CloseAction',
'Tabs.TabSearch.NumTabsClosedPerInstance',
'Tabs.TabSearch.NumTabsOnOpen',
'Tabs.TabSearch.NumWindowsOnOpen',
'Tabs.TabSearch.OpenAction',
'Tabs.TabSearch.PageHandlerConstructionDelay',
'Tabs.TabSearch.WebUI.InitialTabsRenderTime',
'Tabs.TabSearch.WebUI.LoadCompletedTime',
'Tabs.TabSearch.WebUI.LoadDocumentTime',
'Tabs.TabSearch.WebUI.TabListDataReceived',
'Tabs.TabSearch.WebUI.TabSwitchAction',
'Tabs.TabSearch.WindowDisplayedDuration2',
'Tabs.TabSearch.WindowTimeToShowCachedWebView',
'Tabs.TabSearch.WindowTimeToShowUncachedWebView',
]
@benchmark.Info(emails=[
'yuhengh@chromium.org', 'tluk@chromium.org', 'romanarora@chromium.org'
],
component='UI>Browser>TabSearch')
class TabSearch(perf_benchmark.PerfBenchmark):
"""Tab Search Benchmark."""
PLATFORM = 'desktop'
SUPPORTED_PLATFORM_TAGS = [platforms.DESKTOP]
SUPPORTED_PLATFORMS = [story.expectations.ALL_DESKTOP]
def CreateStorySet(self, options):
return page_sets.TabSearchStorySet()
def CreateCoreTimelineBasedMeasurementOptions(self):
category_filter = chrome_trace_category_filter.ChromeTraceCategoryFilter(
filter_string='uma')
category_filter.AddIncludedCategory('browser')
category_filter.AddIncludedCategory('blink.user_timing')
options = timeline_based_measurement.Options(category_filter)
options.config.chrome_trace_config.EnableUMAHistograms(
*TAB_SEARCH_BENCHMARK_UMA)
options.SetTimelineBasedMetrics(['webuiMetric', 'umaMetric'])
return options
@classmethod
def Name(cls):
return 'UNSCHEDULED_tab_search'
......@@ -24,6 +24,7 @@ UNDOCUMENTED_BENCHMARKS = {
'speedometer2-future',
'startup.mobile',
'system_health.webview_startup',
'UNSCHEDULED_tab_search',
'tab_switching.typical_25',
'tracing.tracing_with_background_memory_infra',
'tracing_perftests',
......
{
"archives": {
"tab_search:top100:2020": {
"DEFAULT": "tab_search_desktop_fecd976705.wprgo"
},
"tab_search:top10:2020": {
"DEFAULT": "tab_search_desktop_fecd976705.wprgo"
},
"tab_search:top50:2020": {
"DEFAULT": "tab_search_desktop_fecd976705.wprgo"
}
},
"description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
"platform_specific": true
}
\ No newline at end of file
fecd97670591a1a142d31682f7d58a1c4639ee7c
\ No newline at end of file
yuhengh@chromium.org
tluk@chromium.org
romanarora@chromium.org
\ No newline at end of file
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
""" This package contains tab search stories."""
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from telemetry import story
from page_sets.tab_search import tab_search_story
class TabSearchStorySet(story.StorySet):
STORIES = [
tab_search_story.TabSearchStoryTop10,
tab_search_story.TabSearchStoryTop50,
tab_search_story.TabSearchStoryTop100,
]
def __init__(self):
super(TabSearchStorySet,
self).__init__(archive_data_file=('../data/tab_search_desktop.json'),
cloud_storage_bucket=story.PARTNER_BUCKET)
for cls in self.STORIES:
self.AddStory(cls(self, '--enable-features=TabSearch'))
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import py_utils
from telemetry.page import page
from telemetry.internal.actions.action_runner import ActionRunner
TOP_URL = [
'google.com',
'youtube.com',
'amazon.com',
'facebook.com',
'zoom.us',
'yahoo.com',
'reddit.com',
'wikipedia.org',
'myshopify.com',
'ebay.com',
'instructure.com',
'office.com',
'netflix.com',
'bing.com',
'live.com',
'microsoft.com',
'espn.com',
'twitch.tv',
'blogger.com',
'instagram.com',
'mozilla.org',
'cnn.com',
'apple.com',
'zillow.com',
'etsy.com',
'chase.com',
'nytimes.com',
'linkedin.com',
'dropbox.com',
'adobe.com',
'okta.com',
'craigslist.org',
'twitter.com',
'walmart.com',
'aliexpress.com',
'github.com',
'vimeo.com',
'quizlet.com',
'tmall.com',
'imgur.com',
'wellsfargo.com',
'hulu.com',
'imdb.com',
'salesforce.com',
'homedepot.com',
'indeed.com',
'foxnews.com',
'msn.com',
'spotify.com',
'whatsapp.com',
]
class TabSearchStory(page.Page):
"""Base class for tab search stories"""
def __init__(self, story_set, extra_browser_args=None):
super(TabSearchStory, self).__init__(url=self.URL,
name=self.NAME,
page_set=story_set,
extra_browser_args=extra_browser_args)
def RunNavigateSteps(self, action_runner):
url_list = self.URL_LIST
tabs = action_runner.tab.browser.tabs
tabs[0].Navigate('https://' + url_list[0])
for url in url_list[1:]:
new_tab = tabs.New()
new_tab.Navigate('https://' + url)
if self.WAIT_FOR_NETWORK_QUIESCENCE:
for i, url in enumerate(url_list):
try:
tabs[i].action_runner.WaitForNetworkQuiescence()
except py_utils.TimeoutException:
logging.warning('WaitForNetworkQuiescence() timeout, url[%d]: %s' %
(i, url))
def RunPageInteractions(self, action_runner):
tabs = action_runner.tab.browser.tabs
tabs_len = len(tabs)
# Open Tab Search bubble.
action_runner.tab.browser.supports_inspecting_webui = True
action_runner.tab.browser.ExecuteBrowserCommand('openTabSearch')
# Wait for Tab Search bubble to be inspectable.
py_utils.WaitFor(lambda: len(tabs) > tabs_len, 10)
# Wait for Tab Search bubble to load.
tab = tabs[-1]
action_runner = ActionRunner(
tab) # Recreate action_runner for Tab Search bubble.
tab.WaitForDocumentReadyStateToBeComplete()
# Send key navigation to Tab Search bubble.
self.InteractWithPage(action_runner)
def InteractWithPage(self, action_runner):
self.ScrollTabs(action_runner)
self.SearchTabs(action_runner)
self.CloseTab(action_runner)
def ScrollUp(self, action_runner):
action_runner.Wait(1)
# Scroll to the bottom of the list.
action_runner.PressKey('ArrowUp')
action_runner.Wait(1)
def SearchTabs(self, action_runner):
action_runner.Wait(1)
action_runner.EnterText('o')
action_runner.Wait(2)
action_runner.PressKey('Backspace')
action_runner.Wait(1)
def CloseTab(self, action_runner):
action_runner.Wait(1)
# Tab to the close button of the 2nd tab.
action_runner.PressKey('Tab', repeat_count=4, repeat_delay_ms=500)
action_runner.PressKey(' ')
action_runner.Wait(1)
def ScrollTabs(self, action_runner):
action_runner.Wait(1)
self.StartMeasuringFrameTime(action_runner, 'frame_time_on_scroll')
action_runner.ScrollElement(element_function=SCROLL_ELEMENT_FUNCTION)
self.StopMeasuringFrameTime(action_runner)
action_runner.Wait(1)
def CloseAndOpen(self, action_runner):
action_runner.Wait(1)
action_runner.tab.browser.ExecuteBrowserCommand('closeTabSearch')
action_runner.Wait(1)
action_runner.tab.browser.ExecuteBrowserCommand('openTabSearch')
action_runner.Wait(5)
def StartMeasuringFrameTime(self, action_runner, name):
action_runner.ExecuteJavaScript(MEASURE_FRAME_TIME_SCRIPT)
action_runner.ExecuteJavaScript(START_MEASURING_FRAME_TIME % name)
def StopMeasuringFrameTime(self, action_runner):
action_runner.ExecuteJavaScript(STOP_MEASURING_FRAME_TIME)
class TabSearchStoryTop10(TabSearchStory):
NAME = 'tab_search:top10:2020'
URL_LIST = TOP_URL[:10]
URL = 'https://' + URL_LIST[0]
WAIT_FOR_NETWORK_QUIESCENCE = True
class TabSearchStoryTop50(TabSearchStory):
NAME = 'tab_search:top50:2020'
URL_LIST = TOP_URL[:50]
URL = 'https://' + URL_LIST[0]
WAIT_FOR_NETWORK_QUIESCENCE = True
class TabSearchStoryTop100(TabSearchStory):
NAME = 'tab_search:top100:2020'
URL_LIST = TOP_URL[:50] * 2
URL = 'https://' + URL_LIST[0]
WAIT_FOR_NETWORK_QUIESCENCE = True
SCROLL_ELEMENT_FUNCTION = '''
document.querySelector('tab-search-app').shadowRoot.querySelector('#tabs')
'''
MEASURE_FRAME_TIME_SCRIPT = '''
window.__webui_startMeasuringFrameTime = function(name) {
if (!window.__webui_onRequestAnimationFrame) {
window.__webui_onRequestAnimationFrame = function() {
performance.mark(name + ':benchmark_end');
if (window.__webui_onRequestAnimationFrame) {
requestAnimationFrame(window.__webui_onRequestAnimationFrame);
performance.mark(name + ':benchmark_begin')
}
}
performance.mark(name + ':benchmark_begin')
requestAnimationFrame(window.__webui_onRequestAnimationFrame);
}
}
window.__webui_stopMeasuringFrameTime = function() {
window.__webui_onRequestAnimationFrame = null;
}
'''
START_MEASURING_FRAME_TIME = '''
window.__webui_startMeasuringFrameTime('%s')
'''
STOP_MEASURING_FRAME_TIME = '''
window.__webui_stopMeasuringFrameTime()
'''
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment