Gyorsabb JavaScript és CSS letöltés

Az ötlet, után megoldottuk a JavaScript tömörítését a JavaScript Packer, majd a CSS tömörítést is a CSSTidy segítségével.

Most nézzük a végeredményt, és a használatát

/**
 * headerFiles
 *
 * #:#IIXfgU#:#param Array $files A gyorstárazandó állományok listája
 * #:#IIXfgU#:#param String $mode 'script|css'
 * #:#IIXfgU#:#param String $fileType 'one|list'
 * #:#IIXfgU#:#param String $prefix A  hivatkozás elé szánjuk
 * #:#IIXfgU#:#param mixed $compress Tömörítés mértéke
 * #:#IIXfgU#:#copyright  Copyright (c) 2008 Vince Tikasz
 * #:#IIXfgU#:#license    http://creativecommons.org/licenses/by-nc-sa/2.5/ Attribution-Noncommercial-Share Alike 2.5 Generic
 * #:#IIXfgU#:#version    2008-02-25 08:30
 */
function headerFiles( array $files, $mode, $fileType, $prefix, $compress = 62  ) {
    if ( count( $files ) > 0) {
        // Ha csak listázunk, akkor a fájltípusnak megfelelő hivatkozást szúrjuk be a kódba
        if ( $mode == 'list' ) {
            foreach ( $files as $f ) {
                if ( $fileType == 'css' ) {
                    echo '<link rel="stylesheet" type="text/css" href="'. $prefix.$f.'" />';
                }
                elseif ( $fileType == 'script' ) {
                    echo '<script type="text/javascript" src="'. $prefix.$f.'"></script>';
                }
            }
        }
        elseif ( $mode == 'one' ) {
            //Összeállítjuk a kiszolgálandó állomány elérési útját és nevét
            $dirname = dirname($_SERVER['SCRIPT_FILENAME']);
            $extension = $fileType == 'script' ? 'js' : 'css';
            $Hashes = array();
            foreach ( $files as $f ) {
                $Hashes[] = sha1_file( $dirname.$f );
            }
            $name = sha1( join(';#%#;', $Hashes) );
            $fileName = "{$dirname}/public/cache/{$name}.{$extension}";

            // Ha nem létezik, akkor a források valamelyike változott.
            // Le kell generálni a kiszolgálandó állományt
            if ( !is_file( $fileName ) ) {
                $Content = '';

                // Beolvassuk az állományok tartalmát
                foreach ( $files as $f ) {
                    if ( is_file( $dirname.$f ) ) {
                        $Content .= "/*START file: {$f}*/\n";
                        $Content .= file_get_contents( $dirname.$f );
                        $Content .= "\n/*//END file: {$f}*/\n";
                    }
                }

                // És a megfelelő eszközzel tömörítjük
                if ( $fileType == 'script' && strval(0) != strval($compress) ) {
                    require_once( 'class.JavaScriptPacker.php' );
                    $packer = new JavaScriptPacker($Content, $compress, true, false);
                    $Content = $packer->pack();
                }
                elseif ( $fileType == 'css' && strval(0) != strval($compress) ) {
                    require 'csstidy/class.csstidy.php';
                    $Css = new csstidy();

                    $Css->set_cfg('remove_bslash', 1 );
                    $Css->set_cfg('compress_colors', 1  );
                    $Css->set_cfg('compress_font-weight', 1 );
                    $Css->set_cfg('optimise_shorthands', 1  );
                    $Css->set_cfg('remove_last_;' , false  );
                    $Css->set_cfg('case_properties' , 1  );
                    $Css->set_cfg('merge_selectors', 2  );
                    $Css->set_cfg('css_level', 'CSS2.1' );

                    if ( $compress == 10 || $compress == 'Numeric' || $compress == 'low_compression' ) {
                        $Css->load_template( 'low_compression' );
                    }
                    elseif ( $compress == 62 || $compress == 'Normal' || $compress == 'high_compression' ) {
                        $Css->load_template( 'high_compression' );
                    }
                    elseif ( $compress == 95 || $compress == 'High ASCII' || $compress == 'highest_compression' ) {
                      $Css->load_template( 'highest_compression' );
                    }
                    else {
                        $Css->load_template( 'default' );
                    }
                    $Css->parse( $Content );
                    $Content = $Css->print->plain();
                }

                // A végeredményt eltároljuk...
                file_put_contents( $fileName, $Content );
            }
            // A már létező állományt pedig kiszolgáljuk
            headerFiles( array( "/public/cache/{$name}.{$extension}" ), 'list', $fileType, $prefix );
        }
    }
}

Használat:

A könyvtár szerkesztet:

  • /public
    • /cache (Ide kerülnek a generált, kiszolgálandó állományok)
    • /script (A scriptek forrás állományai)
    • /style (A CSS állományok)
<?php
$Scripts = array(
    // mindig a jQuery, vagy az éppen aktuálisan használt könyvtár az első
     '/public/script/jquery-1.2.3.js'
    // jQuery Pluginok, Addonok
    ,'/public/script/jquery/form.js'
    ,'/public/script/jquery/superfish.js'
    ,'/public/script/jquery/tablesorter.pack.js'
    ,'/public/script/jquery/fckeditor.js'
    ,'/public/script/jquery/delegate.js'
    ,'/public/script/jquery/validate.js'

    // és az utolsó a saját script
    ,'/public/script/sajat.script.js'
);
$CSS = array(
    ,'/public/style/superfish.css'
    ,'/public/style/menu.css'
    ,'/public/style/selectbox.css'
    ,'/public/style/thickbox.css'
    // saját CSS
    ,'/public/style/sajat.css'
);

headerFiles( $Scripts, 'one', 'script' );
headerFiles( $CSS, 'one', 'css' );

4 Responses to Gyorsabb JavaScript és CSS letöltés

  1. //:wladek says:

    Szerintem célszerű megvizsgálni nem csak a fájlok meglétét, hanem a méretét is.
    A másik dolog, ami nem a függvény hibája, hogy pl a scriptaculous -és gyaníthatóan a prototype úgy-ahogy-van – egész egyszerűen nem működik vele együtt, mivel a scriptaculousnak van egy load paramétere is kötelező jelleggel; plusz ez még a saját könyvtárán belül szeretne dolgozni…:)
    Persze mindent meg lehet oldani…
    Magam részéről még komfortosabbá tettem a stuffot akként, hogy visszatérési értéket adok neki.
    Amennyiben gondolod, szívesen megosztom; a megadott mail -en elérsz (motorba lett beépítve, átdolgozást követően…).

    Üdv.:
    //:wladek

  2. //:wladek says:

    Szerintem célszerű megvizsgálni nem csak a fájlok meglétét, hanem a méretét is.
    A másik dolog, ami nem a függvény hibája, hogy pl a scriptaculous -és gyaníthatóan a prototype úgy-ahogy-van – egész egyszerűen nem működik vele együtt, mivel a scriptaculousnak van egy load paramétere is kötelező jelleggel; plusz ez még a saját könyvtárán belül szeretne dolgozni…:)
    Persze mindent meg lehet oldani…
    Magam részéről még komfortosabbá tettem a stuffot akként, hogy visszatérési értéket adok neki.
    Amennyiben gondolod, szívesen megosztom; a megadott mail -en elérsz (motorba lett beépítve, átdolgozást követően…).

    Üdv.:
    //:wladek

  3. Vince says:

    Magam részéről még komfortosabbá tettem a stuffot akként, hogy visszatérési értéket adok neki.
    Amennyiben gondolod, szívesen megosztom;

    Ez jó lenne.

    Persze én is változtattam már ezen a cuccon. Az itt levő kód (ha megnézed) már lassan másfél éves. Fejlődött azóta. Jelenleg ZendFramework-el és jQuery-vel dolgozok. A tömörítés mértéke pedig annyi, hogy a JS kódot, lényegében, csak egy sorba tördeli, nem obfuszkál.

    Jelenleg egy ZF action helper ki-bekapcsolható szolgáltatásaként használom. Ez a helper vizsgálja az alap jQuery fájlok nevét (min, vagy packed), és ha már egyszer átfutott, akkor nem tömörít csak hozzáfűzi az outputhoz.

    Azt mindenképp meg kell jegyeznem, hogy természetesen nem szabad ész nélkül használni. Ha már valami “tömörített” formában van meg, akkor azt vagy nem szabad hozzá venni, vagy a $files tömböt tovább kellene bontani, amiben egyenként megadható a tömörítés mértéke, és további paraméterek.

  4. Vince says:

    Magam részéről még komfortosabbá tettem a stuffot akként, hogy visszatérési értéket adok neki.
    Amennyiben gondolod, szívesen megosztom;

    Ez jó lenne.

    Persze én is változtattam már ezen a cuccon. Az itt levő kód (ha megnézed) már lassan másfél éves. Fejlődött azóta. Jelenleg ZendFramework-el és jQuery-vel dolgozok. A tömörítés mértéke pedig annyi, hogy a JS kódot, lényegében, csak egy sorba tördeli, nem obfuszkál.

    Jelenleg egy ZF action helper ki-bekapcsolható szolgáltatásaként használom. Ez a helper vizsgálja az alap jQuery fájlok nevét (min, vagy packed), és ha már egyszer átfutott, akkor nem tömörít csak hozzáfűzi az outputhoz.

    Azt mindenképp meg kell jegyeznem, hogy természetesen nem szabad ész nélkül használni. Ha már valami “tömörített” formában van meg, akkor azt vagy nem szabad hozzá venni, vagy a $files tömböt tovább kellene bontani, amiben egyenként megadható a tömörítés mértéke, és további paraméterek.