Jonas Kress (WMDE) has uploaded a new change for review. https://gerrit.wikimedia.org/r/269299
Change subject: [WIP] Advanced performance statistics ...................................................................... [WIP] Advanced performance statistics Introduces performance widget that shows statistic data and adds several performance marks Change-Id: I1f626f05ba98d81c14eaf974eb546b30512e46f2 --- M repo/resources/Resources.php M repo/resources/performance/Mark.js A repo/resources/performance/PerformanceMark.js A repo/resources/performance/Statistic.js M repo/resources/performance/resources.php M repo/resources/wikibase.ui.entityViewInit.js M view/resources/jquery/wikibase/jquery.wikibase.entityview.js M view/resources/jquery/wikibase/jquery.wikibase.itemview.js M view/resources/jquery/wikibase/jquery.wikibase.statementview.js 9 files changed, 239 insertions(+), 5 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase refs/changes/99/269299/1 diff --git a/repo/resources/Resources.php b/repo/resources/Resources.php index 73bbc48..e1df5e2 100644 --- a/repo/resources/Resources.php +++ b/repo/resources/Resources.php @@ -106,7 +106,7 @@ 'wikibase.store.CombiningEntityStore', 'wikibase.view.ViewFactory', 'wikibase.WikibaseContentLanguages', - 'wikibase.performance.Mark' + 'wikibase.performance.Mark', ), 'messages' => array( 'pagetitle', diff --git a/repo/resources/performance/Mark.js b/repo/resources/performance/Mark.js index 571e045..f037d44 100644 --- a/repo/resources/performance/Mark.js +++ b/repo/resources/performance/Mark.js @@ -3,6 +3,10 @@ var MODULE = wb.performance; + var MARK_START = '::START'; + var MARK_END = '::END'; + + /** * Wikibase performance mark * @@ -13,7 +17,15 @@ * @static * @param {string} name */ - MODULE.Mark = function( name ) { + var SELF = MODULE.Mark = function( name ) { + SELF._mark( name ); + }; + + /** + * @private + * @static + **/ + SELF._mark = function( name ) { if ( !performance ) { return; } @@ -21,4 +33,56 @@ performance.mark( name ); }; + /** + * Sets a start mark + * + * @static + * @param {string} name + **/ + SELF.addStart = function( name ) { + this._mark( name + MARK_START ); + }; + + /** + * Sets an end mark + * + * @static + * @param {string} name + **/ + SELF.addEnd = function( name ) { + this._mark( name + MARK_END ); + }; + + /** + * Get entries + * + * @static + * @return {PerformanceMark[]} + **/ + SELF.getAllMarks = function() { + var marks = {}, totals = {}, PerformanceMark = wb.performance.PerformanceMark; + + $.each( window.performance.getEntriesByType( 'mark' ), function() { + var markName = this.name.replace( MARK_START, '' ).replace( MARK_END, '' ); + + if( !marks[markName] ){ + marks[markName] = this; + + } else { + if( !totals[ markName ] ){ + totals[ markName ] = new PerformanceMark(); + totals[ markName ].name = markName; + } + var duration = (this.startTime - marks[markName].startTime); + totals[ markName ].duration += duration + totals[ markName ].durations.push( duration ); + + delete marks[markName]; + } + } ); + + return totals; + }; + + }( wikibase, window.performance ) ); diff --git a/repo/resources/performance/PerformanceMark.js b/repo/resources/performance/PerformanceMark.js new file mode 100644 index 0000000..b7cd0ea --- /dev/null +++ b/repo/resources/performance/PerformanceMark.js @@ -0,0 +1,38 @@ +( function( wb ) { + 'use strict'; + + var MODULE = wb.performance; + + /** + * Wikibase performance performanceMark + * + * @class wikibase.performance.PerformanceMark + * @licence GNU GPL v2+ + * + * @author Jonas Kress + * @constructor + * @param {string} name + */ + var SELF = MODULE.PerformanceMark = function( name ) { + this.name = ''; + this.duration = 0; + this.durations = []; + }; + + /** + * @property {string} + **/ + SELF.prototype.name; + + /** + * @property {int} + **/ + SELF.prototype.duration; + + /** + * @property {int[]} + **/ + SELF.prototype.durations; + + +}( wikibase ) ); diff --git a/repo/resources/performance/Statistic.js b/repo/resources/performance/Statistic.js new file mode 100644 index 0000000..ae0e79f --- /dev/null +++ b/repo/resources/performance/Statistic.js @@ -0,0 +1,83 @@ +( function( wb, $ ) { + "use strict"; + + var MODULE = wb.performance; + + /** + * Wikibase performance statistic + * + * @class wikibase.performance.Statistic + * @licence GNU GPL v2+ + * + * @author Jonas Kress + * @constructor + * @param {PerformanceMarks[]} + */ + var SELF = MODULE.Statistic = function( performanceMarks ) { + + this._marks = performanceMarks; + } + + /** + * @property {PerformanceMark[]} + * @private + **/ + SELF.prototype._marks = null; + + /** + * Get HTML + * @return {jQuery} + **/ + SELF.prototype.getHtml = function() { + var self = this, $div = $( '<div/>' ); + + $.each ( this._marks, function( key, value) { + + var durationTotal = self._formatDuration( value.duration ), + durationsMinMaxAvg = self._getMinAverageMax( value.durations ).map( self._formatDuration ), + durations = value.durations; + + var text = key + ': ' + durationTotal, + title = null; + + if( durations.length > 1 ) { + text = key + ' (' + durations.length +'): ' + durationTotal; + title = 'Min: ' + durationsMinMaxAvg[0] + '\n' + + 'Avg: ' + durationsMinMaxAvg[1] + '\n' + + 'Max: ' + durationsMinMaxAvg[2]; + } + + $div.prepend( $( '<div/>' ).text( text ) + .attr( 'title', title ) ); + } ); + + return $div + }; + + SELF.prototype._formatDuration = function( duration ) { + return ( Math.round( duration ) / 1000 ) + 's'; + } + + /** + * Get HTML + * @private + * @return {int[]} [Minimum, Average, Maximum] + **/ + SELF.prototype._getMinAverageMax = function( array ) { + var max = array[0]; + var min = array[0]; + var sum = 0 ; + + $.each( array, function() { + if( this > max ) + max = this; + if( this < min ) + min = this; + sum += this; + } ); + + var avg = sum / array.length; + return [min, avg, max]; + }; + +}( wikibase, jQuery ) ); diff --git a/repo/resources/performance/resources.php b/repo/resources/performance/resources.php index 850f032..48755b4 100644 --- a/repo/resources/performance/resources.php +++ b/repo/resources/performance/resources.php @@ -27,10 +27,21 @@ 'wikibase.performance.Mark' => $moduleTemplate + array( 'scripts' => array( 'Mark.js', + 'PerformanceMark.js', ), 'dependencies' => array( 'wikibase.performance.__namespace', ), ), + 'wikibase.performance.Statistic' => $moduleTemplate + array( + 'scripts' => array( + 'Statistic.js', + ), + 'dependencies' => array( + 'wikibase.performance.__namespace', + 'wikibase.performance.Mark', + ), + ), + ); } ); diff --git a/repo/resources/wikibase.ui.entityViewInit.js b/repo/resources/wikibase.ui.entityViewInit.js index 44a5691..e50b450 100644 --- a/repo/resources/wikibase.ui.entityViewInit.js +++ b/repo/resources/wikibase.ui.entityViewInit.js @@ -333,11 +333,22 @@ } ); } + function displayPerformanceNotifcation() { + if( mw.config.get( 'debug' ) == false ){ + return; + } + + mw.loader.using( ['wikibase.performance.Statistic'] ).done( function() { + var stat = new wikibase.performance.Statistic( wikibase.performance.Mark.getAllMarks() ); + mw.notify( stat.getHtml() , { autoHide: false, type: 'warn' } ); + } ); + } + mw.hook( 'wikipage.content' ).add( function() { if ( mw.config.get( 'wbEntity' ) === null ) { return; } - wikibase.performance.Mark( 'wbInitStart' ); + wikibase.performance.Mark.addStart( 'wbInit' ); var $entityview = $( '.wikibase-entityview' ); var entityInitializer = new wb.EntityInitializer( 'wbEntity' ); @@ -356,7 +367,7 @@ attachWatchLinkUpdater( $entityview, viewName ); } - wikibase.performance.Mark( 'wbInitEnd' ); + wikibase.performance.Mark.addEnd( 'wbInit' ); } ); if ( canEdit ) { @@ -383,9 +394,9 @@ } ); attachCopyrightTooltip( $entityview ); + displayPerformanceNotifcation() } } ); - } )( jQuery, mediaWiki, diff --git a/view/resources/jquery/wikibase/jquery.wikibase.entityview.js b/view/resources/jquery/wikibase/jquery.wikibase.entityview.js index 7f527d8..3121a3c 100644 --- a/view/resources/jquery/wikibase/jquery.wikibase.entityview.js +++ b/view/resources/jquery/wikibase/jquery.wikibase.entityview.js @@ -102,6 +102,8 @@ * @protected */ _initEntityTerms: function() { + wb.performance.Mark.addStart( 'EntityTerms' ); + var $entityTerms = $( '.wikibase-entitytermsview', this.element ); if ( !$entityTerms.length ) { @@ -112,6 +114,8 @@ this.options.value.getFingerprint(), $entityTerms ); + + wb.performance.Mark.addEnd( 'EntityTerms' ); }, /** diff --git a/view/resources/jquery/wikibase/jquery.wikibase.itemview.js b/view/resources/jquery/wikibase/jquery.wikibase.itemview.js index e937813..9f6559f 100644 --- a/view/resources/jquery/wikibase/jquery.wikibase.itemview.js +++ b/view/resources/jquery/wikibase/jquery.wikibase.itemview.js @@ -73,6 +73,8 @@ * @protected */ _initStatements: function() { + wb.performance.Mark.addStart( 'Statements' ); + this.options.buildStatementGroupListView( this.options.value, this.$statements ); // This is here to be sure there is never a duplicate id: @@ -80,13 +82,19 @@ .prev( '.wb-section-heading' ) .first() .attr( 'id', 'claims' ); + + wb.performance.Mark.addEnd( 'Statements' ); }, /** * @protected */ _initSiteLinks: function() { + wb.performance.Mark.addStart( 'SiteLinks' ); + this.options.buildSitelinkGroupListView( this.options.value.getSiteLinks(), this.$siteLinks ); + + wb.performance.Mark.addEnd( 'SiteLinks' ); }, /** diff --git a/view/resources/jquery/wikibase/jquery.wikibase.statementview.js b/view/resources/jquery/wikibase/jquery.wikibase.statementview.js index c5cef41..d55a16a 100644 --- a/view/resources/jquery/wikibase/jquery.wikibase.statementview.js +++ b/view/resources/jquery/wikibase/jquery.wikibase.statementview.js @@ -167,6 +167,8 @@ * @param {number} rank */ _createRankSelector: function( rank ) { + wb.performance.Mark.addStart( '-RankSelector' ); + if ( this._rankSelector ) { return; } @@ -187,6 +189,8 @@ self._trigger( 'change' ); } } ); + + wb.performance.Mark.addEnd( '-RankSelector' ); }, /** @@ -195,6 +199,8 @@ * @param {wikibase.datamodel.Snak|null} [snak=null] */ _createMainSnak: function( snak ) { + wb.performance.Mark.addStart( '-MainSnak' ); + if ( this.$mainSnak.data( 'snakview' ) ) { this._mainSnakSnakView = this.$mainSnak.data( 'snakview' ); return; @@ -219,6 +225,7 @@ snak, this.$mainSnak ); + wb.performance.Mark.addEnd( '-MainSnak' ); }, /** @@ -227,6 +234,8 @@ * @param {wikibase.datamodel.SnakList|null} [qualifiers=null] */ _createQualifiersListview: function( qualifiers ) { + wb.performance.Mark.addStart( '-Qualifiers' ); + if ( this._qualifiers ) { return; } @@ -276,6 +285,8 @@ } ); this._qualifiers = $qualifiers.data( 'listview' ); + + wb.performance.Mark.addEnd( '-Qualifiers' ); }, /** @@ -284,6 +295,8 @@ * @param {wikibase.datamodel.Reference[]} [references] */ _createReferencesListview: function( references ) { + wb.performance.Mark.addStart( '-References' ); + var self = this; var $listview = this.$references.children(); @@ -360,6 +373,8 @@ this.$refsHeading.html( this._$toggler ); this._drawReferencesCounter(); } + + wb.performance.Mark.addEnd( '-References' ); }, /** -- To view, visit https://gerrit.wikimedia.org/r/269299 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1f626f05ba98d81c14eaf974eb546b30512e46f2 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Jonas Kress (WMDE) <jonas.kr...@wikimedia.de> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits