Merge "[search] Add Vue search performance instrumentation"

This commit is contained in:
jenkins-bot 2020-12-09 00:06:32 +00:00 committed by Gerrit Code Review
commit 454611f60a
2 changed files with 63 additions and 1 deletions

View file

@ -16,6 +16,7 @@
:search-language="language"
:show-thumbnail="showThumbnail"
:show-description="showDescription"
@fetch-start="instrumentation.onFetchStart"
@fetch-end="instrumentation.onFetchEnd"
@suggestion-click="instrumentation.onSuggestionClick"
>

View file

@ -8,7 +8,37 @@
* @see https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/skins/Vector/+/refs/heads/master/includes/Constants.php
*/
var INPUT_LOCATION_MOVED = 'header-moved',
wgScript = mw.config.get( 'wgScript' );
wgScript = mw.config.get( 'wgScript' ),
// T251544: Collect search performance metrics to compare Vue search with
// mediawiki.searchSuggest performance. Marks and Measures will only be
// recorded on the Vector skin and only if browser supported.
shouldTestSearchPerformance = !!( window.performance &&
window.requestAnimationFrame &&
performance.mark &&
performance.measure &&
performance.getEntriesByName &&
performance.clearMarks ),
loadStartMark = 'mwVectorVueSearchLoadStart',
queryMark = 'mwVectorVueSearchQuery',
renderMark = 'mwVectorVueSearchRender',
queryToRenderMeasure = 'mwVectorVueSearchQueryToRender',
loadStartToFirstRenderMeasure = 'mwVectorVueSearchLoadStartToFirstRender';
function onFetchStart() {
if ( !shouldTestSearchPerformance ) {
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 );
}
/**
* @param {FetchEndEvent} event
@ -22,6 +52,36 @@ function onFetchEnd( event ) {
query: event.query,
inputLocation: INPUT_LOCATION_MOVED
} );
if ( shouldTestSearchPerformance ) {
// 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 );
} );
} );
}
}
/**
@ -91,6 +151,7 @@ function generateUrl( suggestion, meta ) {
module.exports = {
listeners: {
onFetchStart: onFetchStart,
onFetchEnd: onFetchEnd,
onSuggestionClick: onSuggestionClick,