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

Reply via email to