ソースを参照

AMBARI-12760 FE: Add experimental flag to show "page loaded in X seconds" on important pages. (atkach)

Andrii Tkach 10 年 前
コミット
fd7bcd4e5c

+ 1 - 0
ambari-web/app/assets/test/tests.js

@@ -167,6 +167,7 @@ var files = ['test/init_model_test',
   'test/utils/configs/config_property_helper_test',
   'test/utils/configs/modification_handlers/modification_handler_test',
   'test/utils/configs/modification_handlers/misc_test',
+  'test/utils/load_timer_test',
   'test/views/common/chart/linear_time_test',
   'test/views/common/configs/widgets/combo_config_widget_view_test',
   'test/views/common/configs/widgets/config_widget_view_test',

+ 2 - 1
ambari-web/app/config.js

@@ -72,7 +72,8 @@ App.supports = {
   installGanglia: false,
   opsDuringRollingUpgrade: false,
   customizedWidgetLayout: false,
-  enhancedConfigs: true
+  enhancedConfigs: true,
+  showPageLoadTime: false
 };
 
 if (App.enableExperimental) {

+ 2 - 0
ambari-web/app/controllers/main/service/info/configs.js

@@ -550,6 +550,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
     this.get('configGroups').forEach(function (configGroup) {
       this.getRecommendationsForDependencies(null, true, Em.K, configGroup);
     }, this);
+    App.loadTimer.finish('Service Configs Page');
   },
 
   /**
@@ -801,6 +802,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
    * @method selectConfigGroup
    */
   doSelectConfigGroup: function (event) {
+    App.loadTimer.start('Service Configs Page');
     var configGroupVersions = App.ServiceConfigVersion.find().filterProperty('groupId', event.context.get('configGroupId'));
     //check whether config group has config versions
     if (event.context.get('configGroupId') == -1) {

+ 1 - 0
ambari-web/app/initialize.js

@@ -37,6 +37,7 @@ require('utils/ajax/ajax');
 require('utils/ajax/ajax_queue');
 require('utils/updater');
 require('utils/action_sequence');
+require('utils/load_timer');
 
 require('mappers');
 

+ 1 - 0
ambari-web/app/mixins/common/table_server_view_mixin.js

@@ -123,6 +123,7 @@ App.TableServerViewMixin = Em.Mixin.create({
     clearTimeout(this.get('timeOut'));
     this.set('filteringComplete', true);
     this.propertyDidChange('pageContent');
+    App.loadTimer.finish('Hosts Page');
   },
 
   /**

+ 7 - 0
ambari-web/app/routes/main.js

@@ -120,6 +120,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
     widgets: Em.Route.extend({
       route: '/metrics',
       connectOutlets: function (router, context) {
+        App.loadTimer.start('Dashboard Metrics Page');
         router.set('mainDashboardController.selectedCategory', 'widgets');
         router.get('mainDashboardController').connectOutlet('mainDashboardWidgets');
       }
@@ -127,6 +128,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
     charts: Em.Route.extend({
       route: '/charts',
       connectOutlets: function (router, context) {
+        App.loadTimer.start('Heatmaps Page');
         router.set('mainDashboardController.selectedCategory', 'charts');
         router.get('mainDashboardController').connectOutlet('mainCharts');
       },
@@ -162,6 +164,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
     configHistory: Em.Route.extend({
       route: '/config_history',
       connectOutlets: function (router, context) {
+        App.loadTimer.start('Config History Page');
         router.set('mainDashboardController.selectedCategory', 'configHistory');
         router.get('mainDashboardController').connectOutlet('mainConfigHistory');
       }
@@ -181,6 +184,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
     index: Ember.Route.extend({
       route: '/',
       connectOutlets: function (router, context) {
+        App.loadTimer.start('Hosts Page');
         router.get('mainController').connectOutlet('mainHost');
       }
     }),
@@ -605,6 +609,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
       summary: Em.Route.extend({
         route: '/summary',
         connectOutlets: function (router, context) {
+          App.loadTimer.start('Service Summary Page');
           var item = router.get('mainServiceItemController.content');
           if (router.get('clusterController.isServiceMetricsLoaded')) router.get('updateController').updateServiceMetric(Em.K);
           //if service is not existed then route to default service
@@ -625,6 +630,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
       configs: Em.Route.extend({
         route: '/configs',
         connectOutlets: function (router, context) {
+          App.loadTimer.start('Service Configs Page');
           router.get('mainController').dataLoading().done(function () {
             var item = router.get('mainServiceItemController.content');
             //if service is not existed then route to default service
@@ -661,6 +667,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
       heatmaps: Em.Route.extend({
         route: '/heatmaps',
         connectOutlets: function (router, context) {
+          App.loadTimer.start('Service Heatmaps Page');
           router.get('mainController').dataLoading().done(function () {
             var item = router.get('mainServiceItemController.content');
             if (item.get('isLoaded')) {

+ 6 - 0
ambari-web/app/styles/application.less

@@ -5862,6 +5862,12 @@ input[type="radio"].align-checkbox, input[type="checkbox"].align-checkbox {
   margin-left: -10px;
 }
 
+.attach-to-bottom-right {
+  position: fixed;
+  bottom: 10px;
+  right: 10px;
+}
+
 .version-labels, .version-info-bar, .version-box {
   .label, .badge {
     font-weight: normal;

+ 1 - 0
ambari-web/app/templates/main/alerts.hbs

@@ -107,6 +107,7 @@
         <td colspan="2">
           <div class="spinner"></div>
         </td>
+        <td colspan="2"></td>
       </tr>
     {{/if}}
     </tbody>

+ 3 - 1
ambari-web/app/templates/main/charts/heatmap.hbs

@@ -46,10 +46,12 @@
           <div class="active-widget" {{bindAttr id="activeWidget.id"}}>
             {{view activeWidget.viewClass contentBinding="activeWidget" racksBinding = "racks" idBinding="activeWidget.id"}}
           </div>
+        {{else}}
+          <div class="spinner"></div>
         {{/if}}
       </div>
     </div>
   {{else}}
     <div class="spinner"></div>
   {{/if}}
-</div>
+</div>

+ 67 - 0
ambari-web/app/utils/load_timer.js

@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+App.loadTimer = Em.Object.create({
+
+  timeStampCache: {},
+
+  /**
+   * save start timestamp
+   * @param {string} label
+   */
+  start: function(label) {
+    $('.alert.attach-to-bottom-right').remove();
+    if (App.get('supports.showPageLoadTime')) {
+      this.get('timeStampCache')[label] = window.performance.now();
+    }
+  },
+
+  /**
+   * calculate time difference
+   * @param {string} label
+   * @returns {undefined|string}
+   */
+  finish: function(label) {
+    var result;
+
+    if (typeof(this.get('timeStampCache')[label]) === "number") {
+      result = Number(window.performance.now() - this.get('timeStampCache')[label]).toFixed(2);
+      console.debug(label + " loaded in: " + result + "ms");
+      this.display(label + " loaded in: " + result + "ms");
+      delete this.get('timeStampCache')[label];
+    }
+    return result;
+  },
+
+  /**
+   * display time results on the screen
+   * @param {string} result
+   */
+  display: function(result) {
+    var alert = $("<div class='alert attach-to-bottom-right'>" +  result + "</div>");
+    var closeButton = $("<i class='icon-remove-circle'></i>").click(function () {
+      $(this).remove();
+      $(alert).remove();
+    });
+    alert.append("&nbsp;", closeButton);
+    $('body').append(alert);
+  }
+});
+

+ 3 - 1
ambari-web/app/views/common/widget/heatmap_widget_view.js

@@ -62,6 +62,8 @@ App.HeatmapWidgetView = Em.View.extend(App.WidgetMixin, {
       });
 
       this.set('controller.selectedMetric', metricObject);
+      App.loadTimer.finish('Heatmaps Page');
+      App.loadTimer.finish('Service Heatmaps Page');
     }
   },
 
@@ -116,4 +118,4 @@ App.HeatmapWidgetView = Em.View.extend(App.WidgetMixin, {
 
     return hostToValueMap;
   }
-});
+});

+ 1 - 0
ambari-web/app/views/main/dashboard/config_history_view.js

@@ -197,6 +197,7 @@ App.MainConfigHistoryView = App.TableView.extend(App.TableServerViewMixin, {
     this.set('filteringComplete', true);
     this.propertyDidChange('pageContent');
     this.set('controller.resetStartIndex', false);
+    App.loadTimer.finish('Config History Page');
   },
 
   /**

+ 1 - 0
ambari-web/app/views/main/dashboard/widgets.js

@@ -30,6 +30,7 @@ App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, {
     this.setInitPrefObject();
     this.setOnLoadVisibleWidgets();
     this.set('isDataLoaded', true);
+    App.loadTimer.finish('Dashboard Metrics Page');
     Em.run.next(this, 'makeSortable');
   },
 

+ 1 - 0
ambari-web/app/views/main/host.js

@@ -81,6 +81,7 @@ App.MainHostView = App.TableView.extend(App.TableServerViewMixin, {
    * called when trigger property(<code>refreshTriggers</code>) is changed
    */
   refresh: function () {
+    App.loadTimer.start('Hosts Page');
     this.set('filteringComplete', false);
     var updaterMethodName = this.get('updater.tableUpdaterMap')[this.get('tableName')];
     this.get('updater')[updaterMethodName](this.updaterSuccessCb.bind(this), this.updaterErrorCb.bind(this), true);

+ 1 - 0
ambari-web/app/views/main/service/info/summary.js

@@ -611,6 +611,7 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, {
         $(this).find('.hidden-description').stop().hide().end();
       });
     }, 1000);
+    App.loadTimer.finish('Service Summary Page');
   },
 
   willDestroyElement: function() {

+ 52 - 0
ambari-web/test/utils/load_timer_test.js

@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var misc = require('utils/load_timer');
+
+describe('App.loadTimer', function () {
+
+  window.performance = {
+    now: function() {
+      return 1;
+    }
+  };
+
+  beforeEach(function() {
+    App.set('supports.showPageLoadTime', true);
+  });
+
+  afterEach(function () {
+    App.set('supports.showPageLoadTime', false);
+    App.loadTimer.set('timeStampCache', {});
+  });
+
+  describe("#start()", function() {
+    it("", function() {
+      App.loadTimer.start('test');
+      expect(App.loadTimer.get('timeStampCache')['test']).to.be.an('number');
+    });
+  });
+
+  describe("#finish()", function() {
+    it("", function() {
+      App.loadTimer.start('test');
+      expect(App.loadTimer.finish('test')).to.be.not.empty;
+      expect(App.loadTimer.get('timeStampCache')).to.be.empty;
+    });
+  });
+});

+ 1 - 0
ambari-web/test/views/main/dashboard/config_history_view_test.js

@@ -18,6 +18,7 @@
 
 var App = require('app');
 require('views/main/dashboard/config_history_view');
+require('utils/load_timer');
 
 describe('App.MainConfigHistoryView', function() {
   var view = App.MainConfigHistoryView.create({