Sneller css en javascript inladen revisted

augustus 26th, 2009

No Gravatar

Om even terug te komen op het vorige artikel, het blijkt dat op webkit gebaseerde browsers, c.q. Chrome en Safari niet kunnen omgaan met gzip.

Daarom is het slim om de volgende toevoegingen te maken in de code

if(preg_match('/Chrome/i', $_SERVER['HTTP_USER_AGENT'], $matches) || preg_match('/Safari/i', $_SERVER['HTTP_USER_AGENT'], $matches)) {
     $encoding = 'none';
     $cache = false;
} 

Overigens heb ik de code helemaal omgebouwd naar OOP waarvoor hieronder de listing:

public function __construct() {
        parent::__construct();
        //poo($this);
        $this->_LoadPage = false;
        $this->cache       = true;
        $this->cachedir = HOME_DIR . '../tmp/cache';
        $this->cssdir   = HOME_DIR . 'css';
        $this->jsdir    = HOME_DIR . 'javascript';
    }

    public function combinecss() {
        if($this->_CurrentId[1]) {
            $use_me = explode('?',$this->_CurrentId);
            if($use_me[1]) {
                $use_me2 = explode('=',$use_me[1]);
                $elements = explode(',',$use_me2[1]);
            }
        }   
    
        $base = realpath($this->cssdir);
        //print $base;exit();
        //chrome en safari kunnen niet omgaan met gegzipte css 
        if(preg_match('/Chrome/i', $_SERVER['HTTP_USER_AGENT'], $matches) || preg_match('/Safari/i', $_SERVER['HTTP_USER_AGENT'], $matches)) {
            $encoding = 'none';
            $this->cache = false;
        } 
        
        if(!strstr($_SERVER['HTTP_USER_AGENT'], 'Opera') && 
            preg_match('/^Mozilla\/4\.0 \(compatible; MSIE ([0-9]\.[0-9])/i', $_SERVER['HTTP_USER_AGENT'], $matches)) {
            $version = floatval($matches[1]);
            
            if ($version < 6)
                $encoding = 'none';
                
            if ($version == 6 && !strstr($_SERVER['HTTP_USER_AGENT'], 'EV1')) 
                $encoding = 'none';
        }
        foreach($elements as $key=>$value) {
            $file = realpath($cssdir . '/' . $value);
            $lastmodified = max($lastmodified, filemtime($file));
        }
        // Determine last modification date of the files
        $lastmodified = 0;
        // Send Etag hash
        $hash = $lastmodified . '-' . md5(implode(',',$elements));
        header ("Etag: "" . $hash . """);
        if (isset($_SERVER['HTTP_IF_NONE_MATCH']) 
            && stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) == '"' . $hash . '"') {
            // Return visit and no modifications, so do not send anything
            header ("HTTP/1.0 304 Not Modified");
            header ('Content-Length: 0');
        } else {
            // First time visit or files were modified
            if ($this->cache) {
                // Determine supported compression method
                $gzip = strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip');
                $deflate = strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate');
                // Determine used compression method
                $encoding = $gzip ? 'gzip' : ($deflate ? 'deflate' : 'none');
                // Check for buggy versions of Internet Explorer
                if (!strstr($_SERVER['HTTP_USER_AGENT'], 'Opera') && 
                    preg_match('/^Mozilla\/4\.0 \(compatible; MSIE ([0-9]\.[0-9])/i', $_SERVER['HTTP_USER_AGENT'], $matches)) {
                    $version = floatval($matches[1]);
                    
                    if ($version < 6)
                        $encoding = 'none';
                        
                    if ($version == 6 && !strstr($_SERVER['HTTP_USER_AGENT'], 'EV1')) 
                        $encoding = 'none';
                }
                
                //exclude chrome and safari
                if(preg_match('/Chrome/i', $_SERVER['HTTP_USER_AGENT'], $matches) || preg_match('/Safari/i', $_SERVER['HTTP_USER_AGENT'], $matches)) {
                    $version = floatval($matches[1]);
                    $encoding = 'none';
                }
                // Try the cache first to see if the combined files were already generated
                $cachefile = 'cache-' . $hash . '.css' . ($encoding != 'none' ? '.' . $encoding : '');
                if (file_exists($this->cachedir . '/' . $cachefile)) {
                    if ($fp = fopen($this->cachedir . '/' . $cachefile, 'rb')) {
    
                        if ($encoding != 'none') {
                            header ("Content-Encoding: " . $encoding);
                        }
                    
                        header ("Content-Type: text/css");
                        header ("Content-Length: " . filesize($this->cachedir . '/' . $cachefile));
            
                        fpassthru($fp);
                        fclose($fp);
                        exit;
                    }
                }
                
            }
            
            // Get contents of the files
            $contents = '';
            reset($elements);
            while (list(,$element) = each($elements)) {
                $path = realpath($base . '/' . $element);
                $contents .= file_get_contents($path);              
            }
            //poo($elements);exit();
            // Send Content-Type
            header ("Content-Type: text/css");
    

Het volgende stukje lost een probleem op wat we hadden met de plek van de directories. Omdat deze nu namelijk vanuit controllername/methode worden aangeroepen. (c.q. http://www.domein.extensie/apptools/combinecss)

         if (isset($encoding) && $encoding != 'none') {
                //echo $contents;exit();
                $contents =  ereg_replace('../img/','../../../img/',$contents);
                $contents = gzencode($contents, 9, $gzip ? FORCE_GZIP : FORCE_DEFLATE);
                header ("Content-Encoding: " . $encoding);
                header ('Content-Length: ' . strlen($contents));
                echo $contents;
            } 
    
            // Store cache
            if ($this->cache) {
                if ($fp = fopen($this->cachedir . '/' . $cachefile, 'wb')) {
                    fwrite($fp, $contents);
                    fclose($fp);
                }
            }
        }           
    }

Categorieën: Ontwikkeling

Reageren?

Sneller css en javascript inladen

augustus 20th, 2009

No Gravatar

Guus wees me op het volgende artikel :

http://rakaz.nl/2006/12/make-your-pages-load-faster-by-combining-and-compressing-javascript-and-css-files.html

De truc is dat in één keer al je css files en javascript files worden opgehaald, ingepakt met gzip en gecached. Na enkele tests uitgevoerd te hebben bleek dat dit het tonen van css stukken sneller maakt. Wat me opviel was zelfs dat het sneller is om de pagina de eerste keer te tonen dan dat deze uit cache gehaald moet worden :D

We waren in eerste instantie op zoek naar een server-side oplossing om alle witruimte uit css bestanden te halen om zo deze sneller in te laden. Je originele css blijft dan namelijk intact en dat maakt het makkelijker om het in de toekomst te bewerken.

Zelf heb ik het op de volgende manier toegepast. Ik laad het compare.php bestand in zoals genoemd in het artikel.

Wat ik er zelf nog aan heb toegevoegd is een functie om te kijken of het bestand ook echt bestaat. In de toekomst wil ik de class nog volledig oop opzetten en invoegen en mijn applicatie zodat de compare functie bijvoorbeeld aan te roepen is met app-tools/compare/css/bestandenlijst

De laadtijden zijn zeker met een factor 5 verbeterd

Ik heb het op de volgende manier geimplementeerd :

$CSS_STRING = $this->CheckFilesExistReturnExisting($this->_CssFiles,CSS_DIR);
if(count($CSS_STRING) > 0) {$this->_oSmarty->assign('CSS_FILES',$this->_BaseUrl.'combine.php?type=css&amp;files='.implode(',',$CSS_STRING));}

CheckFilesExistReturnExisting is een functie die uit een array alleen bestaande urls retourneerd. In je Smarty template toon je het vervolgens met:

{if $CSS_FILES} 
    <link rel="stylesheet" type="text/css" href="{$CSS_FILES}"/>
{/if}

Categorieën: Ontwikkeling

Tags:, Reageren?

Zend Framework integratie

juli 29th, 2009

No Gravatar

Vandaag verder gewerkt aan ons eigen software framework, dit is zo veel mogelijk MVC opgebouwd. Ik ben erg gecharmeerd van het Zend Framework, echter de manier waarop de applicatie in mekaar steekt is nog wat omslachtig. Ook de reden dat support voor het Smarty Template systeem niet ideaal is maakt dat ik er voor nu voor kies om mijn eigen bootstrap files en hoofd controller class te gebruiken.

Kort een overzichtje van hoe ik de structuur nu in mekaar heb gestoken: -een project bestaat uit de volgende mappen:

-application = de hoofdmap van de applicatie met alle bussiness logic en modellen -controllers = alle controllers die de communicatie tussen model en view mogelijk maken -models = alle modellen die database bewerkingen mogelijk maken -config = map met alle config bestande -language = met daarin language bestanden in gettext formaat -library = met daarin alle 3rd party oplossingen zoals Zend en Smarty maar ook de mijn eigen abstracte klassen -public = alles wat openbaar is voor het web -css -img -javascript -tpl = alle smarty tpl bestanden -upload = voor bestanden die gebruikers uploaden -sql = database bestanden voor opbouw en testen -tmp -smarty_compile = compilatiemap voor smarty

Onderdelen van ZF die ik nu gebruik zijn ZendDb, Zendauth, Zend registry etc.

Categorieën: Ontwikkeling

Tags:, Reageren?

Working on Umros – progress update

juli 28th, 2009

No Gravatar

UMROS stands for Unified MRO System and is maintained and created by DigitalBits. Goals/Setup UMROS started out as a central product information database for Enluse BV. The idea is to have one central place where all the product information resides so it can be easily used on Enluse company sites and dealers and/or customers sites (from here on reffered to as Enluse Customers). This product information needs to include: -product name -article number -product photos -product description and title -translations of the description and title in an unlimited number of languages

Today the following changelog was submitted:

umros.com – v.102

  • 0000277: [UMROS - product catalogues] [FEATURE] use retail price when adding a product (martbeuk) – resolved.
  • 0000284: [UMROS - product catalogues] [BUG] unable to translate product groups (martbeuk) – resolved.
  • 0000281: [UMROS - products section] [BUG] unable to change a brand for a group (martbeuk) – resolved.
  • 0000275: [UMROS - product catalogues] [FEATURE] Delete button does not work (martbeuk) – resolved.
  • 0000278: [UMROS - product catalogues] [FEATURE] mention number of clones a product has (martbeuk) – resolved.
  • 0000267: [UMROS - product catalogues] [BUG] Adding product to different groups does not work (martbeuk) – resolved.
  • 0000261: [UMROS - overall] wachtwoord voor customer contacts wordt niet goed opgeslagen (martbeuk) – resolved.
  • 0000260: [UMROS - product catalogues] Add Brands Layer (martbeuk) – resolved.
  • 0000220: [UMROS - order section] Ammounts should be saved and shown in cents (martbeuk) – resolved.
  • 0000225: [UMROS - overall] Customer can not be added by non-admins (martbeuk) – resolved.
  • 0000235: [UMROS - overall] change a customers contact password (martbeuk) – resolved.
  • 0000250: [UMROS - order section] [FEATURE] show the customers ref number when editing an order (martbeuk) – resolved.

Not everything is finished but we are right now testing this service release

Categorieën: Geen categorie

Reageren?

Feed

http://blog.digitalbits.nl /