aboutsummaryrefslogtreecommitdiffstats
path: root/resources/src/mediawiki.searchSuggest
diff options
context:
space:
mode:
authorNicholas Ray <nray@wikimedia.org>2020-10-08 10:10:34 -0600
committerNicholas Ray <nray@wikimedia.org>2020-10-09 10:56:19 -0600
commitee22af6ef7f5b6be750c0819764caa1900fe361f (patch)
treecb6b552762aa8bbb12230fd13ef8b7bc73619cd6 /resources/src/mediawiki.searchSuggest
parentd14ce36a8c6578fca8a38d010a6167d73849cffe (diff)
downloadmediawikicore-ee22af6ef7f5b6be750c0819764caa1900fe361f.tar.gz
mediawikicore-ee22af6ef7f5b6be750c0819764caa1900fe361f.zip
Add client-side performance metrics for legacy search
As part of comparing Vue search with legacy search, we need to track how long it takes a keypress to load and render search results for legacy search (Vue search will perform the same metrics). This commit adds the following metrics which will only be used in our synthetic tests. We are not collecting RUM metrics at this time. Marks: * mwVectorLegacySearchLoadStart: Marks start of loading the search module. * mwVectorLegacySearchLoadEnd: Marks the end of loading the search module. Measures: * mwVectorLegacySearchLoadStartToLoadEnd: Measures the time it takes to load the search module. * mwVectorLegacySearchLoadStartToFirstRender: Measures the time it takes from the start of loading the search module to the first render of results. * mwVectorLegacySearchQueryToRender: Measures the time it takes from the start of the fetch to the render of search results. Additional changes: * Fixed a bug in loadSearchModule that added an unneeded `focusin` event listener when the input has already received focus. Bug: T251544 Change-Id: I0fa6b8904bd43c87a68e9161f00d686a0e588966
Diffstat (limited to 'resources/src/mediawiki.searchSuggest')
-rw-r--r--resources/src/mediawiki.searchSuggest/searchSuggest.js68
1 files changed, 64 insertions, 4 deletions
diff --git a/resources/src/mediawiki.searchSuggest/searchSuggest.js b/resources/src/mediawiki.searchSuggest/searchSuggest.js
index 04262775a0e0..c5357305d5b8 100644
--- a/resources/src/mediawiki.searchSuggest/searchSuggest.js
+++ b/resources/src/mediawiki.searchSuggest/searchSuggest.js
@@ -4,11 +4,27 @@
( function () {
// eslint-disable-next-line no-jquery/no-map-util
var searchNS = $.map( mw.config.get( 'wgFormattedNamespaces' ), function ( nsName, nsID ) {
- if ( nsID >= 0 && mw.user.options.get( 'searchNs' + nsID ) ) {
+ if ( nsID >= 0 && mw.user.options.get( 'searchNs' + nsID ) ) {
// Cast string key to number
- return Number( nsID );
- }
- } );
+ return Number( nsID );
+ }
+ } ),
+ // T251544: Collect search performance metrics to compare Vue search with
+ // mediawiki.searchSuggest performance. Marks and Measures will only be
+ // recorded on the Vector skin.
+ shouldTestSearch = !!( mw.config.get( 'skin' ) === 'vector' &&
+ window.performance &&
+ window.requestAnimationFrame &&
+ performance.mark &&
+ performance.measure &&
+ performance.getEntriesByName &&
+ performance.clearMarks ),
+ loadStartMark = 'mwVectorLegacySearchLoadStart',
+ queryMark = 'mwVectorLegacySearchQuery',
+ renderMark = 'mwVectorLegacySearchRender',
+ queryToRenderMeasure = 'mwVectorLegacySearchQueryToRender',
+ loadStartToFirstRenderMeasure = 'mwVectorLegacySearchLoadStartToFirstRender';
+
mw.searchSuggest = {
// queries the wiki and calls response with the result
request: function ( api, query, response, maxRows, namespace ) {
@@ -90,6 +106,20 @@
} );
}
previousSearchText = searchText;
+
+ if ( !shouldTestSearch ) {
+ return;
+ }
+
+ // Clear past marks that are no longer relevant. This likely means that the
+ // search request failed or was cancelled. Whatever the reason, the mark
+ // is no longer needed since we are only interested in collecting the time
+ // from query to render.
+ if ( performance.getEntriesByName( queryMark ).length ) {
+ performance.clearMarks( queryMark );
+ }
+
+ performance.mark( queryMark );
}
/**
@@ -128,6 +158,36 @@
query: metadata.query,
inputLocation: getInputLocation( context )
} );
+
+ if ( shouldTestSearch ) {
+ // Schedule the mark after the search results have rendered and are
+ // visible to the user. Two rAF's are needed for this since rAF will
+ // execute before the rendering steps happen (e.g. layout and paint). A
+ // nested rAF will execute after these rendering steps have completed
+ // and ensure the search results are visible to the user.
+ requestAnimationFrame( function () {
+ requestAnimationFrame( function () {
+ if ( !performance.getEntriesByName( queryMark ).length ) {
+ return;
+ }
+
+ performance.mark( renderMark );
+ performance.measure( queryToRenderMeasure, queryMark, renderMark );
+
+ // Measure from the start of the lazy load to the first render if we
+ // haven't already captured that info.
+ if ( performance.getEntriesByName( loadStartMark ).length &&
+ !performance.getEntriesByName( loadStartToFirstRenderMeasure ).length ) {
+ performance.measure( loadStartToFirstRenderMeasure, loadStartMark, renderMark );
+ }
+
+ // The measures are the most meaningful info so we remove the marks
+ // after we have the measure.
+ performance.clearMarks( queryMark );
+ performance.clearMarks( renderMark );
+ } );
+ } );
+ }
}
// The function used to render the suggestions.