Как "минимизировать" код Javascript

100

У JQuery есть две версии для загрузки, одна из которых - производственная (19 КБ, минифицированная и сжатая с помощью Gzip). , а другая - разработка (120 КБ, несжатый код) .

Теперь компактная версия 19kb, если вы ее загрузите, вы увидите, что это все еще исполняемый код javascript. Как они его компактифицировали? И как я могу таким образом «минимизировать» свой код?

KalEl
источник
1
В частности, есть ли какая-нибудь онлайн-утилита, которая позволяет мне это делать?
KalEl
2
Я наткнулся на этот старый пост с теми же вопросами, так что хороший вопрос! Немного полезной базовой информации: thiscouldbeuseful.com/2012/09/minified-js-for-beginners.html .
Aries51

Ответы:

49

Минификация своими руками

Ни один минификатор не может правильно сжать плохой код.

В этом примере я просто хочу показать, насколько много работает минификатор.

Что вам следует сделать перед минимизацией

А что касается jQuery ... я не использую jQuery. JQuery предназначен для старых браузеров, это было сделано из соображений совместимости ... проверьте caniuse.com, почти все работает в каждом браузере (также ie10 стандартизирован сейчас), я думаю, теперь это просто здесь, чтобы замедлить работу вашего веб-приложения ... если вам нравится, $()вы должны создать свою собственную простую функцию. И зачем беспокоиться о сжатии вашего кода, если вашим клиентам нужно постоянно загружать скрипт jquery размером 100 КБ? насколько велик ваш несжатый код? 5-6кб ..? Не говоря уже о множестве плагинов, которые вы добавляете, чтобы упростить задачу.

Исходный код

Когда вы пишете функцию, у вас есть идея, начинаете писать, и иногда вы получаете что-то вроде следующего кода. Код работает. Теперь большинство людей перестают думать, добавляют это в минификатор и публикуют.

function myFunction(myNumber){
     var myArray = new Array(myNumber);
     var myObject = new Object();
     var myArray2 = new Array();
     for(var myCounter = 0 ; myCounter < myArray.length ; myCounter++){
         myArray2.push(myCounter);
         var myString = myCounter.toString()
         myObject[ myString ] = ( myCounter + 1 ).toString();
     }
    var myContainer = new Array();
    myContainer[0] = myArray2;
    myContainer[1] = myObject;
    return myContainer;
}

Вот уменьшенный код (я добавил новые строки)

Минифицировано с использованием ( http://javascript-minifier.com/ )

function myFunction(r){
 for(var n=new Array(r),t=new Object,e=new Array,a=0;a<n.length;a++){
  e.push(a);
  var o=a.toString();
  t[o]=(a+1).toString()
 }
 var i=new Array;
 return i[0]=e,i[1]=t,i
}

Но нужны ли все эти переменные, if, циклы и определения?

В большинстве случаев НЕТ !

  1. Удалите ненужные if, loop, var
  2. Сохраните копию исходного кода
  3. Используйте минификатор

ДОПОЛНИТЕЛЬНО (увеличивает производительность и короче код)

  1. используйте сокращенные операторы
  2. использовать побитовые операторы (не использовать Math)
  3. используйте a, b, c ... для ваших временных переменных
  4. используйте старый синтаксис ( while, for... не forEach)
  5. использовать аргументы функции в качестве заполнителя (в некоторых случаях)
  6. удалить ненужное "{}","()",";",spaces,newlines
  7. Используйте минификатор

Теперь, если минификатор может сжать код, вы делаете это неправильно.

Ни один минификатор не может правильно сжать плохой код.

Сделай сам

function myFunction(a,b,c){
 for(b=[],c={};a--;)b[a]=a,c[a]=a+1+'';
 return[b,c]
}

Он делает то же самое, что и коды выше.

Производительность

http://jsperf.com/diyminify

Всегда нужно думать о том, что вам нужно:

Прежде чем вы скажете: «Никто не будет писать код, подобный приведенному ниже», проверьте первые 10 вопросов здесь ...

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

Хотите многоразовое состояние

if(condition=='true'){
 var isTrue=true;
}else{
 var isTrue=false;
}
//same as
var isTrue=!!condition

Предупреждать да, только если он существует

if(condition==true){
 var isTrue=true;
}else{
 var isTrue=false;
}
if(isTrue){
 alert('yes');
}
//same as
!condition||alert('yes')
//if the condition is not true alert yes

Предупреждать да или нет

if(condition==true){
 var isTrue=true;
}else{
 var isTrue=false;
}
if(isTrue){
 alert('yes');
}else{
 alert('no');
}
//same as
alert(condition?'yes':'no')
//if the condition is true alert yes else no

Преобразование числа в строку или наоборот

var a=10;
var b=a.toString();
var c=parseFloat(b)
//same as
var a=10,b,c;
b=a+'';
c=b*1

//shorter
var a=10;
a+='';//String
a*=1;//Number

Округлить число

var a=10.3899845
var b=Math.round(a);
//same as
var b=(a+.5)|0;//numbers up to 10 decimal digits (32bit)

Этаж номер

var a=10.3899845
var b=Math.floor(a);
//same as
var b=a|0;//numbers up to 10 decimal digits (32bit)

переключатель случае

switch(n)
{
case 1:
  alert('1');
  break;
case 2:
  alert('2');
  break;
default:
  alert('3');
}

//same as
var a=[1,2];
alert(a[n-1]||3);

//same as
var a={'1':1,'2':2};
alert(a[n]||3);

//shorter
alert([1,2][n-1]||3);
//or
alert([1,2][--n]||3);

попробуй поймать

if(a&&a[b]&&a[b][c]&&a[b][c][d]&&a[b][c][d][e]){
 console.log(a[b][c][d][e]);
}

//this is probably the onle time you should use try catch
var x;
try{x=a.b.c.d.e}catch(e){}
!x||conole.log(x);

больше, если

if(a==1||a==3||a==5||a==8||a==9){
 console.log('yes')
}else{
 console.log('no');
}

console.log([1,3,5,8,9].indexOf(a)!=-1?'yes':'no');

но indexOfмедленно, прочтите это https://stackoverflow.com/a/30335438/2450730

числа

1000000000000
//same as
1e12

var oneDayInMS=1000*60*60*24;
//same as
var oneDayInMS=864e5;

var a=10;
a=1+a;
a=a*2;
//same as
a=++a*2;

Несколько хороших статей / сайтов о побитовых / сокращенных записях, которые я нашел:

http://mudcu.be/journal/2011/11/bitwise-gems-and-other-optimizations/

http://www.140byt.es/

http://www.jquery4u.com/javascript/shorthand-javascript-techniques/

Есть также много сайтов jsperf, показывающих производительность сокращений и битвси, если вы выполняете поиск с помощью своего любимого поискового движка.

Я мог бы заниматься одним часами .. но думаю, что пока этого достаточно.

если есть вопросы, просто задавайте.

И помни

Ни один минификатор не может правильно сжать плохой код.

кокко
источник
30
Вряд ли есть смысл вручную минимизировать код. Напишите код, который будет легко понять другим разработчикам (или вам, через 10 месяцев). Да, лучше проще. Используйте мини-файл в автоматизированном процессе сборки, который сохраняет оригинал. Почти в каждом случае любой выигрыш в скорости от ручной оптимизации намного перевешивается затратами разработчиков на расшифровку минифицированного кода.
alttag
4
зависит от того, что вы делаете. если вы работаете с анимацией / холстом, например, с огромными наборами данных и манипуляциями с файлами, быстрый код очень важен, особенно на мобильных устройствах ... Дело в том, что некоторым разработчикам его трудно читать. да ... я пишу код, так как Pentium 2 ... так что, вероятно, 1998 год, я могу читать код, и, по моему опыту, у меня меньше кода для проверки на наличие ошибок. А насчет скорости ... э-э, вы ошиблись. Повышение производительности с помощью побитового / и сокращения сложных функций - это безумие. Особенно тестирование на различных устройствах / браузерах. Используйте сокращенный побитовый javascript Google, и вы найдете много примеров
cocco
Вернемся к вашему примеру округления: (10.4899845 +.5)|0результат 10 вместо 11.
DanMan
Код DIY только что был добавлен в мой "чрезмерно оптимизированный" файл. Он НЕ делает в точности то, что делает исходный код, когда предоставляется значение меньше нуля (myNumber или a). Исходный код вызывает исключение, а «улучшенный» код переходит в бесконечный цикл.
Дональд Рич
Это звучит как плохой совет с точки зрения поддержки
donkz
10

Google только что предоставил компилятор javascript, который может минимизировать ваш код, исключить мертвые ветки кода и другие оптимизации.

компилятор google javascript

С уважением,
K

Khb
источник
3

Наряду с уменьшением вы также можете кодировать его в base64. Это делает ваш файл более сжатым. Я уверен, что вы видели файлы js, которые заключены в функцию eval () с переданными параметрами (p, a, c, k, e, r). Я прочитал об этом в статье Как уменьшить размер файла Javascript?

Варг
источник
Кодирование base64 не сжимает ваш код, он делает с точностью до наоборот, вы получаете больше символов. Вы можете LZH сжать свою строку, кто-то создал JS-скрипт на github, который выполняет LZH-сжатие для строк с именем: lz-string, вы можете использовать это для сжатия своего кода: pieroxy.net/blog/pages/lz-string/index.html
beliha
3

Я написал крошечный скрипт, который вызывает API для минимизации вашего скрипта, проверьте его:

#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use Fcntl;

my %api = ( css => 'https://cssminifier.com/raw', js => 'https://javascript-minifier.com/raw' );

my $DEBUG = 0;

my @files = @ARGV;

unless ( scalar(@files) ) {
    die("Filename(s) not specified");
}

my $ua = LWP::UserAgent->new;

foreach my $file (@files) {
    unless ( -f $file ) {
        warn "Ooops!! $file not found...skipping";
        next;
    }

    my ($extn) = $file =~ /\.([a-z]+)/;

    unless ( defined($extn) && exists( $api{$extn} ) ) {
        warn "type not supported...$file...skipping...";
        next;
    }

    warn "Extn: $extn, API: " . $api{$extn};

    my $data;

    sysopen( my $fh, $file, O_RDONLY );
    sysread( $fh, $data, -s $file );
    close($fh);

    my $output_filename;

    if ( $file =~ /^([^\/]+)\.([a-z]+)$/ ) {
        $output_filename = "$1.min.$2";
    }

    my $resp = $ua->post( $api{$extn}, { input => $data } );

    if ( $resp->is_success ) {
        my $resp_data = $resp->content;
        print $resp_data if ($DEBUG);
        print "\nOutput: $output_filename";

        sysopen( my $fh, $output_filename, O_CREAT | O_WRONLY | O_TRUNC );
        if ( my $sz_wr = syswrite( $fh, $resp_data ) ) {
            print "\nOuput written $sz_wr bytes\n";
            my $sz_org = -s $file;

            printf( "Size reduction %.02f%%\n\n", ( ( $sz_org - $sz_wr ) / $sz_org ) * 100 );
        }   
        close($fh);
    }
    else {
      warn: "Error: $file : " . $resp->status_line;
    }
}

Использование:

./minifier.pl a.js c.css b.js cc.css t.js j.js [..]
Pradeep
источник
1

Недавно мне нужно было выполнить ту же задачу. Хотя компрессоры, перечисленные в JavaScript CompressorRater , отлично справляются со своей задачей, а инструмент очень полезен, они не очень хорошо справлялись с некоторым кодом jQuery, который я использую (проверки $ .getScript и jQuery.fn). Даже компрессор закрытия Google подавился теми же словами. Хотя в конечном итоге я мог бы сгладить изгибы, было слишком много щуриться, чтобы делать это постоянно.

Тот, который, наконец, работал без проблем, был UglifyJS (спасибо @ Aries51 ), и сжатие было лишь немного меньше, чем у всех остальных. И, как и в Google, у него есть HTTP API. Packer также хорош и имеет языковую реализацию на Perl, PHP и .NET.

Уэйн Вайбель
источник
1

В настоящее время есть 2 способа минимизировать ваш код:

  1. вы применяете минификаторы на бэкэнд-стороне вашего приложения - здесь преимущество состоит в том, что вы можете применять управление версиями и лучше контролировать свой код - вы можете практически полностью автоматизировать процесс минификации, и лучше всего применять его до того, как ваш код будет загружены на сервер - это лучше всего использовать, когда у вас много внешнего (подлежащего минимизации) кода Javascript и CSS:

http://yui.github.io/yuicompressor/

Многие такие инструменты также доступны для Node и npm - это хорошая практика - автоматизировать унификацию Javascript с помощью Grunt.

  1. вы можете использовать некоторые из существующих бесплатных инструментов для минификации, которые работают онлайн - они практически позволяют вам делать то же самое, но вручную. Я бы посоветовал вам использовать их, когда объем вашего кода javascript / css меньше - не много файлов

http://www.modify-anything.com/

ПитерСиний
источник
0

Вы можете использовать javascript- минификатор ubercompute.com для минимизации вашего кода, он уменьшит ваш javascript-код до 75% от их исходной версии.

Абхишек Сингх
источник
0

Если вы используете редактор VSCode, доступно множество плагинов / расширений.

MinifyAll, Например , это очень хороший один - совместим со многими расширения.

Установите его и перезагрузите VSCode. Затем щелкните свой файл, откройте палитру команд ( Ctrl+Shift+p), введите «minify this document» ( Ctrl+alt+m), другие доступные параметры, такие как сохранить исходный документ и так далее! Легко!

ДЭВИД АДЖАИ
источник