David Caunt

PHP and Zend Framework Engineer

Subscribe to my RSS feed

Posts Tagged ‘performance’

Zend Framework Pitfalls Part 2 – Zend_Db Won’t Use the Query Cache with MySQL

November 28th, 2009

This one’s not limited to Zend Framework, but is actually a ‘problem’ in MySQL. I think it is worth covering, as the paragraph in the manual is easily missed.

From the MySQL manual:

Before MySQL 5.1.17, prepared statements do not use the query cache. Beginning with 5.1.17, prepared statements use the query cache under certain conditions, which differ depending on the preparation method

This means that if you’re running MySQL 5.0.x, not uncommon at the time of writing, your applications are not going to benefit from the query cache. There’s a simple workaround, however:

If you’re using Pdo, set the following driver option:

$pdoParams = array(
    PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
);
 
$params = array(
    'host'           => '127.0.0.1',
    'username'       => 'webuser',
    'password'       => 'xxxxxxxx',
    'dbname'         => 'test',
    'driver_options' => $pdoParams
);

Zend_Config_Ini [parse_ini_file()] doesn’t support class constants, so ini users will have to supply the value of PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1000, in their configs:

resources.db.adapter         = pdo_mysql
resources.db.params.host     = localhost
resources.db.params.username = webuser
resources.db.params.password = xxxxxxxx
resources.db.params.dbname   = myDb
resources.db.params.driver_options.1000 = true

Serving gzipped assets from Amazon S3 & Cloudfront

October 13th, 2009

One of the first steps in improving front-end performance is to migrate static assets to a content delivery network, such as Amazon’s CloudFront or Akamai. CloudFront is particularly attractive with its pay-as-you-go model, tiny upfront investment and ease of use.

Your existing web server may already be set up to compress JavaScript and CSS, potentially saving hundreds of kb on the wire. In uploading and testing your assets on CloudFront you’ll soon realise that it doesn’t perform any gzipping or compression. How to benefit from Amazon’s superfast edge locations and smaller file sizes?

When your browser requests a page, the headers sent might look like the following:

Host: www.davidcaunt.co.uk
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729) FirePHP/0.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.8,en-gb;q=0.5,en-us;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.davidcaunt.co.uk/about/

The header we’re interested in here is Accept-Encoding – this denotes whether the browser can cope with gzipped assets, and is used by Apache to decide whether to compress them. We can use this header in our PHP scripts to reference pre-compressed assets, and here’s how:

  1. Compress asset, e.g. home.css -> home.cssgz
  2. Upload both files, home.css and home.cssgz to S3 (CloudFront)
  3. Add PHP code to link to the compressed file if the browser accepts

You can easily compress assets on Linux using the following:

gzip home.css

In step 2, you’ll need to inform S3 that your assets are gzipped. S3 allows you to specify headers that will be sent with your file:

Content-Encoding: gzip

All good libraries and gui tools will help with this. It also makes sense to set Expires headers, if your assets are versioned.

Then the following PHP snippet should be all you need:

if (false !== strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')){
	$path = '/css/home.cssgz';
}else{
	$path = '/css/home.css';
}

You’ll want to integrate this code into your View Helpers (Zend Framework) or application code for generating asset URLs.

Note

You’ll notice I’ve named my file home.cssgz, not home.css.gz. I had problems with Safari PC (and probably Mac) refusing to use these files inline, and being disposed as attachments.


Top