Reputation: 79
When we output images via PHP with image_jpeg
or file_get_contents
it takes more than twice as long as when we use straight links to the jpg files.
These files are about 180kb.
With our thumbnails (4kb images) there's not much of a time difference between the link and output via PHP.
Anyone know of a why PHP output is slower with larger files and a way to fix it?
Upvotes: 0
Views: 88
Reputation: 2332
There is different between image_jpeg and file_get_contents. The first is a gd function that creates a jpeg and this take time. The second just reads data from a file.
The problem is how you output it to the browser. If you don't take appropriate measures, content is never cached, so the browser has to download it every time. Static images are always cached by the browser and after the first load, takes almost no time (just a HEAD request).
Try this code:
function CachedFileResponse($thefile,$nocache=0) {
if (!file_exists($thefile)) {
error_log('cache error: file not found: '.$thefile);
header('HTTP/1.0 404 Not Found',true,404);
} else {
$lastmodified=gmdate('D, d M Y H:i:s \G\M\T', filemtime($thefile));
$etag = '"'.md5($lastmodified.filesize($thefile).$thefile).'"';
header('ETag: '.$etag);
header('Last-Modified: '.$lastmodified);
header('Cache-Control: max-age=3600');
header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time()+86400));
$ext=strtolower(substr($thefile,strrpos($thefile,'.')+1));
$fname=substr($thefile,strrpos($thefile,'/')+1);
if ($ext=='jpg' || $ext=='jpeg') {
header('Content-Type: image/jpeg');
} elseif ($ext=='gif') {
header('Content-Type: image/gif');
} elseif ($ext=='png') {
header('Content-Type: image/png');
} else {
header('Content-Type: application/binary');
}
header('Content-Length: ' . filesize($thefile));
header('Content-Disposition: filename="'.$fname.'"');
$ifmodifiedsince = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : false;
$ifnonematch = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : false;
if ($nocache || (!$ifmodifiedsince && !$ifnonematch) ||
($ifnonematch && $ifnonematch != $etag) ||
($ifmodifiedsince && $ifmodifiedsince != $lastmodified)) {
error_log('cache miss: '.$thefile);
$fp = fopen($thefile, 'rb');
fpassthru($fp);
fclose($fp);
} else {
error_log('cache hit: '.$thefile);
header("HTTP/1.0 304 Not Modified",true,304);
}
}
}
Upvotes: 0
Reputation: 417
All I can think of is that it is being parsed twice when parsed through PHP, instead of directly sending it to the client. Because file_get_contents does what it says, it reads the contents, then sends it to the client. I could be wrong though.
Upvotes: 3