From 8cf278d30556c28ac1cd6c2e0bae0a9d2bc6508b Mon Sep 17 00:00:00 2001 From: Nicholas Ray Date: Mon, 28 Sep 2020 17:18:56 -0600 Subject: [PATCH] Add client-side performance metrics for searchLoader As part of comparing Vue search with legacy search, we need to track how long it takes to lazy load the wvui library. A similar metric was added to measuring the mediawiki.searchSuggest module in I0fa6b8904bd43c87a68e9161f00d686a0e588966. This commit adds the following metrics which will only be used in our synthetic tests. We are not doing RUM tests at this time. To test locally, add the following to your LocalSettings.php and append the query param `useskinversion=2` e.g. (http://localhost:8181/wiki/Test?useskinversion=2): ``` $wgVectorUseCoreSearch = false; ``` Marks: * mwVectorVueSearchLoadStart: Marks the start of loading the search module. * mwVectorVueSearchLoadEnd: Marks the end of loading the search module. Measures: * mwVectorVueSearchLoadStartToLoadEnd: Measures the time it takes to load the search module. Bug: T251544 Change-Id: I14e44b45a66213821d69cd22395fedbae747da88 --- resources/mediawiki.d.ts | 6 +++- resources/skins.vector.js/searchLoader.js | 38 +++++++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/resources/mediawiki.d.ts b/resources/mediawiki.d.ts index 7d488ca..ff25583 100644 --- a/resources/mediawiki.d.ts +++ b/resources/mediawiki.d.ts @@ -43,8 +43,12 @@ interface MediaWiki { * Execute a function after one or more modules are ready. * * @param moduleName + * @param {Function} ready Callback to execute when all dependencies are + * ready. + * @param {Function} after Callback to execute if one or more dependencies + * failed. */ - using( moduleName: string|null ): JQuery.Promise; + using( moduleName: string|null, ready?: Function, error?: Function ): JQuery.Promise; /** * Load a given resourceLoader module. diff --git a/resources/skins.vector.js/searchLoader.js b/resources/skins.vector.js/searchLoader.js index 427081b..074e56c 100644 --- a/resources/skins.vector.js/searchLoader.js +++ b/resources/skins.vector.js/searchLoader.js @@ -11,6 +11,17 @@ var /** @type {VectorResourceLoaderVirtualConfig} */ config = require( /** @type {string} */ ( './config.json' ) ), + // T251544: Collect search performance metrics to compare Vue search with + // mediawiki.searchSuggest performance. + SHOULD_TEST_SEARCH = !!( + !config.wgVectorUseCoreSearch && + window.performance && + performance.mark && + performance.measure && + performance.getEntriesByName ), + LOAD_START_MARK = 'mwVectorVueSearchLoadStart', + LOAD_END_MARK = 'mwVectorVueSearchLoadEnd', + LOAD_MEASURE = 'mwVectorVueSearchLoadStartToLoadEnd', SEARCH_FORM_ID = 'simpleSearch', SEARCH_INPUT_ID = 'searchInput', SEARCH_LOADING_CLASS = 'search-form__loader', @@ -32,7 +43,10 @@ var /** @type {VectorResourceLoaderVirtualConfig} */ function loadSearchModule( element, moduleName, afterLoadFn ) { function requestSearchModule() { - mw.loader.using( moduleName ).then( afterLoadFn ); + if ( SHOULD_TEST_SEARCH ) { + performance.mark( LOAD_START_MARK ); + } + mw.loader.using( moduleName, afterLoadFn ); element.removeEventListener( 'focus', requestSearchModule ); } @@ -101,6 +115,16 @@ function setLoadingIndicatorListeners( element, attach, eventCallback ) { } } +/** + * Marks when the lazy load has completed. + */ +function markLoadEnd() { + if ( SHOULD_TEST_SEARCH && performance.getEntriesByName( LOAD_START_MARK ).length ) { + performance.mark( LOAD_END_MARK ); + performance.measure( LOAD_MEASURE, LOAD_START_MARK, LOAD_END_MARK ); + } +} + /** * Initialize the loading of the search module as well as the loading indicator. * Only initialize the loading indicator when not using the core search module. @@ -128,9 +152,17 @@ function initSearchLoader( document ) { loadSearchModule( searchInput, SEARCH_MODULE_NAME, - setLoadingIndicatorListeners.bind( null, - searchForm, false, renderSearchLoadingIndicator ) + function () { + markLoadEnd(); + + setLoadingIndicatorListeners( + /** @type {HTMLElement} */ ( searchForm ), + false, + renderSearchLoadingIndicator + ); + } ); + } }