После публикации ряда заметок на тему сжатия и объединения JavaScirpt-файлов стоит все же осветить наиболее характерные проблемы этого самого сжатия и объединения.
Начнем с простого: как JS-сжатие способно испортить нам настроение. И как его поднять обратно :)
Вообще стоит сразу упомянуть, что сжатие JavaScript-файлов даст нам всего лишь 5-7% уменьшение размера относительно обычного gzip, который можно использовать везде (нет, реально, везде — начиная от конфигурации Apache через .htaccess и заканчивая статическим сжатием через mod_rewrite + mod_mime и конфигурацией nginx (или LightSpeed). Но вернемся к теме топика: мы хотим минимизировать JavaScript-файлы, как это лучше всего сделать?
Два года назад был произведен обзор текущих инструментов, за это время ситуация не сильно изменилась (разве что появился Google Compiler). Но все по порядку.
+ +
преобразуется в ++
, это ломает логику), это тоже лечится, но сложнее.Резюме здесь: проверяйте JavaScript не только на том сервере, где он разрабатывается, но и после оптимизации. Лучше всего — по одним и тем же unit-тестам. Узнаете много нового про описанные инструменты :) Если это не критично, то используйте просто gzip (лучше всего статический с максимальной степенью сжатия) для обслуживания JavaScript.
После того как мы разобрались со сжатием JavaScript-файлов, хорошо бы затронуть тему их объединения. Средний сайт имеет 5-10 JavaScript-файлов + несколько встроенных (inline) кусков кода, которые могут так или иначе вызывать подключаемые библиотеки. В итоге — 10-15 кусков кода, которые можно объединить вместе (плюсов от этого море — начиная от скорости загрузки на стороне пользователя и заканчивая отказоустойчивостью сервера под DDoS — тут каждое соединение будет на счету, даже статическое).
Но вернемся к баранам. Сейчас мы будем разговаривать про некоторую автоматизацию объединения «сторонних» скриптов. Если вы имеете к ним полный доступ (и разбираетесь в веб-разработке), то не составляет большого руда пофиксить проблемы (или исключить ряд проблемных скриптов из объединения). В противном случае (когда набор скриптов никак не хочет объединяться без ошибок) нижеследующий подход как раз для вас.
Итак, у нас есть 10-15 кусков кода (часть из них в виде встроенного кода, часть — в виде внешних библиотек, которые мы можем так же «слить» вместе). Нам нужно гарантировать их независимую работоспособность. В чем она заключается?
Если у нас есть JavaScript-ошибка в файле, то браузер прекращает выполнение этого файла на ошибке (некоторые наиболее древние еще и прекращают выполнение всех JavaScript-файлов на странице в этом случае, но мы не совсем про это разговариваем). Соответственно, если первая же библиотека, которую мы хотим объединить в общий файл, выдает ошибку, то во всех браузерах у нас клиентская логика после объединения развалится. Грустно.
Дополнительно стоит отметить, что встроенный (inline) код достаточно тяжело отлаживать. Его можно либо исключить из объединения (например, расположив вызов объединенного файла до или после кода), или же при его использовании вообще отменить объединение файлов.
Что мы можем с этим поделать? Наиболее простой путь: исключать проблемные файлы (при этом ошибки могут проявляться только на этапе объединения, отдельные же файлы могут отрабатывать на ура) из логики объединения. Для этого нужно будет отслеживать, в каком месте происходить ошибка, и собрать конфигурацию для объединения для каждого такого случая.
Но можно поступить несколько проще. Для JavaScript мы можем воспользоваться конструкцией try-catch
. Ага, мысль уловили? Еще нет? Мы можем все содержимое файлов, которые объединяем, заключать в try {}
, а в catch(e) {}
вызывать подключение внешнего файла примерно следующим образом:
try { ... содержимое JavaScript-библиотеки ... } catch (e) { document.write('исходный вызов JavaScript-файла'); // или console.log('нужно исключить из объединения JavaScript-файл'); }
При этом у нас у пользователя загрузится один-единственный файл, если никаких проблем не возникло. Если же ошибки были, то подключатся все внешние проблемные файлы в прежнем порядке. Это и обеспечит обратную совместимость.
Очевидно, что данный подход не является «самым правильным». Наиболее логичным было бы определить JavaScript-ошибки, их устранить, и загружать для всех пользователей один файл. Но не всегда это возможно. Также стоит учесть, что try-catch
конструкция тяжеловата для исполнения в браузерах (добавляет 10-25% ко времени инициализации), стоит быть с ней осторожным.
Но описанный подход может замечательно применяться для отладки конкретно объединения JavaScript-файлов: ведь он позволяет точно определять, какие файлы «сыпятся» (если файлов несколько десятков, это очень и очень полезно).
После дополнительной минимизации JavaScript-файлов обязательно проверяйте их функциональность. А отладку корректности объединения JavaScript-файлов можно легко автоматизировать, или даже настроить обратную совместимость в случае невозможности отладки конкретных скриптов.