Подтвердить что ты не робот

Хорошие ресурсы для экстремального мини-JavaScript (js1k-style)

Как я уверен, большинство разработчиков JavaScript знают, что есть новый рождественский js1k. Я планирую войти в это время, но у меня нет опыта в создании такого мини-кода. Кто-нибудь знает хорошие ресурсы для такого рода вещей?

4b9b3361

Ответ 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, вам должно быть тривиально узнать, какие все трюки они применяют.

Но в конце концов все сводится к тому, можно ли найти интеллектуальное маленькое решение для чего-то такого.

Ответ 6

Друг написал jscrush упаковщик для js1k.

Имейте в виду, чтобы максимально сохранить код, похожий на код.

Мой рабочий процесс для экстремальной упаковки: закрытие (красивая печать) → оптимизация рук, сходство функций, другое сходство кода → закрытие (только пробелы) → jscrush.

Это упаковывает около 25% данных.

Там также packify, но я сам этого не тестировал.

Ответ 7

Это единственная онлайн-версия @cowboy packer script:

http://iwantaneff.in/packer/

Очень удобно для упаковки/минирования JS