Хорошие ресурсы для экстремального мини-JavaScript (js1k-style)
Как я уверен, большинство разработчиков JavaScript знают, что есть новый рождественский js1k. Я планирую войти в это время, но у меня нет опыта в создании такого мини-кода. Кто-нибудь знает хорошие ресурсы для такого рода вещей?
Ответы
Ответ 1
Google Closure Compiler является хорошим javascript minifier.
Для быстрого использования существует хороший онлайн-инструмент, или вы можете загрузить этот инструмент и запустить его как часть процесса сборки веб-сайта.
Изменить: Добавлен неисчерпывающий список трюков, которые вы можете использовать для чрезвычайно тщательного исключения JavaScript, прежде чем использовать minifier:
Сократить длинные имена переменных
Используйте сокращенные ссылки на встроенные переменные типа d=document;w=window
.
Установить интервал
Функция setInterval
может принимать либо функцию, либо строку. Передайте строку, чтобы уменьшить количество используемых символов: setInterval('a--;b++',10)
. Обратите внимание, что передача в строке принудительно вызывает eval invokation, поэтому она будет медленнее, чем передача функции.
Сокращение математических расчетов
Пример a=b+b+b
можно уменьшить до a=3*b
.
Использовать научную нотацию
10000
может быть выражен в научной нотации как 1E4
с сохранением 2 байтов.
Перемещение ведущих нулей
0.2 = .2
сохраняет байты
Оператор Тернери
if (a > b) {
result = x;
}
else {
result = y;
}
может быть выражена как result=a>b?x:y
Короткие брекеты
Скобки необходимы только для блоков из более чем одного оператора.
Приоритет оператора
Положитесь на приоритет оператора, а не на добавление ненужных скобок, которые помогают читать код.
Сократить назначение переменных
Вместо function x(){a=1,b=2;...}()
передать значения в функцию, function x(a,b){...}(1,2)
Подумайте нестандартно
Не допускайте автоматического достижения стандартных способов выполнения действий. Вместо использования d.getElementById('p')
для получения ссылки на элемент DOM вы можете использовать b.children[4]
где d=document;b=body
.
Исходный источник для приведенного выше списка трюков:
http://thingsinjars.com/post/293/the-quest-for-extreme-javascript-minification/
Ответ 2
Сполто прав.
Любой код minifier не будет делать трюк в одиночку. Сначала вам нужно оптимизировать свой код, а затем сделать некоторые грязные ручные настройки.
В дополнение к списку трюков Spolto я хочу поощрять использование логических операторов вместо классического синтаксиса if
else
. например:
Следующий код
if(condition){
exp1;
}else{
exp2;
}
несколько эквивалентен
condition&&exp1||exp2;
Еще одна вещь, которую следует учитывать, - это объявление нескольких переменных:
var a = 1;var b = 2;var c = 1;
можно переписать как:
var a=c=1,b=2;
Сполто также прав о фигурных скобках. Вы должны бросить их. Но, кроме того, вы должны знать, что их можно отбросить даже для блоков большего числа выражений, написав выражения, разделенные запятой (с ведущим ;, конечно):
if(condition){
exp1;
exp2;
exp3;
}else{
exp4;
exp5;
}
Можно переписать как:
if(condition)exp1,exp2,exp3;
else exp4,exp5;
Хотя это не так много (это экономит вам только 1 символ/блок для тех, кто считает), это может пригодиться. (Кстати, последний компилятор Google Closure тоже делает этот трюк).
Другим обманом, заслуживающим упоминания, является спорная функциональность with
.
Если вам больше нужна информация о размере, вы должны использовать это, потому что это может уменьшить размер кода.
Например, рассмотрим этот метод объекта:
object.method=function(){
this.a=this.b;
this.c++;
this.d(this.e);
}
Это можно переписать как:
object.method=function(){
with(this){
a=b;
c++;
d(e);
}
}
который в большинстве случаев значительно меньше.
Что-то, чего не делают большинство упаковщиков кода и minifiers, это замена больших повторяющихся токенов в коде меньшими. Это неприятный взлом, который также требует использования eval
, но поскольку мы находимся в нем для пространства, я не думаю, что это должно быть проблемой. Скажем, у вас есть этот код:
a=function(){/*code here*/};
b=function(){/*code here*/};
c=function(){/*code here*/};
/*...*/
z=function(){/*code here*/};
В этом коде много повторяющихся ключевых слов функции. Что делать, если вы можете заменить их одним (неиспользуемым) символом, а затем оценить код?
Вот как я это сделаю:
eval('a=F(){/*codehere*/};b=F(){/*codehere*/};c=F(){/*codehere*/};/*...*/z=F(){/*codehere*/};'.replace(/function/g,'F'));
Конечно, замененный токен может быть любым, так как наш код сводится к оцениваемой строке (например: мы могли бы заменить = function() {с помощью F, тем самым сохраняя еще больше символов).
Обратите внимание, что эту технику следует использовать с осторожностью, потому что вы можете легко испортить свой код несколькими текстовыми заменами; кроме того, вы должны использовать его только в тех случаях, когда это помогает (например: если у вас есть только теги 4 функции, заменяя их меньшим токеном, а затем оценивая код, возможно, на самом деле увеличить длину кода:
var a = "eval(''.replace(/function/g,'F'))".length,
b = ('function'.length-'F'.length)*4;
alert("you should" + (a<b?"":" NOT") + " use this technique!");
Ответ 3
В следующей ссылке вы найдете удивительно хорошие трюки, чтобы минимизировать js-код для этого соревнования:
http://www.claudiocc.com/javascript-golfing/
Один пример: (извлечен из раздела Операторы коротких замыканий):
if (p) p=q; // before
p=p&&q; // after
if (!p) p=q; // before
p=p||q; // after
Или более эзотерический хэш-хэш-трюк:
// before
a.beginPath
a.fillRect
a.lineTo
a.stroke
a.transform
a.arc
// after
for(Z in a)a[Z[0]+(Z[6]||Z[2])]=a[Z];
a.ba
a.fc
a.ln
a.sr
a.to
a.ac
И вот еще одна ссылка на ресурс с удивительно хорошими трюками: https://github.com/jed/140bytes/wiki/Byte-saving-techniques
Ответ 4
Прежде всего, просто бросать свой код в minifier вам не поможет. Когда вы пишете код, вам нужно иметь крайне малый размер файла. Поэтому, частично, вам нужно изучить все трюки самостоятельно.
Кроме того, когда речь заходит о minifiers, UglifyJS является новой звездой для съемки, ее выход меньше, чем GCC, и это быстрее. И так как это написано в чистом JavaScript, вам должно быть тривиально узнать, какие все трюки они применяют.
Но в конце концов все сводится к тому, можно ли найти интеллектуальное маленькое решение для чего-то такого.
Ответ 5
также:
Декан Эдвардс
http://dean.edwards.name/packer/
Uglify JS
http://marijnhaverbeke.nl/uglifyjs
Ответ 6
Друг написал jscrush упаковщик для js1k.
Имейте в виду, чтобы максимально сохранить код, похожий на код.
Мой рабочий процесс для экстремальной упаковки: закрытие (красивая печать) → оптимизация рук, сходство функций, другое сходство кода → закрытие (только пробелы) → jscrush.
Это упаковывает около 25% данных.
Там также packify, но я сам этого не тестировал.
Ответ 7
Это единственная онлайн-версия @cowboy packer script:
http://iwantaneff.in/packer/
Очень удобно для упаковки/минирования JS