CodeIgniter Optimizations
I am currently building a pretty large CMS system on top of CodeIgniter and I wanted to share some of the best performance optimizations I have found. Although CodeIgniter is optimized out of the box, when you start building large scale applications with large controllers, it is easy to miss things that can add up to your overall performance.
Do Not Save Queries
$this->db->save_queries = FALSE;
By default CodeIgniter keeps an array of all the queries1 ran so that they can be used in the profiler for debugging. This is great during development but in most production cases that is not needed and just wasted memory. I recommend disabling this in production mode and can be conditionally setup with a simple if statement:
if (ENVIRONMENT == 'production')
{
$this->db->save_queries = FALSE;
}
Output Cache
CodeIgniter supports several levels of caching and the most extreme is caching is the entire output. That is designed to cache the entire parsed page then just display it the html for the amount of minutes you designate.
By default CodeIgniter writes this cache to files which increases your i/o and it might suit you better to use apc2 (example) or memcache for the storage.
The downside to this is if you are needing some form of dynamic data like user information. Then it will not work. If that is a requirement for you then consider caching queries or other areas where your site is slow. Or you can do like getsparks and use ajax calls to dynamically populate the user information.
Consider Nginx + php-fpm + apc
I know everybody uses Apache and it has tons of tutorials and an all around good server. But in my tests straight out of the box Nginx out performs Apache and I am not the only one
I had a standard AWS medium instance running about 25 sites that was averaging 30% CPU usage during the day with Apache + APC. After just switching to Nginx and php-fpm it is now averaging around 10%. That is a huge difference!
Autoloading Can Be Dangerous
CodeIgniter comes with an “Auto-load” feature that permits libraries, helpers, and models to be initialized automatically every time the system runs.
Lets face it autoloading is awesome, but does come with some drawbacks. The biggest is that everything autoloaded is loaded on every request. This means for every page and every ajax call all those items are being loaded. So unless you are, in fact, going to need it for everything then I wouldn’t recommend auto loading. Instead consider base controllers or loading only when needed.
Only Load What You Need
Touching on autoloading is another common issue I have seen. Loading when you don’t need too. Ideally you do not want to load anything unless you are going to use it in the code that is running.
class Welcome extends CI_Controller {
public function __construct()
{
$this->load->library('email');
$this->load->library('ftp');
}
public function index()
{
$this->load->view('home_page');
}
}
As you can see in the example above we are loading two libraries that will never be used when viewing the home page so by including them you are just wasting resources.
-
This feature has been around since v1.6.0 but is not documented very well. ↩
-
This idea came from getsparks.org and I linked to a gist in case getsparks code changes. ↩