Не настроена минификация javascript файлов
Хочу поделиться способом автоматической минификации стилей и скриптов. Решение было сделано на БУС, но подойдет для других CMS. Описанное решение может оказаться полезным тем, у кого стили распределены по компонентам и не настроены автоматические сборщики типа gulp или webpack и д.р.
Думаю все знают про настройки Оптимизации CSS и JS в главном модуле, а именно "Подключать минифицированные версии CSS и JS файлов" . К сожалению в Битриксе не заложена функция создания минифицированных файлов ( *.min.css и *.min.js ), но зато заложена опция подключения таких файлов.
После успешной установки узнайте путь нахождения установленного модуля, выполнив команду. К примеру у меня, на боевом сервере был свой путь, а на серверах разработки другой.
В ответе будет строка с путём до uglifycss . В моём случае - /usr/local/bin/uglifycss . Далее мы этот путь будем использовать в классе.
В приведенном выше классе есть метод \CCssMinify::getUglifyCssPath, в котором как раз мы возвращаем путь до uglifycss, полученный через whereis uglifycss. Мы не используем специфических настроек запуска uglifycss , только путь до минифицированной версии, которая будет находится рядом с основной.
Сам Агент реализован методом \CCssMinify::minifyAgent(); Как видно из кода, метод автоматически очищает CSS КЕШ сайта. Пересозданию минификаций подвержены только те файлы css, время изменения которых позже созданных для них минификаций. В Административном разделе агент имеет следующие настройки:
Среднее время выполнения агента на моём проекте: 7-8 секунд, для ПОЛНОГО пересоздания. В режиме обычно работы, при пересоздании только изменённых файлов, не превышает 0.1 секунды. Не берусь говорить точно об объёмах, но проект довольно крупный, так что не сильно беспокойтесь, что всё повиснет. Хотя перестраховаться не мешает.
Пример результата работы агента:
C CSS мы закончили. давай перейдем к JS.
После успешной установки узнайте путь нахождения установленного модуля, выполнив команду.В ответе будет строка с путём до uglifyjs . В моём случае - /usr/local/bin/uglifyjs . Далее мы этот путь будем использовать в классе.
Сам Агент реализован методом CJsMinify::minifyAgent(). Как видно из кода, метод автоматически очищает JS КЕШ сайта. Пересозданию минификаций подвержены только те файлы js, время изменения которых позже созданных для них минификаций. В Административном разделе агент имеет следующие настройки:
Среднее время выполнения агента на моём проекте: 30-32 секундs, для ПОЛНОГО пересоздания. В режиме обычной работы, при пересоздании только изменённых файлов, не превышает 0.1 секунды.
Пример результата работы:
Бонус:
В качестве бонуса поделюсь примером .gitignore, чтобы не засорять репозиторий минификациями:
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Перед выкладыванием JavaScript на «боевую» машину – пропускаем его через минификатор (также говорят «сжиматель»), который удаляет пробелы и по-всякому оптимизирует код, уменьшая его размер.
В этой статье мы посмотрим, как работают современные минификаторы, за счёт чего они укорачивают код и какие с ними возможны проблемы.
Современные сжиматели
Рассматриваемые в этой статье алгоритмы и подходы относятся к минификаторам последнего поколения.
Самые широко используемые – первые два, поэтому будем рассматривать в первую очередь их.
Наша цель – понять, как они работают, и что интересного с их помощью можно сотворить.
С чего начать?
Обратите внимание на флаг --charset для GCC. Без него русские буквы будут закодированы во что-то типа \u1234 .
Google Closure Compiler также содержит песочницу для тестирования сжатия и веб-сервис, на который код можно отправлять для сжатия. Но скачать файл обычно гораздо проще, поэтому его редко где используют.
- Убедиться, что стоит Node.js
- Поставить npm install -g uglify-js .
- Сжать файл my.js : uglifyjs my.js -o my.min.js
Что делает минификатор?
Все современные минификаторы работают следующим образом:
Разбирают JavaScript-код в синтаксическое дерево.
Также поступает любой интерпретатор JavaScript перед тем, как его выполнять. Но затем, вместо исполнения кода…
Бегают по этому дереву, анализируют и оптимизируют его.
Записывают из синтаксического дерева получившийся код.
Как выглядит дерево?
Посмотреть синтаксическое дерево можно, запустив компилятор со специальным флагом.
Для GCC есть даже способ вывести его:
Сначала сгенерируем дерево в формате DOT:
Здесь флаг --print_tree выводит дерево, а --use_only_custom_externs убирает лишнюю служебную информацию.
Файл в этом формате используется в различных программах для графопостроения.
Чтобы превратить его в обычную картинку, подойдёт утилита dot из пакета Graphviz:
Пример кода my.js :
Результат, получившееся из my.js дерево:
В узлах-эллипсах на иллюстрации выше стоит тип, например FUNCTION (функция) или NAME (имя переменной). Комментарии к ним на русском языке добавлены мной вручную.
Кроме него к каждому узлу привязаны конкретные данные. Сжиматель умеет ходить по этому дереву и менять его, как пожелает.
Обычно когда код превращается в дерево – из него естественным образом исчезают комментарии и пробелы. Они не имеют значения при выполнении, поэтому игнорируются.
Но Google Closure Compiler добавляет в дерево информацию из комментариев JSDoc, т.е. комментариев вида /** . */ , например:
Такие комментарии не создают новых узлов дерева, а добавляются в качестве информации к существующем. В данном случае – к переменной minIEVersion .
В них может содержаться информация о типе переменной ( number ) и другая, которая поможет сжимателю лучше оптимизировать код ( const – константа).
Оптимизации
Сжиматель бегает по дереву, ищет «паттерны» – известные ему структуры, которые он знает, как оптимизировать, и обновляет дерево.
В разных минификаторах реализован разный набор оптимизаций, сами оптимизации применяются в разном порядке, поэтому результаты работы могут отличаться. В примерах ниже даётся результат работы GCC.
Объединение и сжатие констант
- 'my' + 'string' → "mystring" .
- 600 * 600 * 5 → 18E5 (научная форма числа, для краткости).
- 1 && 0 → 0 .
- b && 0 → без изменений, т.к. результат зависит от b .
- Локальная переменная заведомо доступна только внутри функции, поэтому обычно её переименование безопасно (необычные случаи рассмотрим далее).
- Также переименовываются локальные функции.
- Вложенные функции обрабатываются корректно.
После оптимизации GCC:
- Локальные переменные были переименованы.
- Лишние переменные убраны. Для этого сжиматель создаёт вспомогательную внутреннюю структуру данных, в которой хранятся сведения о «пути использования» каждой переменной. Если одна переменная заканчивает свой путь и начинает другая, то вполне можно дать им одно имя.
- Кроме того, операции elem = getElementsById и elem.parentNode объединены, но это уже другая оптимизация.
Если переменная присваивается, но не используется, она может быть удалена. В примере выше эта оптимизация была применена к переменной parent , а затем и к параметру node .
Заведомо ложная ветка if(0) < .. >убрана, заведомо истинная – оставлена.
То же самое будет с условиями в других конструкциях, например a = true ? c : d превратится в a = c .
Код после return удалён как недостижимый.
- Конструкция while переписана в for .
- Конструкция if (i) . переписана в i&&. .
- Конструкция if (cond) . else . была переписана в cond ? . : . .
Инлайнинг функции – приём оптимизации, при котором функция заменяется на своё тело.
После оптимизации (переводы строк также будут убраны):
- Вызовы функций createMessage и showElement заменены на тело функций. В данном случае это возможно, так как функции используются всего по разу.
- Эта оптимизация применяется не всегда. Если бы каждая функция использовалась много раз, то с точки зрения размера выгоднее оставить их «как есть».
Переменные заменяются на значение, если оно заведомо известно.
Переменная isVisible заменена на true , после чего if стало возможным убрать.
Переменная hi заменена на строку.
Казалось бы – зачем менять hi на строку? Ведь код стал ощутимо длиннее!
…Но всё дело в том, что минификатор знает, что дальше код будет сжиматься при помощи gzip. Во всяком случае, все правильно настроенные сервера так делают.
Алгоритм работы gzip заключается в том, что он ищет повторы в данных и выносит их в специальный «словарь», заменяя на более короткий идентификатор. Архив как раз и состоит из словаря и данных, в которых дубликаты заменены на идентификаторы.
Если вынести строку обратно в переменную, то получится как раз частный случай такого сжатия – взяли "Привет вам из JavaScript" и заменили на идентификатор hi . Но gzip справляется с этим лучше, поэтому эффективнее будет оставить именно строку. Gzip сам найдёт дубликаты и сожмёт их.
Плюс такого подхода станет очевиден, если сжать gzip оба кода – до и после минификации. Минифицированный gzip-сжатый код в итоге даст меньший размер.
- …И ещё некоторые другие мелкие изменения кода…
Подводные камни
Описанные оптимизации, в целом, безопасны, но есть ряд подводных камней.
Конструкция with
Куда будет присвоено значение position = 'absolute' ?
Это неизвестно до момента выполнения: если свойство position есть в style – то туда, а если нет – то в локальную переменную.
Можно ли в такой ситуации заменить локальную переменную на более короткую? Очевидно, нет:
Такая же опасность для сжатия кроется в использованном eval . Ведь eval может обращаться к локальным переменным:
Получается, что при наличии eval мы не имеем права переименовывать локальные переменные. Причём (!), если функция является вложенной, то и во внешних функциях тоже.
А ведь сжатие переменных – очень важная оптимизация. Как правило, она уменьшает размер сильнее всего.
Что делать? Разные минификаторы поступают по-разному.
- UglifyJS – не будет переименовывать переменные. Так что наличие with/eval сильно повлияет на степень сжатие кода.
- GCC – всё равно сожмёт локальные переменные. Это, конечно же, может привести к ошибкам, причём в сжатом коде, отлаживать который не очень-то удобно. Поэтому он выдаст предупреждение о наличии опасной конструкции.
Ни тот ни другой вариант нас, по большому счёту, не устраивают.
Для того, чтобы код сжимался хорошо и работал правильно, не используем with и eval .
Либо, если уж очень надо использовать – делаем это с оглядкой на поведение минификатора, чтобы не было проблем.
Я подробно рассмотрел на примере популярных CMS, как выполнить минификацию (сжатие) исходного кода сайта. Для кого-то это может показаться совсем не нужным дополнением, но я рекомендую уделить этому особое внимание.
Для чего вообще делается сжатие файлов? Для того, чтобы уменьшить их вес, тем самым ускорить работу вашего сайта.
Приведу простой пример. У вас есть не сжатая библиотека jQuery, которая весит 120 килобайт. А в сжатом виде эта же библиотека будет весить 60 килобайт. Получаем экономию в 60 КБ, что вполне неплохо. А если таких файлов 15-20?
Вообще сжатие файлов можно производить и вручную через какой-нибудь онлайн-сервис, а можно поступить куда умнее и воспользоваться готовым PHP-скриптом, с помощью которого легко можно решить поставленные задачи.
Минификация (сжатие) CSS-файлов на PHP
Основная идея минификации стилей будет заключаться в следующем: мы объединяем все файлы в один и удаляем в нем все переводы строк, символы табуляции, двойные пробелы и комментарии.
PHP-скрипт будет выглядеть следующим образом:
В нем вы прописываете адреса до всех ваших файлов стилей и отправляете итоговый файл на сайт по FTP или другим удобным для вас способом.
После чего на сайте вы удаляете указанные в скрипте стили и подключаете новый стиль по такому принципу:
Где «/style.php» – это ссылка до ранее созданного PHP-файла.
Сохраняете все изменения и смотрите, не поехал ли дизайн на вашем сайте, если поехал – то проверьте, корректные ли адреса вы прописали в скрипте.
Теперь, если вы обратитесь к вашему скрипту через браузер, то увидите, что ваши стили максимально оптимизированы.
Минификация (сжатие) JS-файлов на PHP
Оптимизация скриптов выполняется примерно по тому же принципу: объединяем все файлы в один и удаляем в нем переводы строк, двойной пробел и знак табуляции, а также комментарии кода.
Итоговый скрипт будет выглядеть следующим образом:
Не забывайте в нем прописать ссылки до ваших скриптов.
И по аналогии с CSS-файлами – подключение следующее:
Где «/script.php» – ссылка до ранее созданного PHP-скрипта.
На что здесь стоит обратить внимание?
- Проставляйте корректные ссылки до ваших файлов.
- На вашем хостинге должна быть поддержка PHP.
В остальном вроде проблем быть не должно, но если все-таки они появились – пишите об этом в комментариях, постараюсь вам помочь.
Минификация CSS , JS , HTML файлов (не путать со сжатием CSS ) включает в себя удаление любых ненужных символов из файла, чтобы уменьшить его размер и тем самым ускорить загрузку.
Ниже приведены примеры того, что удаляется во время минификации файла:
- Символы пробелов;
- Комментарии;
- Разрывы строк;
- Разделители блоков.
В большинстве случаев процесс минификации не влияет на файл, а оптимизирует его для загрузки. Особенно полезна минификация CSS , JS и HTML-файлов . Кроме этого Google при ранжировании учитывает быстродействие ресурса, а минификация помогает ускорить работу сайта.
Чтобы различать минифицированные файлы, в их имена добавляется расширение .min ( например: foobar.min.css ).
Разница между минификацией и сжатием
Минификация и сжатие CSS файлов – это не одно и то же. Хотя оба этих метода предназначены для уменьшения времени загрузки. Различие заключается в том, как они работают. Сжатие используется для уменьшения размера файла при помощи алгоритмов сжатия, таких как Gzip или brotli . Файлы сжимаются перед отправкой клиенту.
Следовательно, процесс сжатия осуществляется следующим образом:
- Файл сжимается с помощью алгоритма сжатия;
- Выполняется запрос для сжатой версии файла;
- Сжатый файл отправляется от сервера к клиенту;
- Клиент распаковывает файл и считывает информацию.
Поддерживаемые алгоритмы сжатия могут варьироваться в зависимости от сервера, а также браузеров. Когда браузер отправляет запрос серверу, он сообщает ему, какой метод сжатия поддерживает, так что сервер может оптимизировать отклик для этого браузера.
Если браузер не поддерживает конкретный алгоритм сжатия, сервер будет отправлять данные в первоначальном виде ( без обработки ).
Пример минификации
В следующем примере показано, как CSS файл выглядит до и после минификации.
ДО CSS минификации:
ПОСЛЕ CSS минификации:
После минификации CSS-файл стало сложнее читать, поскольку отсутствуют переносы строк, разделители и т.д. Но оптимизированный вариант имеет меньший размер, что ускоряет его загрузку, как и сжатие CSS онлайн .
Минификация CSS
Онлайн
Инструменты разработки
Минификация JS
Онлайн
Инструменты разработки
- yui.github.io : предоставляет возможность минимизировать JS файлы для веб-проектов.
Минификация HTML
WordPress плагины для минификации
- Better WordPress Minify ;
- Autoptimize .
Многие плагины кэширования также предлагают возможность минификации. Например, Cache Enabler поставляется с возможностью включения минификации HTML и JS . Использование этой функции позволяет уменьшить время загрузки веб-страниц, но в некоторых случаях это может привести к конфликту с другим плагином сжатия CSS WordPress .
Drupal модуль минификации
В сообществе Drupal популярным вариантом для минификации является модуль Minify . Он позволяет минимизировать HTML , JavaScript файлы и использует компилятор Google Closure , чтобы проанализировать минификацию. Конфигурация данного модуля проходит быстро.
Joomla! Расширение для минификации
CMS Joomla также предлагает расширение для оптимизации сайта под названием JCH Optimize , которое уменьшает размер JavaScript и производит сжатие CSS файлов . Оно также предоставляет возможность включить GZIP сжатие для агрегированных файлов.
Преимущества уменьшения файлов
Дайте знать, что вы думаете по этой теме материала в комментариях. Мы очень благодарим вас за ваши комментарии, подписки, отклики, дизлайки, лайки!
Минификация (сокращение) объёма кода является одним из эффективных приёмов оптимизации скорости загрузки сайта, обеспечивающим снижение общего размера веб-страниц.
Содержание
Принципы сокращения кода
Минификация (минимизация, сокращение) кода подразумевает его оптимизацию в пользу уменьшения объёма памяти, при этом в жертву приносится удобочитаемость.
Минифицированный код является полностью рабочим, но лишенным всех символов и участков, не влияющих на его работоспособность, к которым относятся:
- комментарии,
- лишние пробелы,
- табуляция,
- переносы строк,
- другие лишние символы.
Перечисленные символы и комментарии в коде применяются для лучшего его восприятия разработчиками при написании и редактировании, но «раздувают» его объём, увеличивая общий вес веб-страницы. Поэтому целесообразно их удалять перед применением на сайте, оставляя копию оригинала для возможного редактирования.
Сокращенные файлы фреймворков
Все популярные JS-библиотеки и CSS-фреймворки предоставляют необходимые файлы в нормальном (удобочитаемом) и сокращенном формате с префиксом .min в названии. Например:
bootstrap.js Версия для веб-разработчика. При необходимости может редактироваться и минифицироваться, в последующем заменяя собой сокращенную версию. bootstrap.min.js Сокращенная версия для применения на сайте.
Файл | Нормальный | Сокращенный | Разница | Коэффициент |
---|---|---|---|---|
uikit-2.27.4.js | 119 КБ | 57 КБ | 62 КБ | 52% |
uikit-2.27.4.css | 181 КБ | 105 КБ | 76 КБ | 42% |
bootstrap-3.3.7.js | 69 КБ | 37 КБ | 32 КБ | 46% |
bootstrap-3.3.7.css | 143 КБ | 119 КБ | 24 КБ | 17% |
jquery-3.2.1.js | 261 КБ | 85 КБ | 176 КБ | 67% |
По данным таблицы не сложно заметить существенную разницу в размере обычных и сокращенных файлов: применение минифицированных версий определённо сделает веб-страницы легче, что благоприятно отразится на скорости загрузки сайта. Именно поэтому сервис PageSpeed Insights обращает внимание на объём кода (HTML, CSS и JS) и возможности по его сокращению для улучшения производительности:
Сокращение HTML-кода
Минификация HTML-кода не столь эффективна по отношению к сокращению CSS и JavaScript по двум причинам:
- HTML-код, как правило, составляет незначительную часть от общего объёма кода веб-страницы.
- HTML-код динамических сайтов формируется на сервере и отдаётся браузеру при запросах.
Поэтому предварительно минифицированные HTML-файлы могут применяться только на статичных веб-страницах. Но ведь PageSpeed Insights при наличии несокращенного кода на проверенной странице синим по белому пишет «Сократите код HTML». И действительно, есть выход даже для динамических сайтов: это расширения для CMS. Об этом читайте ниже.
Пример сокращения HTML-кода
Удобочитаемый фрагмент HTML-кода размером 313 Б:
Минифицированный вариант представленного выше HTML-кода составляет 208 Б:
Объём кода значительно сократился за счет удаления:
- пробелов между тегами,
- переносов строк,
- комментариев в коде ( <!-- --> ),
- кавычек вокруг значений атрибутов тегов,
- лишних атрибутов (в частности type ).
Все перечисленные сокращения сохраняют соответствие кода стандарту HTML5.
Минификация HTML онлайн
Как указывалось выше, предварительная минификация HTML-кода на динамических сайтах не применяется, т. к. он формируется на сервере (например, посредством PHP ). Но если появится необходимость сократить HTML-код (например, для статичного сайта), то существует неплохой онлайн-сервис HTML Compressor, позволяющий также сокращать код CSS и JS.
Сервис позволяет установить степень сокращения HTML-кода, определяющая необходимость удаления переносов строк, кавычек для значений атрибутов и прочее.
Примечательно, что в закладке «Compressed», отображающей результат минификации, можно проверить валидность как исходного, так и оптимизированного кода, перейдя по ссылкам «Validate Original Code» и «Validate Compressed Code» соответственно.
К минусам сервиса можно отнести отсутствие возможности передавать файл для оптимизации кода, а также отсутствие продвинутых параметров оптимизации CSS-кода (автоматическое совмещение свойств для одинаковых селекторов).
Сокращение CSS-кода
Объём CSS-кода, как правило, составляет куда большую часть веса веб-страницы, чем HTML, поэтому не следует игнорировать замечание сервиса PageSpeed Insights «Сократите CSS» и пренебрегать возможностью использовать сокращенный код в CSS-файлах для ускорения загрузки веб-страниц сайта.
Пример сокращения CSS-кода
Удобочитаемый фрагмент CSS-кода размером 123 Б:
Сокращённый вариант указанного фрагмента составляет 84 Б:
Размер уменьшился за счет:
- удаления комментария ( /* */ ),
- удаления лишних пробелов,
- удаления всех переносов строк,
- удаления символов ; перед закрывающей фигурной скобкой > ,
- объединения свойств для одного селектора ( a ).
Минификация CSS онлайн
Чтобы качественно сократить CSS-код рекомендуем применять специализированный онлайн-сервис CSS Resizer, который позволяет:
Сокращение JS-кода
Минификация кода JavaScript не менее актуальна, чем для CSS: во многих случаях JS-код занимает наибольший объём памяти по сравнению с CSS и HTML вместе взятыми, т. к. на сайтах применяются JS-скрипты CSS-фреймворков, а также JS-библиотеки и плагины.
Пример сокращения JS-кода
Удобочитаемый фрагмент JS-кода объёмом 328 B:
Сокращенный вариант фрагмента весит 172 B:
Как и в случае с HTML и CSS, уменьшение объёма происходит за счет удаления лишних элементов кода, не влияющих на его работоспособность.
Минификация JS онлайн
Сократить JavaScript онлайн можно с помощью рассмотренного на примере минификации HTML-кода сервиса HTML Compressor, который минифицирует JS-код не хуже прочих.
Для разнообразия предлагаем к рассмотрению другой узконаправленный онлайн-сервис JSCompress:
К плюсам сервиса можно отнести возможность отправлять код для минификации в файле, к минусам — отсутствие возможности редактировать сокращенный сервисом код в окне вывода.
Сокращение кода сайтов на CMS
Для популярных CMS, таких как WordPress или Joomla, существует масса расширений, автоматически минифицирующих код HTML, CSS и JS. Иначе говоря, достаточно установить и настроить определённый плагин, и «танцы с бубном» вокруг несокращенного кода отпадают сами собой: расширение обеспечит минификацию кода перед отправкой клиенту, после чего этот код будет хранится в кэше сервера и отдаваться при запросах определённое в настройках время.
В частности для Joomla и WordPress применятся превосходный плагин JCH Optimize, способный не только автоматически сокращать весь код веб-страниц, но и оптимизировать его согласно всем рекомендациям сервиса от Google.
Читайте также: