Минификация CSS и Javascript в Website проекте ASP.NET / Хабр
Про минимизацию javascript и css знают все. Ну если кто не знает, то, вкратце, это уменьшение объема файлов за счет удаления комментариев, разметки, переносов строк и прочего. Особенно актуально оно для интернет сайтов, которые при первом же визите пользователя должны порадовать его своей производительностью. Но наш проект, во-первых, работает в локальной сети, а во-вторых, используется на одних и тех же компьютерах изо дня в день, поэтому мы долгое время совсем не задумывались об оптимизации скриптов и стилей. Пока не стали плотно работать с ExtJS.Созданная страничка со всеми подключенными скриптами и стилями весит больше 5 Мб (около 200 файлов). Одно только сгенерированное DOM-дерево в коде HTML содержит более 500 000 байт. Работать с системой пользователь может начать не раньше, чем через 5 секунд после загрузки страницы (инициализация скриптов, ExtJS и т.п.).
Как оказалось, несмотря на наличие локальной сети у заказчика и частую работу с одними и теми же страницами (должно же быть встроенное кэширование в браузере), иногда с загрузкой страниц возникают проблемы. Поэтому было решено уменьшить количество запросов к серверу и поработать над общей производительностью ExtJS в IE8.
Для минификации скриптов сначала скачал Google Closure Compiler, как один из самых популярных, да и корпорация добра плохого не сделает…
Google Closure Compiler
Положил файлик compressor.jar в папку со скриптами. Чтобы его запускать, пришлось поставить java. Сделал bat-файлик запуска с двумя командами, последняя из которых всего лишь делает задержку в 10 секунд, чтобы можно было успеть увидеть возможные ошибки и самому закрыть окно командной строки. Вот таким вот образом слил все скрипты в один файл, вес уменьшился примерно в полтора раза (это содержимое bat-файла):cd %0\..\ java -jar compiler.jar --js=NavigationJS.js --js=SSSC.js (здесь еще куча файликов аналогичным образом) --js_output_file=bcr_master.min.js ping -n 1 -w 100000 192.168.254.254 >nul
Все просто и элегантно, провозился минут пять. Команда cd %0\..\ в начале файла нужна для того, чтобы дальнейшее выполнение команд происходило внутри директории, в которой расположен сам . bat файл, а не с директории по умолчанию после запуска командной строки.
Но тут возникла идея минимизировать не только JS, но и CSS файлы, а Google Closure этого делать, увы, не умеет. Поэтому решил переделать все на YUI Compressor, о котором много отзывов, и он также сжимает CSS.
YUI Compressor
Для объединения всех файлов проекта был написан батник уже значительно большего объема, потому что этот YUI не умеет воспринимать в строке сразу несколько файлов — ему можно скармливать только по одному файлу. А значит, предварительно нам нужно слепить файлы в один временный файл командой copy, а уже потом его сжать юай компрессором.Кстати, важное замечание — все объединяемые файлы javascript должны иметь в конце файла точку с запятой, а лучше с переносом на след.строку. Вообще любые операторы должны заканчиваться точкой с запятой, и решарпер люто негодует, когда видит наш javascript.
cd %0\..\ copy /b .\..\..\Scripts\JSON.js + (еще много файликов) + Bids.js combined. js java -jar yuicompressor-2.4.8.jar combined.js --type js -o combined.min.js --charset cp-1251 copy /b combined.min.js + (еще много уже минимизированных файликов) + .\..\..\Scripts\jquery\plugins.fileupload.min.js mbcrfull.min.js del combined.min.js del combined.js ::copy /b .\..\..\Styles\MPMessage.css + (еще много файликов) + .\..\..\BCR\Styles\Kondor.css combined1.css ::java -jar yuicompressor-2.4.8.jar combined1.css -o .\..\..\BCR\Styles\mbcrfull.min.css --charset cp-1251 ::del combined1.css ::copy /b .\..\..\Styles\jquery\ui.all.css + (еще много файликов) + .\..\..\Styles\jquery\jqueryslidemenu.css combined2.css ::java -jar yuicompressor-2.4.8.jar combined2.css -o .\..\..\Styles\jquery\mbcrfull.min.css --charset cp-1251 ::del combined2.css ::ping -n 1 -w 10000 192.168.254.254 >nul
Так выглядит файл запуска компрессора в настоящее время. Как видите, строки минификации CSS закомментированы в силу специфики нашего проекта. На самом деле в минификации CSS есть масса тонкостей, а сливать их а один файл — задача не из легких:
- Во-первых, нужно тщательно следить за использованием относительных путей к изображениям. Стили ExtJS и других библиотек основаны на относительных путях, а значит они сразу выпадают из нашего объединения (кстати, в большинстве своем они уже минифицированы).
- Во-вторых, в CSS файлах могут встречаться команды
@import
. Это ад. - В третьих, можно же создавать минифицированные объединенные стили отдельно в каждой из папок, а потом включать в проект, но, как выяснилось, таких файлов у нас получается не так уж много и прирост производительности будет небольшой. Поэтому решили минификацию CSS пока отложить. (Можно было и на Google Closure Compiler остановиться в таком случае)
А теперь самое интересное — батник у нас есть, объединенные скрипты генерируются успешно, осталось их прописать в релизной версии проекта. Все вроде работает, нужно коммитить…. каждый раз запуская скрипт.
Автоматизация минификации при коммите в релиз
Дело в том, что у нас две ветки в SVN — рабочая (DEV) и релизная. Каждый раз перед выкладыванием версии на сервер мы выполняем merge всех (ну или нужной части) изменений, билдим и только потом (если все нормально) коммитим. И надо, во-первых, не забывать самому постоянно выполнять этот батник перед коммитом в релиз, а во-вторых, следить за всеми разработчиками, чтобы тоже не забывали это делать.И тут нам на помощь приходят Hook Scripts в TortoiseSVN!
В настройках клиента SVN заходим на вкладку Hook Scripts и выбираем там папку нашего проекта и сам батник. В опциях Hook Type выбираем «Start-Commit Hook«, чтобы скрипт запускался перед тем, как отобразится окно коммита.
Настройка запуска минификации перед коммитом
Вуаля, все работает и не надо ни за кем следить!
Есть, конечно, куча встроенных в visual studio средств объединения и минификации, но их тоже надо устанавливать на каждой машине, а еще в них тоже много тонкостей. До этого у нас использовался встроенный метод Composite Scripts, но он не обладает достаточной функциональностью в сравнении с теми же YUI или Google closure Compiler.
ASP.NET Core | Бандлинг и минификация
Последнее обновление: 10.05. 2022
В проекте может быть множество файлов скриптов javascript, стилей css, которые подключаются на веб-страницу. Однако чем больше разных скриптов и стилей подключено на веб-странице, тем больше запросов надо совершить браузеру, а серверу обработать. Что увеличивает нагрузку на сервер.
Скрипты и стили могут содержать множество строк. И опять же чем больше в файле строк, тем больше серверу надо передать байт на сторону клиенту. Поэтому также с ростом размера файлов возрастает нагрузка на сервер.
Для решения этих проблем применяются два механизма: бандлинг и минификация.
Бандлинг представляет соединение скриптов или стилей в один общий файл или бандл.
Минификация представляет сокращение содержимого скриптов или стилей.
Для проведения бандлинга и минификации в веб-разработке могут применяться самые различные утилиты и инструменты. Однако если мы работаем в Visual Studio, то нам доступен такой инструмент как Bundler & Minifier, который представляет расширение для Visual Studio.
Для работы с BundlerMinifier нам надо загрузить и установить данное расширение по ссылке.
Либо можно в Visual Studio через пункт меню Extensions -> Manage Extensions и затем в окне управления расширениями найти нужное расширение и установить
Для установки расширения необходимо перезапустить Visual Studio.
Конфигурация BundlerMinifier
Конфигурация BundlerMinifier задается с помощью файла bundleconfig.json. Он определяется в в следующем формате:
[ { // настройки 1-го бандла }, { // настройки 2-го бандла }, { // настройки n-го бандла } ]
Фактически файл определяет массив бандлов. Для настройки каждого отдельного бандла применяется ряд опций:
{ "outputFileName": "wwwroot/js/site.min.js", "inputFiles": [ "wwwroot/js/site.js" ], "minify": { "enabled": true, "renameLocals": true }, "sourceMap": false }
Параметр outputFileName
задает путь выходного файла, который будет формироваться в результате объединения файлов.
Параметр inputFiles
определяет через запятую набор файлов, которые будут объединяться. То есть в данном случае из файла «wwwroot/js/site.js»
будет формироваться файл «wwwroot/js/site.min.js»
Дополнительный параметр minify
указывает, будут ли минифицироваться включаемые в бандл файлы. Значение enabled: true
включает минификацию.
А значение "renameLocals": true
позволяет сократить имена локальных переменных.
Последний параметр sourceMap
указывает, надо ли генерировать файл-карту сопоставления исходного и выходного файлов.
Применение BundlerMinifier
Для примера возьмем простейши проект ASP.NET Core. Для работы с BundlerMinifier определим в проекте папку wwwroot и затем добавим в нее ряд стилей и скриптов:
Допустим, в папке wwwroot/css будут два файла стилей: site.css и style2.css. А в папке wwwroot/js будут располагаться скрипты site.js, site2.js, site3.js.
Также добавим в проект файл bundleconfig. json. Затем изменим его следующим образом:
[ { "outputFileName": "wwwroot/css/bundle.css", "inputFiles": [ "wwwroot/css/site.css", "wwwroot/css/site2.css" ] }, { "outputFileName": "wwwroot/js/bundle.js", "inputFiles": [ "wwwroot/js/site.js", "wwwroot/js/site2.js", "wwwroot/js/site3.js" ], "minify": { "enabled": true, "renameLocals": true } } ]
После сохранения этого файла Visual Studio автоматически создаст четыре новых файла: в папке с js-скриптами появятся полная и минимизированная версия файла bundle.js, который объединяет все скрипты, а в папке со стилями css будет создан файл bundle.css, а также его минимизированная версия — bundle.min.css
И при каждом изменении и повторном сохранении файла Visual Studio также будет генерировать общую и минимизированную версию файлов.
Настройка и запуск бандлинга и миницикации
Мы можем не полагаться на Visual Studio и непосредственно запланировать создание бандлов и их минимизированных версий. Для этого нажмем правой кнопкой мыши на файл bundleconfig.json и в контекстном меню выберем пункт Task Runner Explorer
(Либо можно перейти через пункт меню View -> Other Windows -> Task Runner Explorer). После этого внизу Visual Studio откроется окно Task Runner Explorer. В этом окне нажмем правой кнопкой мыши на пункт Update all files:
При открытии контекстого меню нам надо установить привязку с помощью пункта Binding. Здесь имеются четыре типа привязки:
Before Build
: бандлы будут собираться перед построением проектаAfter Build
: бандлы будут собираться после построения проектаClean
: бандлы будут собираться при очистке проектаProject Open
: бандлы будут собираться при открытии проекта
В любой момент мы можем отменить подобную привязку.
Настройка каталога
Стоит отметить, что скрипты и стили не обязательно должны располагаться в каталоге wwwroot. Например, мы можем дополнительно определить в проекте другую папку, например, назовем ее static, и расположить скрипты и стили в этой папке. А бандлы формировать и подключать из wwwroot:
В этом случае мы могли бы настроить файл bundleconfig.json следующим образом:
[ { "outputFileName": "wwwroot/css/bundle.css", "inputFiles": [ "static/css/*.css" ] }, { "outputFileName": "wwwroot/js/bundle.js", "inputFiles": [ "static/js/*.js" ], "minify": { "enabled": true, "renameLocals": true } } ]
Автоматический бандлинг и минификация
Стоит отметить, что в принципе нам необязательно добавлять файл bundleconfig.json вручную. Мы можем также выделить все нужные элементы, нажать на выделенный элемент правой кнопкой мыши и в контекстном меню выбрать пункт Bundler & Minifier -> Bundle and Minify Files:
После выбора этой опции в диалоговом окне надо будет ввести расположение для выходного файла, в который будет собираться бандл. По умолчанию дается имя bundle.js
. И после
сохранения автоматически сгенерируется файл bundleconfig.json, а также файл бандла.
НазадСодержаниеВперед
Что такое минификация?
Обзор
Когда дело доходит до создания страницы или запуска сценария, веб-браузеры не заботятся о читабельности кода. Минификация удаляет из файла кода все данные, которые не требуются для выполнения файла. В отличие от традиционных методов сжатия, мини-файлы не нужно распаковывать, прежде чем их можно будет прочитать, изменить или выполнить.
Минификация выполняется после написания кода для веб-приложения, но до его развертывания. Когда пользователь запрашивает веб-страницу, вместо полной версии отправляется уменьшенная версия, что приводит к более быстрому времени отклика и снижению затрат на пропускную способность. Минификация используется на веб-сайтах, начиная от небольших личных блогов и заканчивая многомиллионными пользовательскими сервисами.
Как работает минификация
Минификация работает, анализируя и переписывая текстовые части веб-сайта, чтобы уменьшить общий размер файла. Минификация распространяется на сценарии, таблицы стилей и другие компоненты, которые веб-браузер использует для отображения сайта.
Минификация выполняется на веб-сервере перед отправкой ответа. После минимизации веб-сервер использует минифицированные ресурсы вместо исходных ресурсов для более быстрого распространения среди пользователей.
Вот пошаговое описание того, как работает минификация:
- Веб-разработчик создает файл JavaScript или CSS для использования в веб-приложении. Эти файлы отформатированы для удобства разработчика, что означает, что они используют пробелы, комментарии, длинные имена переменных и другие приемы для удобства чтения.
- Разработчик применяет метод минимизации (см. ниже), чтобы преобразовать файл в более оптимизированный, но трудный для чтения. Общие методы минимизации включают удаление пробелов, сокращение имен переменных и замену многословных функций более короткими и лаконичными функциями.
- Веб-сервер использует уменьшенный файл при ответе на веб-запросы, что снижает использование полосы пропускания без ущерба для функциональности.
Преимущество минификации в том, что ее нужно выполнять только при изменении исходного файла. В сочетании с другими методами сжатия минификация может значительно сократить использование полосы пропускания как для предприятия, так и для пользователя.
Методы и инструменты минификации
Одним из наиболее полных инструментов минификации является minify. Minify обрабатывает минимизацию, кэширование и сжатие файлов CSS, HTML и JavaScript. Minify также предлагает интеграцию с популярными веб-приложениями и фреймворками, включая WordPress и Zend Framework.
Минимизация HTML
Google предоставляет расширение PageSpeed Insights Chrome, которое рекомендует повысить производительность любого веб-сайта. PageSpeed Insights предоставляет правило «Minify HTML», которое создает уменьшенную версию открытого веб-сайта.
Минимизация CSS
Поскольку CSS редко меняется, несколько онлайн-инструментов обеспечивают мгновенную минимизацию CSS. CSS Minifier – это быстрый и простой способ минимизировать CSS, а Refresh-SF использует несколько инструментов для минимизации CSS, HTML и JavaScript.
Минимизация JavaScript
Инструмент Google для оптимизации JavaScript — Closure Compiler — создает более эффективную копию любого файла JavaScript. Когда разработчик вносит изменения в файл JavaScript, он использует Closure Compiler для минимизации кода. Новый файл передается на веб-сервер, где к нему может получить доступ веб-браузер пользователя.
Пример минификации
В следующем блоке кода показан пример простого HTML и CSS:
<голова> <стиль> #myContent {семейство шрифтов: Arial} #myContent {размер шрифта: 90% } стиль> голова> <тело> <дел>Привет, мир!
Ниже показан тот же код после минификации:
<голова> голова> <тело>тело>Привет, мир!