user981971
user981971

Reputation: 79

Large images load slowly when sending via php vs straight links

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

Answers (2)

Ghigo
Ghigo

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

Michel Maas
Michel Maas

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

Related Questions