Automatic Asset Optimization with Munee
Munee is an asset management tool which can compile LESS, SCSS, or CoffeeScript, manipulate images, minify CSS and JS, and cache assets on the server and client on the fly. It works with PHP 5.3 and newer versions.
In this tutorial, we will learn how Munee makes it easy to include assets in templates, how to install it, how it works and how to use it.
Munee is another way to avoid NodeJS in asset management of PHP apps.
Why would you want to use Munee?
Munee aims to make asset management easier. It performs a lot of tasks for us on the fly (i.e., when the asset is requested by the client) which we had to do manually before, thus saving time.
Here are some of the reasons why you may want to use Munee:
There are many shared web hosting servers which don’t have gzip enabled. If you are using Munee, it compresses files using PHP, ignoring this restriction.
You don’t have to worry about adding caching directives to .htaccess files. Munee will take care of both server and client side caching of assets.
Munee can manipulate images on the fly and is very handy for responsive web design. You don’t have to maintain different image files for different dimensions.
These are just some of the cases where you can find Munee very useful.
How does Munee work?
Once Munee is installed, it automatically starts caching assets on the server, sends proper client side caching headers, and starts sending gzip compressed responses, as well as compiled output for requested LESS, SCSS and CoffeeScript files.
To provide instructions to Munee for manipulating images or minifying CSS and JS files you need to add query string parameters to the path of the assets.
To be able to manipulate or minify assets Munee needs to intercept client requests for CSS, LESS, SCSS, JS, CoffeeScript and various image format files. To let munee intercept client requests for these assets we need to add an internal rewrite rule to .htaccess file (Nginx instructions also follow below).
Munee uses other third-party libraries such as
tedivm, etc. to resize, manipulate, compile and minify assets.
Query string parameters meant to provide instructions to Munee are called filters.
How does Munee cache assets?
For implementing client side caching, it sets
Cache-Control: must-revalidate headers while sending responses for the requested assets. It also reads caching headers in HTTP requests and sends a response or
304 Not Modified status depending on whether the client has the latest assets in its cache or not.
For implementing server side caching it stores the compiled, minified and manipulated assets in a separate directory.
It can detect changes to the original assets on runtime. When it detects a change in an original asset, it updates the server cache and also forces clients to use the latest files.
composer require meenie/munee
In the case of you trying to install Munee on a shared hosting server,
composer require Munee on your local computer manually and upload the
vendor directory to the hosting server.
Now we need to create a PHP file which is responsible for optimizing, manipulating, compiling and minifying assets using Munee.
For this, create a PHP file called
<?php require "vendor/autoload.php"; echo \Munee\Dispatcher::run(new \Munee\Request());
Now we need to redirect requests to assets such as CSS, LESS, SCSS, JS, CoffeeScript and various image format files to munee.php. We can do this using a server’s internal URL rewrite rules.
If you are using Apache, place this code in the .htaccess file of the directory in which the munee.php file is placed:
RewriteEngine On RewriteRule ^(.*\.(?:css|less|scss|js|coffee|jpg|png|gif|jpeg))$ munee.php?files=/$1 [L,QSA,NC]
If you are using Nginx then you must modify the actual virtualhost settings for a URL rewrite rule as per this issue and this gist.
.htaccess is disabled on your server or you don’t want to rewrite using
.htaccess, then you can manually pass the file path into
munee.php instead of an asset path in HTML:
For the rest of the tutorial, we’ll assume you are using
All the assets in the directory tree in which Munee is installed will be optimized.
Compiling SCSS, LESS and CoffeeScript
Here is some example code to demonstrate this:
<link rel="stylesheet" href="index.scss"> <link rel="stylesheet" href="index.less"> <script src="index.coffee"/>
For the SCSS and LESS files, the response header
Content-Type will be
text/css, and the response body text will be compiled CSS.
Similarly, for Coffee files the response header
Content-Type will be
Minifying CSS and JS Files
To minify CSS and JS files or compiled LESS, SCSS and CoffeeScript output we need to add
minify=true to the path of the asset in HTML:
<link rel="stylesheet" href="index.scss?minify=true"> <link rel="stylesheet" href="index.less?minify=true"> <link rel="stylesheet" href="index.css?minify=true"> <script src="index.js?minify=true" /> <script src="index.coffee?minify=true" />
Munee lets us resize, crop and colorize images on the fly. Apart from this it also let’s us convert images to grayscale, convert images to negative and also use default images in place of missing ones.
Resizing, Stretching and Cropping Images
To resize images on the fly we need to use the
resize filter. The value of the
resize filter is a set of arguments.
Here is an example which shows how to change the height and width of an image to 100px if it’s above that:
We can also provide only the height or width argument if we want to resize keeping the aspect ratio.
To crop an image we need to provide an
exact[true] argument along with height and width. Here is an example to demonstrate this:
Here the image will be cropped to exactly 100px height and width.
We can also add
stretch=true to stretch or resize an image to 100px height and width. Here is an example to demonstrate this:
These features of Munee are very useful for responsive and adaptive web design.
Placeholders for Missing Images
If an image is missing from the server, then we can use a placeholder image. For this functionality there is no filter. Rather, you have to add these instructions to the
require "vendor/autoload.php"; echo \Munee\Dispatcher::run( new \Munee\Request(array( "image" => array( "placeholders" => array( "/tourism/*" => "http://placedog.com/100/100", "*" => WEBROOT . DS . "img" . DS . "my-placeholder-image.jpg" ) ) )) );
Here inside the
placeholders array, we can provide a URL or path for placeholders of images missing in different sub directories. In the above example for all missing images inside the
tourism sub-directory we are using
http://placedog.com/100/100 as a placeholder, whereas for every other missing image we are using
Image Manipulation Security
Image manipulation takes a lot of memory and CPU time. Hackers can take down your server by requesting manipulated images again and again. Munee has built-in ways to tackle this issue:
- Referer should be the same domain where the image is located.
- It doesn’t keep more than 3 manipulated versions of an image in a time span of 5 minutes.
To combine assets, we just need to provide the file paths comma separated in HTML.
Here is an example to demonstrate this:
<link rel="stylesheet" type="text/css" href="index.css,index.scss?minify=true"> <script src="index.js,index.coffee?minify=true"></script>
Here we are combining
index.scss into one file. We have also passed
minify=true to minify the output. Munee will compile
index.scss to CSS before sending a response.
Similarly, we are combining
index.coffee into one file.
The library also provides an API to applications to manually optimize, manipulate and minify assets. You will only need to learn this API if you are planning to build a library which uses Munee as dependency.
You can find out more about this API in the official documentation.
There are many other options for managing assets but if you want assets to be managed on the fly, Munee seems like the best choice. You can learn about other miscellaneous filters provided by Munee in their official documentation.
How do you manage your assets? Taking the NodeJS route or avoiding it? Did you try Munee? Let us know in the comments!