Comments 48
UFO just landed and posted this here
А почему делать можно только через замыкание?
Приемы ручного сжатия напомнили, как мы участвовали в Time Limit Exceeded — индийский контест на решение задач на C так, чтобы программа получалась минимальной длины. Славно мы тогда поизвратились, я о C столько нового узнала :-)
Вообще можно ещё код сжать в png. Загрузчик кода из png, разумеется, тоже нужен будет, но размер таким образом можно уменьшить, например, и со 123 кб до 30 кб (как показывает практика). :)
загрузчик под килобайт вроде весит
Я загрузчик ужимал до минимума: bolknote.ru/files/tank-1k-game/
1 кб? С загрузчиком? Браво! :)
Здорово — распаковщик в 109 байт + 90 байт накладных расходов. Правда этот подход в таком виде в каком есть не годится для js1k (запрещены внешние ресурсы). Если создавать картинку с image:data, то получим +30-40% к весу картинки. И не понятно будет ли оправдано это.
Вобщем прикинул: у вас картинка весит 753 байта, а кода в ней на 1059 (хотя я думал там будет 1059*4 байт ибо RGBA, почему вы брали каждый 4-й элемент, храните ещё что-то в RGB?). С data:image мы получим около 1054 байт + 100 байт распаковщик (можно оптимизировать если точить под js1k). Если занимать все пространство RGBA, то минимизированный скрипт можно ужать ещё в 5-6 раз!
Имея картинку в 650 байт (910 image:data) в неё можно засунуть около 3640 байт ужатого скрипта. Плюс 100 байт оптимизированный под js1k распаковщик. В сумме получим 1010 байт чистого кода, который теоретически должен развернуться до 3640 байт.
Поправьте если что не так.
Вобщем прикинул: у вас картинка весит 753 байта, а кода в ней на 1059 (хотя я думал там будет 1059*4 байт ибо RGBA, почему вы брали каждый 4-й элемент, храните ещё что-то в RGB?). С data:image мы получим около 1054 байт + 100 байт распаковщик (можно оптимизировать если точить под js1k). Если занимать все пространство RGBA, то минимизированный скрипт можно ужать ещё в 5-6 раз!
Имея картинку в 650 байт (910 image:data) в неё можно засунуть около 3640 байт ужатого скрипта. Плюс 100 байт оптимизированный под js1k распаковщик. В сумме получим 1010 байт чистого кода, который теоретически должен развернуться до 3640 байт.
Поправьте если что не так.
Есть вариант без внешних ресурсов :) bolknote.ru/files/tank-1k-game-2/ (правда, я знаю как его ещё уменьшить).
Вобщем прикинул: у вас картинка весит 753 байта, а кода в ней на 1059 (хотя я думал там будет 1059*4 байт ибо RGBA, почему вы брали каждый 4-й элемент, храните ещё что-то в RGB?)Я вообще хотел класть во все четыре компоненты, но сжимается лучше всего выбранный вариант.
Напомнило (если кто-то ещё не читал): www.wasm.ru/article.php?article=onebyte
var a='lineTo';c[a](150,150);c[a](150,200);c[a](150,250);c[a](250,350);c[a](450,350);c[a='lineTo'](150,150);c[a](150,200);c[a](150,250);c[a](250,350);c[a](450,350);
Вообще как-то негусто приёмов описано.
Все в ваших руках.
c[a='lineTo'](150,150);c[a](150,200);c[a](150,250);c[a](250,350);c[a](450,350);
l=c.lineTo;l(150,150);l(150,200);l(150,250);l(250,350);l(450,350);
Серёг, или я торможу или lineTo получит в this window.
var a=z.lineTo.bind(z);a(150,150);
;)попробуйте для сжатия compressorrater.thruhere.net/ для меня там лучшим оказался Packer (Version 3.1) + допиливаю руками названия функций которые он не умеет сжимать. в моем случае Packer оказался на 10% лучше UglifyJS. Пишу тетрис. Пытаюсь затолкать 2048 байт. осталось еще 100 байт срезать, уж не знаю где еще :)
Туда бы для сравнения UglifyJS добавить и GCC.
habrahabr.ru/blogs/javascript/115369/#comment_3736982
habrahabr.ru/blogs/javascript/115369/#comment_3736982
или я чегото не понял, или обясните мне: почему не использовали gcc? он очень качественно все делает и Вам бы не пришлось почти ничего оптимизировать руками. Почему о нем нету ни слова?
GCC умеет работать с JavaScript?
ага, code.google.com/closure/
Куча опций оптимизаций, сам сжимаю только им — по анализам, вроде самый оптимальный
Куча опций оптимизаций, сам сжимаю только им — по анализам, вроде самый оптимальный
GCC Advanced=on сжал мой скрипт до 1100 байт, UglifyJS — 1048, Packer 3.1 — 1049. Притом Packer и GCC коверкают порядок переменных (d,g,f вместо a,b,c) и от обрамляющего замыкания невозможно сразу избавиться. Если вы в GCC пользуетесь особыми настройками, то посвятите.
Однако… Это не тот gcc, о котором все подумали :)
Вроде бы не нашел у вас совет такого рода:
Если часто используется какой либо метод, например Math, можно сократить код так:
var m = Math;
И вызывать, например, так: m.abs();
Возможно я туплю и glifyJS это все уже сам делает.
Если часто используется какой либо метод, например Math, можно сократить код так:
var m = Math;
И вызывать, например, так: m.abs();
Возможно я туплю и glifyJS это все уже сам делает.
9. Замените циклы for на while, избавьтесь от оптимизаций счетчиков c = smth.lengthПотом замените while на for и получите ещё N байт ;)
i=smth.length;while(i--)do(i);
for(i=smth.length;i--;)do(i);
13. Удалите двойные и одинарные кавычки из атрибутов вашего HTML кода <div id=«aaa»> — <div a=aaa>
14. Замените строки в id элементов на числа <div id=aaa> — <div a=1>
Почему бы не создавать собственные элементы? Например,
<r>
. Вроде бы и html короче и путь в querySelectorAll
. Конечно, с канвасом так не выйдет.Кстати, иногда имеет смысл сделать подобную оптимизацию:
Особенно в паре с другими оптимизациями:
И, особо, при использовании длинных повторяющихся названий:
__fillStyle__ = 'fillStyle',
__fillRect__ = 'fillRect',
// =>
__fill__ = 'fill',
__fillStyle__ = __fill__ + 'Style',
__fillRect__ = __fill__ + 'Rect'
Особенно в паре с другими оптимизациями:
__fillStyle__ = 'fillStyle',
__fillRect__ = 'fillRect',
// =>
__fill__ = 'fill',
__stroke__ = 'stroke',
__Style__ = 'Style',
__Rect__ = 'Rect',
__fillStyle__ = __fill__ + __Style__,
__fillRect__ = __fill__ + __Rect__,
__strokeStyle__ = __stroke__ + __Style__,
__strokeRect__ = __stroke__ + __Rect__,
И, особо, при использовании длинных повторяющихся названий:
__getElement__ = 'getElement',
__getElementById__ = __getElement__ + 'ById',
__getElementsByTagName__ = __getElement__ + 'sByTagName',
__getElementsByClassName__ = __getElement__ + 'sByClassName',
Ещё читал вариант, если необходимо использоваться сообственные функции, то лучше создать одну функцию, а внутри сделать ветвление зависимо от первого параметра.
function foo () {
// foo code
}
function bar () {
// bar code
}
function qux () {
// qux code
}
// =>
function g (fn) {
if (fn == 'foo') {
// foo code
}
if (fn == 'bar') {
// bar code
}
if (fn == 'qux') {
// qux code
}
}
Sign up to leave a comment.
JS1k — пишем отличное веб приложение в 1024 байт