当通过php与直接链接发送时,大图像加载缓慢


Large images load slowly when sending via php vs straight links

当我们使用image_jpegfile_get_contents通过PHP输出图像时,它需要的时间是我们使用直接链接到jpg文件时的两倍多。
这些文件大约180kb。
对于我们的缩略图(4kb图像),链接和通过PHP输出之间没有太大的时间差。

谁知道为什么PHP输出较慢与较大的文件和一种方法来解决它?

我所能想到的是,当通过PHP解析时,它被解析了两次,而不是直接发送给客户端。因为file_get_contents按照它所说的去做,所以它读取内容,然后将其发送给客户机。我可能错了。

image_jpeg和file_get_contents不一样。第一个是创建jpeg的gd函数,这需要花费一些时间。第二种只是从文件中读取数据。

问题是如何将其输出到浏览器。如果不采取适当的措施,内容永远不会被缓存,因此浏览器每次都必须下载它。静态图像总是由浏览器缓存,并且在第一次加载之后,几乎不需要花费时间(只是一个HEAD请求)。

试试这个代码:

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);
    }
  }
}