Уменьшение размера загружаемых объектов. Минимизация, обфускация и сжатие кода. Обзор методов клиентской оптимизации
Оптимизация изображений
Устранение избыточного кода
Минимизация
Этим термином именуется процесс уменьшения объема кода за счет следующих операций: удаления избыточных пробелов, табуляций и переносов строк; удаление комментариев; удаление дублирующегося кода.
Минимизация применима к коду HTML, CSS и JS и в зависимости от размера и содержимого кода, позволяет достичь результатов близких, к gzip-сжатию, уменьшать файлы до 30% от исходного размера, а иногда и более. При использовании же еще и gzip-сжатия, предварительная минимизация позволяет увеличить итоговую степень сжатия в среднем на 3-5%.
В ситуациях, когда gzip-сжатие применить невозможно, например, когда CSS и JS код встроены в веб-страницу, минимизация - один из немногих оставшихся способов существенно уменьшить размер такой веб-страницы.
Стоит заметить, что после проведения минимизации результирующий код по-прежнему полностью совместим со всеми браузерами т.к. он по-прежнему останется тем же корректным HTML, CSS или JS кодом, в то время как, gzip-сжатие до сих пор поддерживается не всеми пользовательскими браузерами. Кроме того минимизированный код всегда распознается и обрабатывается браузером быстрее.
Обфускация
Так называется процесс, при котором JavaScript-код специальным образом запутывается для того, чтобы затруднить процесс его разбора и модификации. Обфускация может включать в себя те же операции, что и минимизация, а также: кодирование символов в различные форматы; изменение имен переменных и функций; добавление избыточного кода.
Ниже приведен фрагмент JS-кода до обфускации:
var Prototype = {
Version: '1.6.1_rc3',
Browser: (function(){
var ua = navigator.userAgent;
var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
return {
IE: !!window.attachEvent && !isOpera,
Opera: isOpera,
WebKit: ua.indexOf('AppleWebKit/') > -1,
Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
MobileSafari: /Apple.*Mobile.*Safari/.test(ua)
}
})(),
BrowserFeatures: {
XPath: !!document.evaluate,
SelectorsAPI: !!document.querySelector,
ElementExtensions: (function() {
var constructor = window.Element || window.HTMLElement;
return !!(constructor && constructor.prototype);
})(),
SpecificElementExtensions: (function() {
if (typeof window.HTMLDivElement !== 'undefined')
return true;
var div = document.createElement('div');
var form = document.createElement('form');
var isSupported = false;
if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
isSupported = true;
}
div = form = null;
return isSupported;
})()
},
ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
emptyFunction: function() { },
K: function(x) { return x }
};
А так этот же код выглядит после обфускации:
eval((function(x){var d="";var p=0;while(p<x.length){if(x.charAt(p)!="`")d+=x.charAt(p++);else{var l=x.charCodeAt(p+3)-28;if(l>4)d+=d.substr(d.length-x.charCodeAt(p+1)*96-x.charCodeAt(p+2)+3104-l,l);else d+="`";p+=4}}return d})("var Prototype={Version:\"1.6.0.3\",Browser:{IE:!!(window.attachEvent&&navigator.userAgent.indexOf(\"Opera\")===-1),` )!:` -@>-1,WebKit` 1:Apple` C\"/` P\"Gecko` 7:` >!` I!`!_;KHTML`!w#,MobileSafari:!!` E0match(/`!P!.*` K\".*` M\"/)}`#F$Features:{XPath:!!document.evaluate,SelectorsAPI` 5(query` 5$,ElementExtensions:!!`$=#HTML` 8#,Specific` =.` o%create` :#(\"div\").__proto__&&` \"C!==` 24form` ?(},ScriptFragment:\"<s` ,![^>]*>([\\\\S\\\\s]*?)</` 4\">\",JSONFilter:/^\\/\\*-secure-([\\s\\S]*)\\*\\/\\s*$/,emptyFunction:f` \"#(){},K` %&x){return x;}};"))
Несмотря на подобный вид, такой код работает точно также как исходный, из которого он был получен.
В редких ситуациях при помощи обфускации можно достичь более эффективного сжатия, чем при помощи минимизации, но это отнюдь не является основной целью операции. В ситуации, когда в код добавляется большое количество избыточного кода объем кода может значительно увеличиваться.
О наиболее популярных приложениях для минимизации и обфускации было рассказано в книге «Разгони свой сайт», во второй главе. Также часть подобных приложений рассматривается в начале седьмой главы.
Сжатие
Наиболее простым способом уменьшения размера загружаемых объектов с точки зрения внедрения является сжатие текстовых файлов при помощи технологии gzip. Эта технология, основанная на широко известном алгоритме DEFLATE, существует уже более 13 лет. По данным компании Google, среди всех использующихся на сегодняшний день браузеров 99,8% распознают gzip-сжатие HTML-документов и файлов CSS и JavaScript.
Со времен появления поддержки протокола HTTP/1.1, браузеры указывают в HTTP-запросах поддерживаемые типы сжатия, устанавливая заголовок Accept-Encoding:
Accept-Encoding: gzip, deflate
Если веб-сервер получает такой заголовок в запросе, он может применить сжатие ответа одним из методов, перечисленных клиентом. Отправляя ответ, сервер уведомляет клиента о том, каким методом сжимался ответ при помощи заголовка Content-Encoding.
Content-Encoding: gzip
Для использования технологии gzip-сжатия обычно достаточно прописать несколько строк в конфигурационном файле сервера и общая скорость загрузки может возрасти на десятки и даже сотни процентов - размер сжатых файлов обычно не превышает 20% от исходного размера.
С использованием gzip-сжатия нагрузка на браузеры пользователей практически не возрастает, поскольку восстановление сжатого файла малого размера (а на веб-страницах размеры текстовых файлов измеряются в килобайтах) происходит почти мгновенно. Временные затраты возможны на стороне сервера, но только в случае динамического сжатия, т.е. сжатия в реальном времени. В ситуации, когда динамическое сжатие оказывает недопустимо большую нагрузку на веб-сервер, следует применять статическое сжатие, т.е. сжатие и кэширование всех необходимых файлов только при их изменении.
Используя gzip-сжатие важно убедиться в том, что оно отключено для изображений и других двоичных файлов. Поскольку эти файлы уже сжаты, а их размер обычно существенно превышает размеры типичных текстовых файлов, использование gzip-сжатия не принесет никакого выигрыша в клиентском быстродействии веб-страниц, а только лишь увеличит нагрузку на сервер. Следует также обратить внимание на то, что сжатие эффективно только для файлов размером порядка одного килобайта и более. Сжатие файлов меньшего размера ощутимого результата, скорее всего, не принесет.
Достичь дополнительного выигрыша при сжатии файлов HTML и CSS можно также за счет использования стандартов верстки, при которых везде, где это возможно используется один и тот же регистр, а все HTML-атрибуты, CSS-свойства и другие подобные элементы разметки упорядочиваются (чаще всего по алфавиту).
Сжатие текстовых файлов подробно рассмотрено во второй главе.