Combine .js and .css files to make OSClass load faster

From OSClass

Each OSClass page used several different .js and .css files,a lot of time is wasted fetching each of these files individually. The solution is to combine all the different files into a single large file and compress that file using gzip. Doing this manually turns out into maintenance problems, each time you need to modify a css file or a js script, you will need to combine and compress them again. Warning: while you save time reducing the number of external files, you lose a little combining and compressing them.


We've created a file that will automate the process, you will need zero programming skills, and only modify a few lines on your current theme. The file should be placed on your theme folder and call it on your HTML like the following example :


For CSS loading:

<link href="<?php echo osc_current_web_theme_url('combine.php?type=css&files=css/style.css,css/tabs.css') ; ?>" rel="stylesheet" type="text/css" />


For JS loading:

<script type="text/javascript" src="<?php echo osc_current_web_theme_url('combine.php?type=js&files=js/jquery.js,js/jquery-ui.js,js/jquery.uniform.js,js/global.js,js/tabber-minimized.js') ; ?>"></script>


General usage:

combine.php?type={TYPE}&files={FILES}

Where {TYPE} is js o css, depends on what you want to combine, and {FILES} are the files separated by commas (relative path from the theme folder).


This modification is done at a theme level, some themes may have it already included, so no work is required. With this short tip you could save a couple of seconds in page loading time. In modern theme, .js files where reduced from 313Kb to 85Kb and css files from 37Kb to 8Kb!


combine.php

<?php
 
    /************************************************************************
     * CSS and Javascript Combinator 0.5
     * Copyright 2006 by Niels Leenheer
     *
     * Permission is hereby granted, free of charge, to any person obtaining
     * a copy of this software and associated documentation files (the
     * "Software"), to deal in the Software without restriction, including
     * without limitation the rights to use, copy, modify, merge, publish,
     * distribute, sublicense, and/or sell copies of the Software, and to
     * permit persons to whom the Software is furnished to do so, subject to
     * the following conditions:
     * 
     * The above copyright notice and this permission notice shall be
     * included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     */
 
    $cache    = true;
    $cachedir = '../../uploads';
    $base     = dirname(__FILE__);
 
    $type     = $_GET['type'];
    $elements = explode(',', $_GET['files']);
 
    if( !in_array($type, array('css', 'js')) ) {
        header ("HTTP/1.0 403 Forbidden") ;
        exit ;
    }
 
    // Determine last modification date of the files
    $lastmodified = 0;
    while( list(,$element) = each($elements) ) {
        $path = realpath($base . '/' . $element) ;
 
        if( ($type != 'js' && $type != 'css') || 
            ($type == 'js' && substr($path, -3) != '.js') || 
            ($type == 'css' && substr($path, -4) != '.css') ) {
            header ("HTTP/1.0 403 Forbidden") ;
            exit ;
        }
 
        if (substr($path, 0, strlen($base)) != $base || !file_exists($path)) {
            header ("HTTP/1.0 404 Not Found");
            exit;
        }
 
        $lastmodified = max($lastmodified, filemtime($path));
    }
 
    // Send Etag hash
    $hash = $lastmodified . '-' . md5($_GET['files']);
    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( $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';
                }
            }
 
            // Try the cache first to see if the combined files were already generated
            $cachefile = 'cache-' . $hash . '.' . $type . ($encoding != 'none' ? '.' . $encoding : '') ;
 
            if( file_exists($cachedir . '/' . $cachefile) ) {
                if( $fp = fopen($cachedir . '/' . $cachefile, 'rb') ) {
                    if( $encoding != 'none' ) {
                        header ("Content-Encoding: " . $encoding) ;
                    }
 
                    header( "Content-Type: text/" . $type) ;
                    header( "Content-Length: " . filesize($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 .= "\n\n" . file_get_contents($path) ;
        }
 
        // Send Content-Type
        header ("Content-Type: text/" . $type) ;
 
        if (isset($encoding) && $encoding != 'none') {
            // Send compressed contents
            $contents = gzencode($contents, 9, $gzip ? FORCE_GZIP : FORCE_DEFLATE) ;
            header( "Content-Encoding: " . $encoding ) ;
            header( 'Content-Length: ' . strlen($contents) ) ;
            echo $contents ;
        } else {
            // Send regular contents
            header( 'Content-Length: ' . strlen($contents) ) ;
            echo $contents ;
        }
 
        // Store cache
        if( $cache ) {
            if( $fp = fopen($cachedir . '/' . $cachefile, 'wb') ) {
                fwrite($fp, $contents) ;
                fclose($fp) ;
            }
        }
    }
 
?>