Blog webdeveloperski Patryk yarpo Jar

Minimalizacja kodu JS – JSMin

Autor wiadomości Kwiecień 7, 2011

Co zrobić, aby strona ładowała się szybciej? Sprawić, aby zajmowała mniej miejsca. Wydaje się oczywiste, a jednak bardzo wielu webdeveloperów [w tym często ja sam] ładuje internaucie pliki JS zawierające tonę komentarzy, spacji, enterów i innych białych znaków.

Dodatkowym problem jest nie tyle rozmiar strony, co mnogość requestów do serwera. 30 requestów, a każdy plik ma po 1kB danych. Jak to zmienić? W tym artykule zajmę się zmniejszeniem rozmiaru plików JS.

Prosta strona

Oto kod prostej strony, która ładuje dwa pliki JS:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>Minimalizacja JS</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <script src="js/file_1.js" type="text/javascript"></script>
    <script src="js/file_2.js" type="text/javascript"></script>
</head>
<body></body></html>

Powyższy kod powoduje załączenie dwóch plików JS. Poniżej przedstawiam ich kod:

file_1.js

/**
* Kolejny przyklad pliku z kodem JS
* */

var a = {
    'aaa' : "sadasdasasdasd", // to jest komentarz
    'bbb' : 12,
    'ccc' : {
                'aa' : 123
            },
    'ddd' : [
                1, // Tu jeszcze wiecej komentarza
                2,
                3,
                4,
                5
            ]
};

file_2.js:

/**
* Funkcja przykladowa, nic nie robi procz tego, za zajmuje
* troche miejsca
*
* @param b parametr 1
* @param c parametr 2
* @param d parametr 3
* */

function a(b, c, d)
{
    b = 10; // to jest komentarz

    // tu jeszcze wiecej komentarza
    return ( b + c ) * d;
}

Jak widać, kody są bardzo ładne. Czytelnie sformatowane, okraszone sporą ilością komentarzy, które pewnie są bardzo pomocne przy rozwijaniu skryptów. Ale czy potrzebuje ich zwykły Kowalski? Myślę, że nie.

Rozwiązania

Oczywiście, jak zawsze rozwiązań jest wieleee. Niedawno pisałem o Shrinksafe, który jest wykorzystywany m.in. przez dojo.

Jak pewnie zdążyłeś zgadnąć, nie jest to jedyne możliwe rozwiązanie. Doug Crockford na swojej stronie opublikował własną klasę PHP pozwalającą na minimalizację kodu JS.

Pokażę, w jaki sposób można wykorzystać klasę JSMin do kompresji kodu JS w locie, podczas ładowania plików.

JSMin

Kod JSMin można pobrać ze strony autora.

Przeróbmy zatem kod z pierwszego listingu:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>Minimalizacja JS</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <script src="js/min.php?f=file_1" type="text/javascript"></script>
    <script src="js/min.php?f=file_2" type="text/javascript"></script>
</head>
<body></body></html>

I dodajmy skrypt `min.php' w katalogu` js':

<?php
if (empty($_GET['f']))
{
	die('/* niewlasciwe dane */');
}

require_once 'jsmin.php';

$file = $_GET['f'] . '.js';
if (file_exists($file))
{
	echo JSMin::minify(file_get_contents($file));
}

Co nam to dało? Rozmiar plików uległ zmniejszeniu. Oto porównanie rozmiaru pobranych plików:

http://localhost/cache/js/min.php?f=file_1    76 B
http://localhost/cache/js/min.php?f=file_2    40 B

http://localhost/cache/js/file_1.js        337 B
http://localhost/cache/js/file_2.js        277 B

Jak widać, różnice są bardzo duże. Wniosek: robić!

Nie tak pięknie

Hola! Hola! To jednak nie jest takie piękne. Owszem, rozmiar pliku uległ zmniejszeniu. Jednak co z czasem? Czy przypadkiem zmniejszanie rozmiaru pliku nie powoduje narzutu czasowego? Tak, powoduje :/.

W niektórych przypadkach może powodować do tego stopnia, że mniejszy plik wczytuje się dłużej (samo przesyłanie danych trwa oczywiście mniej czasu, jednak doliczyć do tego należy czas jaki potrzebuje skrypt php na zminimalizowanie kodu).

Rozwiązanie

Czemu nie cache'ować już zminimalizowanych plików?

Nowa wersja min.js:

<?php

if (empty($_GET['f']))
{
 die('/* niewlasciwe dane */');
}

require_once 'jsmin.php';

$file = $_GET['f'] . '.js';
$min_file = 'min_' . $file;

if (!file_exists($file))
{
    die('/* nie ma pliku */');
}
else
{
    if (!file_exists($min_file))
    {
        file_put_contents($min_file, JSMin::minify(file_get_contents($file)));
    }
    echo file_get_contents($min_file);
}

Takie rozwiązanie przy pierwszym wywołaniu trwa dłużej. Później jednak wczytywany jest już zapisany na dysku plik ze skompresowanym kodem.

Pobierz kod

Warto przeczytać:

Komentarze (0) Trackbacks (0)

Brak komentarzy.


Leave a comment

 

Brak trackbacków.