Сжатие JavaScript с использованием PNG и Canvas
Jacob Seidelin в своём блоге «Nihilogic» опубликовал небезынтересную статью, где он рассказывает о своих экспериментах по сжатию кода JavaScript при помощи Canvas и PNG.
Идея простая, из разряда «как мне раньше не пришло это в голову». JavaScript переводится в последовательность байт, которая записывается как изображение. Изображение сохраняется в PNG-формате, в PNG используется довольно эффективное сжатие, что даже при расходах на заголовок даёт ощутимые результаты — известная библиотека Prototype (124 килобайта) стала занимать всего 30 килобайт в восьмибитном PNG-файле. Каждый пиксель в 24-битном PNG позволяет хранить три байта информации, в 8-битном формате — один.
Далее PNG-изображение загружается в тег CANVAS (нужный функционал поддерживается FireFox, WebKit/Safari и бета-версией «Оперы») и считывается попиксельно функцией getImageData, после чего полученный код выполняется (eval) и мы получаем исходный JavaScript.
Единственный недостаток метода — скорость. Извлечение скрипта в 255Кб может занять несколько секунд, что, впрочем, не всегда является проблемой.
ты уверен, что deflate сжимает хуже? ;)
Это из разряда brain fuck что-то... практической ценности не вижу =)
Комментарий для indeyets.livejournal.com:
Так же. Был бы он ещё везде, этот deflate :)
Комментарий для romik-g.livejournal.com:
Всё просто — сжимать JavaScript.
Бред!
А LZW на JS еще никто не реализовал?
Комментарий для Евгения Степанищева:
Сжимать JavaScript... А зачем его сжимать таким способом?
Какие преимущества несёт данный способ перед обычным gzip/deflate-сжатием?
Комментарий для slaver.info:
ага :)
Комментарий для bealex.livejournal.com:
Медленно, думаю, будет :)
Комментарий для victorgr.livejournal.com:
Во-первых, это способ из разряда «а ещё вот так можно», т. е. практического применения, возможно, у него никакого :)
Во-вторвых, на хостингах, где нет сжатия файлов и не подключены языки программирования, это выход.
«В PNG используется довольно эффективное сжатие» — да, только эффективно оно для изображений (то есть, предполагается что соседние писели не сильно отличаются и т. п.). Битовый «шум», полученный из JS, сожмётся не лучше чем простым гзипом. Что мы, вероятнее всего и наблюдаем.
Хотя конечно, сама идея, что и так тоже можно выпендриться — она внушаетъ:)
Комментарий для david-m.livejournal.com:
PNG использует тот же deflate, который в gzip :)
Феерично. Наверняка эта возможность будет проверяться в ACID4 :)
И где это его нет?
Сделал страницу
http://maxim.rusf.ru/cmp.html
проверил во всех доступных мне в 3 часа ночи браузерах, работает везде кроме Netscape 3.04/Linux (есть такое чудо у меня).
Linux:
Firefox 1.0
Firefox 2.0
Opera 9.1
Windows XP:
MSIE 6.0
Opera 9.0
Windows Vista:
MSIE 7.0
Windows CE (КПК то бишь):
MSIE 4.0
Телефон Nokia 6300:
Какой безымянный встроенный браузер
Opera Mini 4.0
Есть у вас что-то, не аналогичное по идиотизму 3-му Нетскейпу, где на <a href=» http://maxim.rusf.ru/cmp.html%22%3E%D1%8D%D1%82%D0%BE%D0%B9 странице</a> не выдалось бы «OK, gzipped JS is supported»?
Комментарий для Евгения Степанищева:
Зачем для выкладывания файла script.js.gz нужны какие-то там языки программирования или «сжатие файлов на хостинге»?
Комментарий для maxim-zotov.livejournal.com:
Не в браузерах его нет, а на хостингах может и не быть.
Комментарий для maxim-zotov.livejournal.com:
Для этого .gz должен быть прописан заголовок content-encoding и правильный content-type.
Комментарий для Евгения Степанищева:
Корректная выдача заголовков для gz и тип для js прописаны в конфигах «из коробки» в самом массовом сервере — Апаче. Нужно специально приложить усилия, чтобы _не_ работало, а не дополнительно настраивать, чтобы работало.
Может быть, конечно, вебмастера сначала выкидывают всё из конфига, а потом начинают по строчке добавлять, не знаю.
Комментарий для maxim-zotov.livejournal.com:
Многим нужно чтобы файлы .gz просто скачивались, а не распаковывались в браузер. Так как это — просто архивы в одном из распространённых форматов во всяких Линуксах.
Кроме того, я не защищаю этот метод. Мне он просто нравится, он остроумен.
Комментарий для maxim-zotov.livejournal.com:
Не работает:
Browser: Mozilla/5.0 (compatible; Konqueror/3.5; FreeBSD; X11; i386; en_US, ru) KHTML/3.5.8 (like Gecko)
Result: external script is not loaded
Комментарий для shoorick.livejournal.com:
А разве где-то написано, что под KHTML будет работать?
Комментарий для shoorick.livejournal.com:
«Не работает:»
Жаль.
Комментарий для Евгения Степанищева:
«А разве где-то написано»
Да, я считал, что script.js.gz сработает в любом современном браузере.
Комментарий для Евгения Степанищева:
«Многим нужно чтобы файлы .gz просто скачивались, а не распаковывались в браузер. Так как это — просто архивы в одном из распространённых форматов во всяких Линуксах.»
Если то, что сжато гзипом, не должно отображаться в браузере, оно не отобразится. gzip — это не формат архива, это формат сжатия. Архив (набор файлов) — это tar. У файлов tar mime-тип application/x-tar, поэтому он не отображается, а скачивается.
Если вы сжимаете файл html или txt, то он, разумеется, отобразится. И было бы очень нелогично, если бы не отображалось, а скачивалось. Это ведь html и текст, с какой стати оно должно скачиваться?
Если человек выкидывает из конфига веб-сервера поддержку content-encoding gzip’а, скорее всего, он не понимает, что делает, и пытается добиться какого-то своего результата неправильным способом.
Комментарий для maxim-zotov.livejournal.com:
Я знаю всё про gzip, tar и MIME-заголовки. Я же хакер.
Не вижу ничего нелогичного в том, что .html.gz или .txt.gz должен скачиваться, а не распаковываться. Если я указываю браузеру, что файл должен скачаться, я знаю что я делаю. Значит этот txt или html не предназначен для того, чтобы читать его из браузера, например, там очень большой текст, который 99% скачает и откроет на PDA/телефоне/любом наладонном устройстве.
Комментарий для bealex.livejournal.com:
Реализовали :)
Комментарий для Евгения Степанищева:
Хех, скорость ответа — пять баллов.
А насколько оно адекватно? В смысле, например, крупных AJAX-ответов? Тестов не было? Или просто блочный lzw передавать в условиях потоковой передачи… не?
/Перечитал — какой-то бред несу, но пускай остается для потомков/
Комментарий для bealex.moikrug.ru:
Ага узнал, так и сообщил :))
Оно вполне адекватно и хорошо сжимает. Но есть загвоздка — скорость распаковки даже какого-нибудь prototype (чуть больше 100КБ) может достигнуть секунд под не шустром браузером на не шустром ноуте.
Комментарий для Евгения Степанищева:
То есть в идеале надо бы анализировать скорость ответа (соединения) и в зависимости от нее — выбирать тот или иной способ упаковки… Да еще и зависимость получается нелинейная. Дамс, проще забить. :) Но сама мысля — интересна.
Это не единственный недостаток, ie только с 9-ого поддерживает canvas.
А так очень эффективный способ сжатия.
Спасибо за материал. А я вот так автоматизировал процесс сжатия — http://plutov.by/post/js_css_auto_compress
Комментарий для http://plutov.by:
А почему вы не используете что-нибудь готовое? Например: http://gruntjs.com