Как «минимизировать» код Javascript - PullRequest
95 голосов
/ 15 ноября 2009

JQuery имеет две версии для загрузки, одна из которых Production (19 КБ, сжатые и сжатые) , а другая Разработка (120 КБ, несжатый код) .

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

Ответы [ 7 ]

45 голосов
/ 25 января 2014

DIY Минификация

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

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

Что вы должны сделать перед минификацией

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

Оригинальный код

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

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
}

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

Большую часть времени НЕТ !

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

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

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

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

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

DIY

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, показывающих производительность сокращений и bitwsie, если вы выполняете поиск с помощью вашего любимого поисковика.

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

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

И помните

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

35 голосов
/ 15 ноября 2009

Вы можете использовать один из множества доступных миниатюр javascript.

9 голосов
/ 15 ноября 2009

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

Google javascript compiler

Привет
K

3 голосов
/ 29 ноября 2015

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

2 голосов
/ 14 октября 2017

Я написал крошечный скрипт, который вызывает 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 [..]
1 голос
/ 01 марта 2016

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

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

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

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

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

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

1 голос
/ 09 сентября 2013

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...