Як "мінімізувати" код Javascript


99

JQuery має дві версії для завантаження, одна - виробництво (19 КБ, мінімізований та Gzipped) , а інша - розробка (120 КБ, нестиснений код) .

Тепер компактна версія 19 Кбіт, якщо ви її завантажите, ви побачите, що це все ще виконуваний код Javascript. Як вони це ущільнили? І як я можу так само "мінімізувати" свій код?


1
Тим більше, чи є якась онлайн-утиліта, яка дозволяє мені це робити?
KalEl

2
Я натрапив на цей старий пост з тими ж запитаннями, так добре запитання! Ось хороша основна інформація: thiscouldbeuseful.com/2012/09/minified-js-for-beginners.html .
Aries51

Відповіді:


48

Зроби сам

Жоден мініфікатор не може правильно стиснути неправильний код.

У цьому прикладі я просто хочу показати, наскільки працює мініфікатор.

Що слід зробити перед тим, як пом'якшити

Щодо jQuery ... я не використовую jQuery.jQuery для старих браузерів, він був зроблений з міркувань сумісності. Перевірте caniuse.com, майже все працює на кожному браузері (також ie10 зараз стандартизовано), я думаю, зараз це просто тут, щоб сповільнити веб-додаток ... якщо вам подобається, $()вам слід створити власну просту функцію. І навіщо турбуватися стискати свій код, якщо клієнтам потрібно щоразу завантажувати скрипт jquery 100kb? Наскільки великий ваш нестиснений код? 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
}

Але чи потрібні всі ці варіанти, ifs, циклі та визначення?

Більшість часу НІ !

  1. Видаліть зайве, якщо, петля, вар
  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

Перетворити число в рядок або в viceversa

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, якщо ви шукаєте улюблений пошук.

Я міг би їхати по годинах .. але я думаю, що цього зараз достатньо.

якщо у вас є якісь питання, просто задайте.

І пам’ятайте

Жоден мініфікатор не може правильно стиснути неправильний код.


30
Навряд чи є причина вручну мінімізувати код. Напишіть код, який легко зрозуміти іншим розробникам (або ви, через 10 місяців). Так, простіше - краще. Використовуйте мінімізований процес автоматизованого збирання, який зберігає оригінал. Майже в кожному випадку будь-які надбавки в швидкості від оптимізації рук набагато перевищують вартість розробників, що розшифровують мінімізований код.
alttag

4
залежить, що ти робиш. якщо ваша робота з анімацією / полотном, величезними наборами даних і маніпуляцією файлів, наприклад, швидкий код дуже важливий, особливо на мобільних пристроях ... справа в тому, що для деяких розробників важко читати. так ... я пишу код, оскільки pentium 2 .. тому, напевно, 1998 рік, я можу прочитати код, і за моїм досвідом у мене є менше коду, щоб перевірити наявність помилок. Підвищення продуктивності за допомогою побітових / та скорочень в складних функціях - це insane.expecial testing на різних пристроях / browsers.use google shorthandbitwise javascript, і ви знайдете багато прикладів
cocco

(10.4899845 +.5)|0
Перегляньте

Щойно доданий DIY-код до мого файлу "над оптимізованим". Він НЕ робить саме те, що робить оригінальний код, коли надається значення менше нуля (myNumber або a). Оригінальний код кидає виняток, і "покращений" код переходить у нескінченний цикл.
Дональд Річ

Це звучить як така погана порада з точки зору підтримки
donkz


10

Щойно компанія Google представила компілятор javascript, який може мінімізувати ваш код, усунути гілки мертвих кодів та більше оптимізацій.

Google компілятор JavaScript

З повагою
К


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
беліга

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 [..]

1

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

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


1

Наразі існує два способи мінімізації коду:

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

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

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

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

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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.