Bug 1441614 - Use imports for templates instead of cache-template.js (#3286)

Previously all templates were being included on every page, regardless
of whether they were being used, bloating the bundles. In addition,
`templateUrl` has a number of issues compared to `template`:
https://medium.com/@frosty/angularjs-template-vs-templateurl-cdde055b7907

There are now no more instances of non-global `require()`s (or any
require()s for that matter), so we can enable that eslint rule:
https://eslint.org/docs/rules/global-require

Improves the bundle sizes as follows:
* index: -60KB
* logviewer: -138KB
* perf: -84KB
This commit is contained in:
Ed Morley 2018-03-01 17:05:35 +00:00 коммит произвёл GitHub
Родитель 893baca118
Коммит 038e60a833
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
18 изменённых файлов: 121 добавлений и 76 удалений

Просмотреть файл

@ -29,7 +29,6 @@ module.exports = neutrino => {
'consistent-return': 'off',
'default-case': 'off',
'func-names': 'off',
'global-require': 'off',
// Indentation is disabled pending a switch from 4 to 2 space for JS.
'indent': 'off',
'jsx-a11y/label-has-for': 'off',

Просмотреть файл

@ -1,29 +0,0 @@
// This is a run block which, when used on an angular module, loads all
// of the partials in /ui/partials and /ui/plugins into the Angular
// template cache. This means that ng-includes and templateUrls will not
// actually need to request a partial file at any point. See:
// https://github.com/dmachat/angular-webpack-cookbook/wiki/Angular-Template-Cache
// TODO: See if there's a way to avoid adding all partials to every page, that
// importantly also works for ng-includes. Perhaps one of these would work:
// - https://github.com/teux/ng-cache-loader
// - https://github.com/WearyMonkey/ngtemplate-loader
// - https://github.com/EJIqpEP/angular-templatecache-loader
module.exports = ['$templateCache', ($templateCache) => {
const partialsReq = require.context('../partials', true, /\.html$/);
partialsReq.keys().forEach((template) => {
const keyPath = `partials${template.substring(1)}`;
$templateCache.put(
keyPath,
partialsReq(template)
);
});
const pluginsReq = require.context('../plugins', true, /\.html$/);
pluginsReq.keys().forEach((template) => {
const keyPath = `plugins${template.substring(1)}`;
$templateCache.put(
keyPath,
pluginsReq(template)
);
});
}];

Просмотреть файл

@ -1,7 +1,8 @@
import treeherder from '../../treeherder';
import logviewerTemplate from '../../../partials/logviewer/logviewer.html';
treeherder.component('thLogViewer', {
templateUrl: 'partials/logviewer/logviewer.html',
template: logviewerTemplate,
controller: ['$sce', '$location', '$element', '$scope', '$rootScope',
($sce, $location, $element, $scope, $rootScope) => {
const unifiedLogviewerUrl = 'https://taskcluster.github.io/unified-logviewer/';

Просмотреть файл

@ -1,11 +1,16 @@
import treeherder from '../../treeherder';
import trendTableTemplate from '../../../partials/perf/trendtable.html';
import compareTableTemplate from '../../../partials/perf/comparetable.html';
import averageTemplate from '../../../partials/perf/average.html';
import revisionDescribeTemplate from '../../../partials/perf/revisiondescribe.html';
import compareErrorTemplate from '../../../partials/perf/comparerror.html';
treeherder.component('phCompareTable', {
templateUrl: ['$attrs', function ($attrs) {
template: ['$attrs', function ($attrs) {
if ($attrs.type === 'trend') {
return 'partials/perf/trendtable.html';
return trendTableTemplate;
}
return 'partials/perf/comparetable.html';
return compareTableTemplate;
}],
bindings: {
baseTitle: '@',
@ -81,7 +86,7 @@ treeherder.component('phCompareTable', {
});
treeherder.component('phAverage', {
templateUrl: 'partials/perf/average.html',
template: averageTemplate,
bindings: {
value: '@',
stddev: '@',
@ -91,7 +96,7 @@ treeherder.component('phAverage', {
});
treeherder.component('revisionInformation', {
templateUrl: 'partials/perf/revisiondescribe.html',
template: revisionDescribeTemplate,
bindings: {
originalProject: '<',
originalRevision: '<',
@ -104,7 +109,7 @@ treeherder.component('revisionInformation', {
});
treeherder.component('compareError', {
templateUrl: 'partials/perf/comparerror.html',
template: compareErrorTemplate,
bindings: {
errors: '<',
originalProject: '<',

Просмотреть файл

@ -1,4 +1,5 @@
import perf from '../../perf';
import modifyAlertsCtrlTemplate from '../../../partials/perf/modifyalertsctrl.html';
perf.factory('PhBugs', [
'$http', '$httpParamSerializer', '$interpolate', '$rootScope', 'dateFilter', 'thServiceDomain',
@ -293,7 +294,7 @@ perf.controller('AlertsCtrl', [
};
$scope.linkToBug = function (alertSummary) {
$uibModal.open({
templateUrl: 'partials/perf/modifyalertsctrl.html',
template: modifyAlertsCtrlTemplate,
controller: 'ModifyAlertSummaryCtrl',
size: 'sm',
resolve: {
@ -312,7 +313,7 @@ perf.controller('AlertsCtrl', [
};
$scope.markAlertsDownstream = function (alertSummary) {
$uibModal.open({
templateUrl: 'partials/perf/modifyalertsctrl.html',
template: modifyAlertsCtrlTemplate,
controller: 'MarkDownstreamAlertsCtrl',
size: 'sm',
resolve: {
@ -329,7 +330,7 @@ perf.controller('AlertsCtrl', [
};
$scope.reassignAlerts = function (alertSummary) {
$uibModal.open({
templateUrl: 'partials/perf/modifyalertsctrl.html',
template: modifyAlertsCtrlTemplate,
controller: 'ReassignAlertsCtrl',
size: 'sm',
resolve: {

Просмотреть файл

@ -2,6 +2,7 @@ import angular from 'angular';
import Mousetrap from 'mousetrap';
import perf from '../../perf';
import testDataChooserTemplate from '../../../partials/perf/testdatachooser.html';
perf.controller('GraphsCtrl', [
'$state', '$stateParams', '$scope', '$rootScope', '$uibModal',
@ -817,7 +818,7 @@ perf.controller('GraphsCtrl', [
}
var modalInstance = $uibModal.open({
templateUrl: 'partials/perf/testdatachooser.html',
template: testDataChooserTemplate,
controller: 'TestChooserCtrl',
size: 'lg',
resolve: {

Просмотреть файл

@ -1,4 +1,6 @@
import treeherder from '../../treeherder';
import thPinnedJobTemplate from '../../../partials/main/thPinnedJob.html';
import thRelatedBugQueuedTemplate from '../../../partials/main/thRelatedBugQueued.html';
import { getBtnClass, getStatus } from "../../../helpers/jobHelper";
treeherder.directive('thPinnedJob', function () {
@ -24,7 +26,7 @@ treeherder.directive('thPinnedJob', function () {
}, true);
},
templateUrl: 'partials/main/thPinnedJob.html'
template: thPinnedJobTemplate
};
});
@ -32,6 +34,6 @@ treeherder.directive('thRelatedBugQueued', function () {
return {
restrict: "E",
templateUrl: 'partials/main/thRelatedBugQueued.html'
template: thRelatedBugQueuedTemplate
};
});

Просмотреть файл

@ -1,4 +1,5 @@
import treeherder from '../../treeherder';
import lvLogStepsTemplate from '../../../partials/logviewer/lvLogSteps.html';
treeherder.directive('lvLogSteps', ['$timeout', ($timeout) => {
function getOffsetOfStep(order) {
@ -14,7 +15,7 @@ treeherder.directive('lvLogSteps', ['$timeout', ($timeout) => {
return {
restrict: 'A',
templateUrl: 'partials/logviewer/lvLogSteps.html',
template: lvLogStepsTemplate,
link: (scope) => {
scope.toggleSuccessfulSteps = () => {
scope.showSuccessful = !scope.showSuccessful;

Просмотреть файл

@ -1,4 +1,5 @@
import treeherder from '../../treeherder';
import thNotificationsBoxTemplate from '../../../partials/main/thNotificationsBox.html';
//Directive blurThis which removes focus from a specific element
treeherder.directive('blurThis', ['$timeout', function ($timeout) {
@ -98,7 +99,7 @@ treeherder.directive('thNotificationBox', [
function (thNotify) {
return {
restrict: "E",
templateUrl: "partials/main/thNotificationsBox.html",
template: thNotificationsBoxTemplate,
link: function (scope) {
scope.notifier = thNotify;
scope.alert_class_prefix = "alert-";

Просмотреть файл

@ -1,4 +1,8 @@
import treeherder from '../../treeherder';
import thWatchedRepoTemplate from '../../../partials/main/thWatchedRepo.html';
import thWatchedRepoInfoDropDownTemplate from '../../../partials/main/thWatchedRepoInfoDropDown.html';
import thRepoMenuItemTemplate from '../../../partials/main/thRepoMenuItem.html';
import thResultStatusChickletTemplate from '../../../partials/main/thResultStatusChicklet.html';
import { getBtnClass } from '../../../helpers/jobHelper';
treeherder.directive('thWatchedRepo', [
@ -72,7 +76,7 @@ treeherder.directive('thWatchedRepo', [
}
});
},
templateUrl: 'partials/main/thWatchedRepo.html'
template: thWatchedRepoTemplate
};
}]);
@ -95,7 +99,7 @@ treeherder.directive('thWatchedRepoInfoDropDown', [
}
}, true);
},
templateUrl: 'partials/main/thWatchedRepoInfoDropDown.html'
template: thWatchedRepoInfoDropDownTemplate
};
}]);
@ -142,7 +146,7 @@ treeherder.directive('thRepoMenuItem',
}
},
templateUrl: 'partials/main/thRepoMenuItem.html'
template: thRepoMenuItemTemplate
};
});
@ -152,6 +156,6 @@ treeherder.directive('thResultStatusChicklet', function () {
link: function (scope) {
scope.chickletClass = `${getBtnClass(scope.filterName)}-filter-chicklet`;
},
templateUrl: 'partials/main/thResultStatusChicklet.html'
template: thResultStatusChickletTemplate
};
});

Просмотреть файл

@ -18,6 +18,6 @@ logViewerApp.config(['$compileProvider', '$locationProvider', '$resourceProvider
// All queries should be cancellable by default (why is this configurable??)
$resourceProvider.defaults.cancellable = true;
}]).run(require('./cache-templates'));
}]);
export default logViewerApp;

Просмотреть файл

@ -1,4 +1,14 @@
import perf from './perf';
import alertsCtrlTemplate from '../partials/perf/alertsctrl.html';
import graphsCtrlTemplate from '../partials/perf/graphsctrl.html';
import compareCtrlTemplate from '../partials/perf/comparectrl.html';
import compareSubtestCtrlTemplate from '../partials/perf/comparesubtestctrl.html';
import compareChooserCtrlTemplate from '../partials/perf/comparechooserctrl.html';
import dashboardTemplate from '../partials/perf/dashboard.html';
import dashboardSubtestTemplate from '../partials/perf/dashboardsubtest.html';
import compareSubtestDistributionTemplate from '../partials/perf/comparesubtestdistribution.html';
import helpMenuTemplate from '../partials/perf/helpMenu.html';
import tooltipGraphsTemplate from '../partials/perf/tooltipgraphs.html';
// configure the router here, after we have defined all the controllers etc
perf.config(['$compileProvider', '$locationProvider', '$httpProvider', '$stateProvider', '$urlRouterProvider',
@ -23,49 +33,49 @@ perf.config(['$compileProvider', '$locationProvider', '$httpProvider', '$statePr
$stateProvider
.state('alerts', {
title: 'Alerts',
templateUrl: 'partials/perf/alertsctrl.html',
template: alertsCtrlTemplate,
url: '/alerts?id&status&framework&filter&hideImprovements&hideDwnToInv&page',
controller: 'AlertsCtrl'
})
.state('graphs', {
title: 'Graphs',
templateUrl: 'partials/perf/graphsctrl.html',
template: graphsCtrlTemplate,
url: '/graphs?timerange&series&highlightedRevisions&highlightAlerts&zoom&selected',
controller: 'GraphsCtrl'
})
.state('compare', {
title: 'Compare',
templateUrl: 'partials/perf/comparectrl.html',
template: compareCtrlTemplate,
url: '/compare?originalProject&originalRevision?&newProject&newRevision&hideMinorChanges&framework&filter&showOnlyImportant&showOnlyConfident&selectedTimeRange&showOnlyNoise?',
controller: 'CompareResultsCtrl'
})
.state('comparesubtest', {
title: 'Compare - Subtests',
templateUrl: 'partials/perf/comparesubtestctrl.html',
template: compareSubtestCtrlTemplate,
url: '/comparesubtest?originalProject&originalRevision?&newProject&newRevision&originalSignature&newSignature&filter&showOnlyImportant&showOnlyConfident&framework&selectedTimeRange&showOnlyNoise?',
controller: 'CompareSubtestResultsCtrl'
})
.state('comparechooser', {
title: 'Compare Chooser',
templateUrl: 'partials/perf/comparechooserctrl.html',
template: compareChooserCtrlTemplate,
url: '/comparechooser?originalProject&originalRevision&newProject&newRevision',
controller: 'CompareChooserCtrl'
})
.state('dashboard', {
title: 'Perfherder Dashboard',
templateUrl: 'partials/perf/dashboard.html',
template: dashboardTemplate,
url: '/dashboard?topic&filter&showOnlyImportant&showOnlyConfident&showOnlyBlockers&repo&timerange&revision',
controller: 'dashCtrl'
})
.state('dashboardsubtest', {
title: 'Perfherder Dashboard - Subtests',
templateUrl: 'partials/perf/dashboardsubtest.html',
template: dashboardSubtestTemplate,
url: '/dashboardsubtest?topic&filter&showOnlyImportant&showOnlyConfident&baseSignature&variantSignature&repo&timerange&revision',
controller: 'dashSubtestCtrl'
})
.state('comparesubtestdistribution', {
title: 'Compare Subtest Distribution',
templateUrl: 'partials/perf/comparesubtestdistribution.html',
template: compareSubtestDistributionTemplate,
url: '/comparesubtestdistribution?originalProject&newProject&originalRevision&newRevision&originalSubtestSignature?newSubtestSignature',
controller: 'CompareSubtestDistributionCtrl'
});
@ -79,4 +89,9 @@ perf.config(['$compileProvider', '$locationProvider', '$httpProvider', '$statePr
window.document.title = $state.current.title;
}
});
}]).run(require('./cache-templates'));
}]).run(['$templateCache', ($templateCache) => {
// Templates used by ng-include have to be manually put in the template cache.
// Those used by directives should instead be imported at point of use.
$templateCache.put('partials/perf/helpMenu.html', helpMenuTemplate);
$templateCache.put('partials/perf/tooltipgraphs.html', tooltipGraphsTemplate);
}]);

Просмотреть файл

@ -2,6 +2,7 @@ import { Queue } from 'taskcluster-client-web';
import treeherder from '../treeherder';
import thTaskcluster from './taskcluster';
import tcJobActionsTemplate from '../../partials/main/tcjobactions.html';
/* Services */
treeherder.factory('thUrl', [
@ -175,7 +176,7 @@ treeherder.factory('customPushActions', [
return {
open(repoName, pushId) {
$uibModal.open({
templateUrl: 'partials/main/tcjobactions.html',
template: tcJobActionsTemplate,
controller: 'TCJobActionsCtrl',
size: 'lg',
resolve: {

Просмотреть файл

@ -7,6 +7,22 @@ import uiBootstrap from 'angular1-ui-bootstrap4';
import mcResizer from '../vendor/resizer';
import treeherderModule from './treeherder';
import AnnotationsTemplate from '../plugins/annotations/main.html';
import AutoClassificationTemplate from '../plugins/auto_classification/main.html';
import FailureSummaryTemplate from '../plugins/failure_summary/main.html';
import JobDetailsTemplate from '../plugins/job_details/main.html';
import PerfDetailsTemplate from '../plugins/perf_details/main.html';
import pluginPanelTemplate from '../plugins/pluginpanel.html';
import SimilarJobsTemplate from '../plugins/similar_jobs/main.html';
import thActiveFiltersBarTemplate from '../partials/main/thActiveFiltersBar.html';
import thFilterChickletsTemplate from '../partials/main/thFilterChicklets.html';
import thGlobalTopNavPanelTemplate from '../partials/main/thGlobalTopNavPanel.html';
import thHelpMenuTemplate from '../partials/main/thHelpMenu.html';
import thInfraMenuTemplate from '../partials/main/thInfraMenu.html';
import thPinboardPanelTemplate from '../partials/main/thPinboardPanel.html';
import thShortcutTableTemplate from '../partials/main/thShortcutTable.html';
import thTreeherderUpdateBarTemplate from '../partials/main/thTreeherderUpdateBar.html';
import thWatchedRepoNavPanelTemplate from '../partials/main/thWatchedRepoNavPanel.html';
const treeherderApp = angular.module('treeherder.app', [
treeherderModule.name,
@ -55,6 +71,25 @@ treeherderApp.config(['$compileProvider', '$locationProvider', '$routeProvider',
reloadOnSearch: false
})
.otherwise({ redirectTo: '/jobs' });
}]).run(require('./cache-templates'));
}]).run(['$templateCache', ($templateCache) => {
// Templates used by ng-include have to be manually put in the template cache.
// Those used by directives should instead be imported at point of use.
$templateCache.put('partials/main/thActiveFiltersBar.html', thActiveFiltersBarTemplate);
$templateCache.put('partials/main/thFilterChicklets.html', thFilterChickletsTemplate);
$templateCache.put('partials/main/thGlobalTopNavPanel.html', thGlobalTopNavPanelTemplate);
$templateCache.put('partials/main/thHelpMenu.html', thHelpMenuTemplate);
$templateCache.put('partials/main/thInfraMenu.html', thInfraMenuTemplate);
$templateCache.put('partials/main/thPinboardPanel.html', thPinboardPanelTemplate);
$templateCache.put('partials/main/thShortcutTable.html', thShortcutTableTemplate);
$templateCache.put('partials/main/thTreeherderUpdateBar.html', thTreeherderUpdateBarTemplate);
$templateCache.put('partials/main/thWatchedRepoNavPanel.html', thWatchedRepoNavPanelTemplate);
$templateCache.put('plugins/annotations/main.html', AnnotationsTemplate);
$templateCache.put('plugins/auto_classification/main.html', AutoClassificationTemplate);
$templateCache.put('plugins/failure_summary/main.html', FailureSummaryTemplate);
$templateCache.put('plugins/job_details/main.html', JobDetailsTemplate);
$templateCache.put('plugins/perf_details/main.html', PerfDetailsTemplate);
$templateCache.put('plugins/pluginpanel.html', pluginPanelTemplate);
$templateCache.put('plugins/similar_jobs/main.html', SimilarJobsTemplate);
}]);
export default treeherderApp;

Просмотреть файл

@ -1,17 +1,16 @@
import angular from 'angular';
import thShortcutTableTemplate from '../partials/main/thShortcutTable.html';
const userguideApp = angular.module('userguide', []);
userguideApp.config(['$compileProvider', function ($compileProvider) {
// Disable debug data, as recommended by https://docs.angularjs.org/guide/production
$compileProvider.debugInfoEnabled(false);
}]).run(['$templateCache', ($templateCache) => {
// The user guide only requires a single partial - just include it instead
// of requiring the full set of templates
$templateCache.put(
'partials/main/thShortcutTable.html',
require('../partials/main/thShortcutTable.html')
);
// Templates used by ng-include have to be manually put in the template cache.
// Those used by directives should instead be imported at point of use.
$templateCache.put('partials/main/thShortcutTable.html', thShortcutTableTemplate);
}]);
export default userguideApp;

Просмотреть файл

@ -1,4 +1,11 @@
import treeherder from '../../js/treeherder';
import staticOptionTemplate from '../../plugins/auto_classification/staticOption.html';
import intermittentTemplate from '../../partials/main/intermittent.html';
import optionTemplate from '../../plugins/auto_classification/option.html';
import errorLineTemplate from '../../plugins/auto_classification/errorLine.html';
import errorsTemplate from '../../plugins/auto_classification/errors.html';
import toolbarTemplate from '../../plugins/auto_classification/toolbar.html';
import panelTemplate from '../../plugins/auto_classification/panel.html';
treeherder.factory('thStringOverlap', function () {
return function (str1, str2) {
@ -108,7 +115,7 @@ treeherder.controller('ThStaticClassificationOptionController', [
]);
treeherder.component('thStaticClassificationOption', {
templateUrl: 'plugins/auto_classification/staticOption.html',
template: staticOptionTemplate,
controller: 'ThStaticClassificationOptionController',
bindings: {
thJob: '<',
@ -160,7 +167,7 @@ treeherder.controller('ThClassificationOptionController', [
}
var modalInstance = $uibModal.open({
templateUrl: 'partials/main/intermittent.html',
template: intermittentTemplate,
controller: 'BugFilerCtrl',
size: 'lg',
openedClass: "filer-open",
@ -188,7 +195,7 @@ treeherder.controller('ThClassificationOptionController', [
]);
treeherder.component('thClassificationOption', {
templateUrl: 'plugins/auto_classification/option.html',
template: optionTemplate,
controller: 'ThClassificationOptionController',
bindings: {
thJob: '<',
@ -688,7 +695,7 @@ treeherder.controller('ThErrorLineController', [
]);
treeherder.component('thErrorLine', {
templateUrl: 'plugins/auto_classification/errorLine.html',
template: errorLineTemplate,
controller: 'ThErrorLineController',
bindings: {
thJob: '<',
@ -740,7 +747,7 @@ treeherder.controller('ThAutoclassifyErrorsController', ['$scope', '$element',
]);
treeherder.component('thAutoclassifyErrors', {
templateUrl: 'plugins/auto_classification/errors.html',
template: errorsTemplate,
controller: "ThAutoclassifyErrorsController",
bindings: {
thJob: '<',
@ -780,7 +787,7 @@ treeherder.controller('ThAutoclassifyToolbarController', [
]);
treeherder.component('thAutoclassifyToolbar', {
templateUrl: 'plugins/auto_classification/toolbar.html',
template: toolbarTemplate,
controller: "ThAutoclassifyToolbarController",
bindings: {
loadStatus: '<',
@ -1254,7 +1261,7 @@ treeherder.controller('ThAutoclassifyPanelController', [
]);
treeherder.component('thAutoclassifyPanel', {
templateUrl: 'plugins/auto_classification/panel.html',
template: panelTemplate,
controller: 'ThAutoclassifyPanelController',
bindings: {
thJob: '<',

Просмотреть файл

@ -3,6 +3,7 @@ import { Queue, slugid } from 'taskcluster-client-web';
import treeherder from '../js/treeherder';
import thTaskcluster from '../js/services/taskcluster';
import tcJobActionsTemplate from '../partials/main/tcjobactions.html';
import { getStatus } from '../helpers/jobHelper';
treeherder.controller('PluginCtrl', [
@ -503,7 +504,7 @@ treeherder.controller('PluginCtrl', [
$scope.customJobAction = function () {
$uibModal.open({
templateUrl: 'partials/main/tcjobactions.html',
template: tcJobActionsTemplate,
controller: 'TCJobActionsCtrl',
size: 'lg',
resolve: {

Просмотреть файл

@ -1,6 +1,7 @@
import angular from 'angular';
import treeherder from '../../js/treeherder';
import intermittentTemplate from '../../partials/main/intermittent.html';
treeherder.controller('BugsPluginCtrl', [
'$scope', '$rootScope', 'ThTextLogStepModel',
@ -107,7 +108,7 @@ treeherder.controller('BugsPluginCtrl', [
}
var modalInstance = $uibModal.open({
templateUrl: 'partials/main/intermittent.html',
template: intermittentTemplate,
controller: 'BugFilerCtrl',
size: 'lg',
openedClass: "filer-open",