AngularJS
Подготовьтесь к производству - Grunt
Поиск…
Просмотр предварительной загрузки
Когда запрашивается первый запрос времени, обычно Angular делает запрос XHR
для получения этого представления. Для проектов среднего размера количество просмотров может быть значительным, и это может замедлить отзывчивость приложения.
Хорошей практикой является предварительная загрузка всех представлений сразу для небольших и средних проектов. Для более крупных проектов хорошо их агрегировать и в некоторых значимых объемах, но некоторые другие методы могут быть полезны для разделения нагрузки. Для автоматизации этой задачи удобно использовать задачи Grunt или Gulp.
Чтобы предварительно загрузить представления, мы можем использовать объект $templateCache
. Это объект, в котором углы хранят каждое полученное представление с сервера.
Можно использовать модуль html2js
, который преобразует все наши представления в один модуль - файл js. Тогда нам нужно будет вставить этот модуль в наше приложение, и все.
Чтобы создать конкатенированный файл всех представлений, мы можем использовать эту задачу
module.exports = function (grunt) {
//set up the location of your views here
var viewLocation = ['app/views/**.html'];
grunt.initConfig({
pkg: require('./package.json'),
//section that sets up the settings for concatenation of the html files into one file
html2js: {
options: {
base: '',
module: 'app.templates', //new module name
singleModule: true,
useStrict: true,
htmlmin: {
collapseBooleanAttributes: true,
collapseWhitespace: true
}
},
main: {
src: viewLocation,
dest: 'build/app.templates.js'
}
},
//this section is watching for changes in view files, and if there was a change, it will regenerate the production file. This task can be handy during development.
watch: {
views:{
files: viewLocation,
tasks: ['buildHTML']
},
}
});
//to automatically generate one view file
grunt.loadNpmTasks('grunt-html2js');
//to watch for changes and if the file has been changed, regenerate the file
grunt.loadNpmTasks('grunt-contrib-watch');
//just a task with friendly name to reference in watch
grunt.registerTask('buildHTML', ['html2js']);
};
Чтобы использовать этот способ конкатенации, вам нужно сделать 2 изменения: в вашем файле index.html
вам необходимо ссылаться на файл конкатенированного представления
<script src="build/app.templates.js"></script>
В файле, где вы объявляете свое приложение, вам нужно ввести зависимость
angular.module('app', ['app.templates'])
Если вы используете популярные роутеры, такие как ui-router
, никаких изменений в способе, как вы ссылаетесь на шаблоны
.state('home', {
url: '/home',
views: {
"@": {
controller: 'homeController',
//this will be picked up from $templateCache
templateUrl: 'app/views/home.html'
},
}
})
Оптимизация скриптов
Хорошая практика - объединить файлы JS и их минимизировать. Для более крупного проекта могут быть сотни JS-файлов, и он добавляет лишнюю задержку для загрузки каждого файла отдельно от сервера.
Для угловой минимизации требуется, чтобы все функции были аннотированы. Это необходимо для правильной минимальной инъекции угловой зависимости. (Во время минификсации имена функций и переменные будут переименованы, и он будет разорвать инъекцию зависимостей, если никаких дополнительных действий не будет предпринято.)
Во время minificaiton $scope
и myService
переменные будут заменены некоторыми другими значениями. Угловые инъекции зависимостей основаны на имени, в результате эти имена не должны меняться
.controller('myController', function($scope, myService){
})
Угловой будет понимать обозначение массива, потому что минификация не заменит строковые литералы.
.controller('myController', ['$scope','myService', function($scope, myService){
}])
- Во-первых, мы будем конкатенировать все файлы до конца.
- Во-вторых, мы будем использовать модуль
ng-annotate
, который подготовит код для минимизации - Наконец, мы применим модуль
uglify
.
module.exports = function (grunt) {// настраиваем расположение ваших скриптов для повторного использования в скрипте var varLocation = ['app / scripts / *. js'];
grunt.initConfig({
pkg: require('./package.json'),
//add necessary annotations for safe minification
ngAnnotate: {
angular: {
src: ['staging/concatenated.js'],
dest: 'staging/anotated.js'
}
},
//combines all the files into one file
concat: {
js: {
src: scriptLocation,
dest: 'staging/concatenated.js'
}
},
//final uglifying
uglify: {
options: {
report: 'min',
mangle: false,
sourceMap:true
},
my_target: {
files: {
'build/app.min.js': ['staging/anotated.js']
}
}
},
//this section is watching for changes in JS files, and if there was a change, it will regenerate the production file. You can choose not to do it, but I like to keep concatenated version up to date
watch: {
scripts: {
files: scriptLocation,
tasks: ['buildJS']
}
}
});
//module to make files less readable
grunt.loadNpmTasks('grunt-contrib-uglify');
//mdule to concatenate files together
grunt.loadNpmTasks('grunt-contrib-concat');
//module to make angularJS files ready for minification
grunt.loadNpmTasks('grunt-ng-annotate');
//to watch for changes and if the file has been changed, regenerate the file
grunt.loadNpmTasks('grunt-contrib-watch');
//task that sequentially executes all steps to prepare JS file for production
//concatinate all JS files
//annotate JS file (prepare for minification
//uglify file
grunt.registerTask('buildJS', ['concat:js', 'ngAnnotate', 'uglify']);
};