Smaller – Batch minify HTML, PHP, CSS and JavaScript on the Mac

Honestly, I was looking into JavaScript, HTML & CSS minifiers for my production usage, definitely my preferences were not to visit online-minifier’s website every time I need some minification, something has faster usability, something sells soft obfuscation (‘Packer’ is slow!), something does the work in a batch, merges all in a one (save HTTP requests!), something replaces the original (I don’t want renaming the file with “.min” etc.).

You know, some unplanned tweaking in the CSS/JS occurs at the last moment to/after deploy and non-automated minification of your static files really sucks that time. Better we may use some kind of automatic or semi-automatic automation for those repetitive tasks to buy some time.

Something about the other minifiers bothered me that, those were not ready for production usages like elimination of conditional HTML statements (IE hacks!), non-batch, some were only for JS or CSS etc.

Later I found Smaller, I drag and drop my entire template/layout directory and have my contents minified replacing the original, found handy in my case and a recommended app for Mac.

BTW, I found some backward compatibility issue with it and was not being able to use their latest version (1.3.5) in my Snow Leopard 10.6.8. I call for a support, the lead dev Chen Luo promptly responded “Smaller 1.3.5 was built with Xcode 4.4 but Apple removed OS X 10.6 SDK since then”.  So, 1.3.4 is working for me and haven’t missed much from 1.3.5.

Disclosure: I have written this review in exchange of a license of “Smaller”.

Advertisements

Using Google’s CDN to load JavaScript libraries

For rich Ajax web applications page loading time suffers from loading JavaScript libraries such as JQuery, MooTools, Prototype etc..  Most of them are larger than 50KB in size and if you are in need to combine libraries then you are adding 100KB+ to your page loads.

Also your web server will experience delivery of your own hosted JavaScript libraries across distinct geographical requests. You can easily offload your server for those files.

Assuming all possible ways to improve JavaScript libraries loading time, Google’s CDN aka Google Libraries API can be a good solution.

Why Google CDN? Why not my own server?

  • The Google Libraries API is a content distribution network and loading architecture for the most popular, open-source JavaScript libraries.
  • Google’s huge CDN (content delivery network) can deliver the file much. Since Google has large data centers all over the world, these files will be served from data centers geographically closer to your users. This helps to reduce network latency and add to reliability, scalability and so on.
  • The more sites that include Google’s google.load() API the greater the chance that a user has already has the file cached, thus enabling your site to load faster as the script will not need to be downloaded.
  • You save bandwidth as you no longer have to serve the file(s).
  • The versioning system that Google has created makes it effortless to include specific versions of these libraries.

All you need to do is make a Google’s Libraries API call google.load() like:


<script src="http://www.google.com/jsapi" type="text/javascript"></script>

google.load("chrome-frame", "1.0.2");
google.load("dojo", "1.5");
google.load("ext-core", "3.1.0");
google.load("jquery", "1.4.2");
google.load("jqueryui", "1.8.4");
google.load("mootools", "1.2.4");
google.load("prototype", "1.6.1.0");
google.load("scriptaculous", "1.8.3");
google.load("swfobject", "2.2");
google.load("yui", "2.8.1");
google.load("webfont", "1.0.6");

.

Minor Drawbacks

  • You’re dependent on the CDN infrastructure. If they are down, your website will be hardly usable, too.  But that case u have to write extra codes to check the desired library loaded or not.
  • You cannot influence bandwidth and carriers of the delivery provider’s network.

Reference: http://code.google.com/apis/libraries/devguide.html#AjaxLibraries

.

🙂

Cache PHP output for high traffic websites. PEAR: Cache_Lite

Intro…

Now days the WebPages are outcome of heavy script processing in order to provide more dynamicity to page visitors. The utility of server side scripting is to adopt more engineering on web. When the page gets more visitors or becomes more popular, you have to ensure that, that traffic doesn’t stack or queued in front of your freaky web server. All you have to do is to serve them with your page and ofcourse serve it faster. Again server side scripting requires processing and compiling.

In order to serve pages faster, to make light use of server side processing and compiling and to survive within heavy traffic, caching dynamic script output is needed.

The Need For Speed…

Every time a request hits your web server, PHP has to do a lot of processing, all of your codes have to be compiled and executed for a single traffic hit every time. Interesting thing will be if the outcomes of all these processing is identical for each visitors. Say, processing happens every time for visitor 24500 and 24501 while the outputs are so same. Argh!!

What would be if we save the flat HTML generated for visitor 24500 and serve that to 24501 as well??? That will be awesome 😀 coz this leads to less processing and faster page handover. This da mechanism we are talking about, yeah! Cache PHP output 😀

Well we can write such optimization system but there is a smart package in PEAR called Cache_Lite that can do this job for us. Let’s check out why Cache_Lite:

  • It saves time of writing new caching codes 😀
  • It’s optimized for high traffic websites
  • Robust, easy to implement
  • Have time to time documentation
  • Bunch of cool features. 🙂

Installation…

The Cache_Lite class comes courtesy of PEAR, the “PHP Extension and Application Repository” (http://pear.php.net). In case you didn’t know, PEAR is an online repository of free PHP software, including classes and modules for everything from data archiving to XML parsing. When you install PHP, a whole bunch of PEAR modules get installed as well; the Cache_Lite class is one of them.

In case not installed then…

It is just like coding hello world!! 😀

On ubuntu:

sudo aptitude -y update
sudo aptitude install php-pear

Now that we have PEAR, i would use it to install the Cache_Lite extension

sudo pear install Cache_Lite

Perfect! 😀

Checking whether installed/ checking PEAR verson:

Both pear and pecl tools should be available everywhere on command line. For that to work, pear’s binary (bin) directory should be in your PATH variable.

To verify it works, simply type pear. A list of commands should be shown:

$ pear
Commands:
build                  Build an Extension From C Source
bundle                 Unpacks a Pecl Package
channel-add            Add a Channel
...

You should further test that PEAR is up to date:

$ pear version
PEAR Version: 1.7.2
PHP Version: 5.2.6RC4-pl0-gentoo
Zend Engine Version: 2.2.0
Running on: Linux ...

More installation queries here: http://pear.php.net/manual/en/installation.checking.php

Implementation…

<?php

// Include the package
require_once('Cache/Lite.php'); // make sure cache_lite script path

// Set a id for this cache
$id = '123';

// Set a few options
$options = array(
    'cacheDir' => '/tmp/',
    'lifeTime' => 3600
);

// Create a Cache_Lite object
$Cache_Lite = new Cache_Lite($options);

// Test if thereis a valide cache for this id
if ($data = $Cache_Lite->get($id)) {

    // Cache hit !
    // Content is in $data
    // (...)

} else { // No valid cache found (you have to make the page)

    // Cache miss !
    // Put in $data datas to put in cache
    // (...)
    $Cache_Lite->save($data);

}

?>

 

More clearly…


<?php
require_once "Cache/Lite.php";

$options = array(
    'cacheDir' => '/tmp/',
    'lifeTime' => 7200,
    'pearErrorMode' => CACHE_LITE_ERROR_DIE
);
$cache = new Cache_Lite($options);

if ($data = $cache->get('id_of_the_page')) {

    // Cache hit !
    // Content is in $data
    echo $data;

} else {

    // No valid cache found (you have to make and save the page)
    $data = '<html><head><title>test</title></head><body><p>this is a test</p></body></html>';
    echo $data;
    $cache->save($data);

}

?>

If you wish use a cache per block and not a global cache, take as example the following script:

<?php
require_once('Cache/Lite.php');

$options = array(
    'cacheDir' => '/tmp/',
    'lifeTime' => 3600
);

// Create a Cache_Lite object
$Cache_Lite = new Cache_Lite($options);

if ($data = $Cache_Lite->get('block1')) {
    echo($data);
} else {
    $data = 'Data of the block 1';
    $Cache_Lite->save($data);
}

echo('<br><br>Non cached line !<br><br>');

if ($data = $Cache_Lite->get('block2')) {
    echo($data);
} else {
    $data = 'Data of the block 2';
    $Cache_Lite->save($data);
}

?>

Little bit implementation:

The key point is Cache_Lite maintains a unique identifier for every page. Cache_Lite will check for that identifier used before. If so, it will retrieve the stored HTML from disk (can use RAM as turbo charged storage i.e. mount tmpfs in RAM memory) and echo it right away. If not, we:

  • turn on output buffereing so we can catch all following content
  • we include the original PHP code
  • catch the output buffer, and let Cache_Lite store it on disk for the next time.
  • and then echo it

Example:

<?php

/* Include the class */
require_once 'Cache/Lite.php';

/* Set a key for this cache item */
$id = 'newsitem1';

/* Set a few options */
$options = array(
    'cacheDir' => '/var/www/www.mywebsite.com/cache/',
    'lifeTime' => 3600
);

/* Create a Cache_Lite object */
$Cache_Lite = new Cache_Lite($options);

/* Test if there is a valid cache-entry for this key */
if ($data = $Cache_Lite->get($id)) {
    /* Cache hit! We've got the cached content stored in $data! */
} else {
    /* Cache miss! Use ob_start to catch all the output that comes next*/
    ob_start();

    /* The original content, which is now saved in the output buffer */
    include "requiredPhpFile.php";

    /* We've got fresh content stored in $data! */
    $data = ob_get_contents();

    /* Let's store our fresh content, so next
     * time we won't have to generate it! */
    $Cache_Lite->save($data, $id);
    ob_get_clean();
}
echo $data;

?>

A Special case…

Say a case, is to automatically purge an article’s cache when a comment has been placed. You could for example place this before Cache_Lite checks if it’s got a cache page for a specific $id:


<?php
if(isset($_POST["add_comment"]) && $_POST["add_comment"]){
    $Cache_Lite->remove($id);
}

?>

Docs for Cahe_Lite here:

http://pear.php.net/manual/en/package.caching.cache-lite.php