


Альтернативные методы сжатия. Сжатие тегом canvas
Распаковка, реализованная на JavaScript
canvas — предложенный фирмой «Apple» тег, который, на данный момент, входит в HTML5. Он позволяет при помощи JavaScript создавать, на ограниченном тегом участке, растровые изображения.
Идея сжатия, реализуемого при помощи этого тега, проста — каждый байт сжимаемого содержимого представляется как точка изображения любого формата сжатия без потерь, поддерживаемого браузером (GIF, PNG). Это изображение запрашивается с сервера и подгружается в тег canvas методом drawImage (поддерживается браузерами Firefox 1.5 и выше, Safari 2.0 и выше, Opera 9.0 и выше, а также Google Chrome).
Как легко догадаться, из canvas изображение поточечно считывается, каждая точка представляется как символ, и полученная строка выполняется как JavaScript.
Уровень сжатия кода таким способом колеблется в условных пределах от 20 до 50%. Например, библиотека jQuery версии 1.2.3 сжимается с 53КБ до 17, что экономит 32% (для сравнения gzip сжимает е? до 15,5Кб, bzip2 — до 14,6КБ).
Особенно привлекательно в этом методе то, что часть JavaScript,ответственная за получение кода на стороне клиента, очень небольшая:
var codeimg = new Image()
// когда картинка загрузится, вызовется эта функция
codeimg.onload = function () {
var code = '' // переменная, куда будет собираться код
var size = 119 // размер изображения (оно квадратное)
var canvas = document.createElement("canvas")
canvas.width = canvas.height =
canvas.style.width = canvas.style.height = size
var inner = canvas.getContext("2d")
// загружаем изображение в созданный нами CANVAS
inner.drawImage(codeimg)
// забираем содержимое и переводим его в символы
var data = inner.getImageData(0, 0, size, size)
for (var i = 0, len = data.length; i<len; i+=4) {
if (data[i] > 0) code += String.fromCharCode(data[i])
}
eval(code)
}
// указываем URL изображения, где у нас хранится код
codeimg.src = 'image-with-our-code.png'
Серверная часть также очень проста, реализацию на PHP можно посмотреть в блоге автора метода, также просто она реализуется на любом другом языке — в квадратное изображение, сторона которого равна квадратному корню из значения длины файла, в каждую точку ставится по коду символа из передаваемого контента.
Таким же методом можно паковать и CSS — в конце вместо eval нужно просто создать в DOM тег style с соответствующим содержимым.
Само изображение, получающееся в результате, ничего интересного не представляет — обычный бинарный шум.

Рис. 2.1. Библиотека Prototype (версия 1.6.0.2), сжатая до 30КБ PNG (экономия 24%)
У метода есть и недостатки. Во-первых, автор не использует цветовую составляющую для передачи каких-либо данных, тут есть простор для экспериментов. Во-вторых, на текущий момент, распаковка средних по размеру (200—500 КБ) данных занимает несколько секунд В-третьих, метод поддерживается не всеми браузерами (например, не поддерживается IE). И, в-четв?ртых, автор не позаботился о поддержке UTF-8 (что, впрочем, можно исправить).
Поскольку общее время, через которое скрипт будет доступен равно сумме времени загрузки и времени, потраченного на его распаковку, нужно очень внимательно относиться к использованию этого метода — возможно, результатом его применения станет лишь увеличение времени ожидания.
Не исключено, что ситуацию может исправить использования цветовых компонент изображения. В этом случае, размер передаваемых (а значит и обрабатываемых скриптом) данных должен уменьшиться.