Я увлечен оптимизацией интерфейса и был в течение многих лет. Моим оригинальным вдохновением был Стив Соудерс и его выступление на веб-сайтах Even Faster на OSCON 2008 . С тех пор я оптимизировал этот блог , сделал его еще быстрее с новым дизайном , удвоил скорость работы нескольких приложений для клиентов и показал, как сделать AppFuse быстрее . В рамках презентации Devoxx 2013 я показал, как оптимизировать скорость страницы в веб-приложении Java .
Я разработал пару приложений AngularJS в прошлом году. Чтобы объединить и минимизировать их таблицы стилей и сценарии, я использовал механизмы, которые уже существовали в проектах. В одном проекте это был Ant и его конкретная задача . С другой стороны, это было частью приложения Grails, поэтому я использовал ресурсы и плагины yui-minify-resources .
Проект Angular, над которым я сейчас работаю, будет опубликован на веб-сервере, а также включен в собственное приложение iOS. Поэтому на этот раз я обратился к Гранту за оптимизацией. Я обнаружил, что это довольно просто, как только я понял, как заставить его работать с Angular . Основываясь на моих выводах, я отправил запрос на добавление Grunt в angular-seed .
Ниже приведены шаги, которые я использовал, чтобы добавить Grunt в свой проект Angular.
- Установите интерфейс командной строки Grunt с помощью команды «sudo npm install -g grunt-cli».
- Отредактируйте файл package.json, указав номер версии (например, «версия»: «1.0.0»).
- Добавьте плагины Grunt в package.json для создания версий concat / minify / asset:
"grunt": "~0.4.1", "grunt-contrib-concat": "~0.3.0", "grunt-contrib-uglify": "~0.2.7", "grunt-contrib-cssmin": "~0.7.0", "grunt-usemin": "~2.0.2", "grunt-contrib-copy": "~0.5.0", "grunt-rev": "~0.1.0", "grunt-contrib-clean": "~0.5.0"
- Создайте,
Gruntfile.js
который запускает все плагины.module.exports = function (grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), clean: ["dist", '.tmp'], copy: { main: { expand: true, cwd: 'app/', src: ['**', '!js/**', '!lib/**', '!**/*.css'], dest: 'dist/' }, shims: { expand: true, cwd: 'app/lib/webshim/shims', src: ['**'], dest: 'dist/js/shims' } }, rev: { files: { src: ['dist/**/*.{js,css}', '!dist/js/shims/**'] } }, useminPrepare: { html: 'app/index.html' }, usemin: { html: ['dist/index.html'] }, uglify: { options: { report: 'min', mangle: false } } }); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-rev'); grunt.loadNpmTasks('grunt-usemin'); // Tell Grunt what to do when we type "grunt" into the terminal grunt.registerTask('default', [ 'copy', 'useminPrepare', 'concat', 'uglify', 'cssmin', 'rev', 'usemin' ]); };
- Добавьте комментарии в app / index.html, чтобы usemin знал, какие файлы обрабатывать. Комментарии являются важной частью, ваши файлы, вероятно, будут отличаться.
<!-- build:css css/app-name.min.css --> <link rel="stylesheet" href="lib/bootstrap/bootstrap.min.css"/> <link rel="stylesheet" href="lib/font-awesome/font-awesome.min.css"/> <link rel="stylesheet" href="lib/toaster/toaster.css"/> <link rel="stylesheet" href="css/app.css"/> <link rel="stylesheet" href="css/custom.css"/> <link rel="stylesheet" href="css/responsive.css"/> <!-- endbuild --> ... <!-- build:js js/app-name.min.js --> <script src="lib/jquery/jquery-1.10.2.min.js"></script> <script src="lib/bootstrap/bootstrap.min.js"></script> <script src="lib/angular/angular.min.js"></script> <script src="lib/angular/angular-animate.min.js"></script> <script src="lib/angular/angular-cookies.min.js"></script> <script src="lib/angular/angular-resource.min.js"></script> <script src="lib/angular/angular-route.min.js"></script> <script src="lib/fastclick.min.js"></script> <script src="lib/toaster/toaster.js"></script> <script src="lib/webshim/modernizr.min.js"></script> <script src="lib/webshim/polyfiller.min.js"></script> <script src="js/app.js"></script> <script src="js/services.js"></script> <script src="js/controllers.js"></script> <script src="js/filters.js"></script> <script src="js/directives.js"></script> <!-- endbuild -->
Несколько вещей, на которые следует обратить внимание: 1) задача копирования копирует каталог » shims » из библиотеки Webshims, потому что он загружает файлы динамически, и 2) установка «mangle: false» в задаче uglify необходима для внедрения внедрения Angular в зависимости. Я попытался использовать grunt-ngmin с uglify и не повезло.
После внесения этих изменений я могу запустить «grunt» и получить оптимизированную версию моего приложения в папке «dist» моего проекта. Что касается разработки, я продолжаю запускать приложение из папки «app», поэтому в настоящее время у меня нет необходимости наблюдать и обрабатывать ресурсы на лету. Это может измениться, если я начну использовать LESS или CoffeeScript.
Результаты говорят сами за себя: от 27 запросов до 5 при начальной загрузке и только 3 запроса менее чем за 2К после этого.
YSlow | Скорость страницы | |
---|---|---|
Без оптимизации | 75
27 HTTP-запросов / 464K |
55/100 |
Оптимизация Apache (заголовки gzip и expires) | 89
начальная загрузка: 26 запросов / 166 КБ, |
88/100 |
Apache + concat / minified / versioned файлы | 98
начальная загрузка: 5 запросов / 136 |
93/100 |