3

This is my php code.

    <?php
    ob_start();
    echo file_get_contents("originalhighqualityphoto.jpg");
    $dat=ob_get_contents();
    ob_end_clean();
    $dat=gzencode($dat,2);
    header("content-disposition: attachment; filename=\"OptimizedPhoto.jpg\"",true);
    header("content-encoding: gzip",true);
    header("content-type: image/jpeg",true);
    header("cache-control: max-age=1000000",true);
    header("content-length: ".strlen($dat),true);
    echo $dat;exit();
    ?>

What I'm trying to do is make it so that the images will download at 100% quality and faster off my website without having to offer them as zip files. I don't want to use direct image compression (like with photoshop for example) because thats already used elsewhere on my site as "previews" to the high quality images.

I tested the download in my own web browser (Opera v11.6) and it works normally.

Here is what throws me off. I used webpagetest.org to try to download the images and the weirdest results are as follows:

Via firefox at webpagetest.org:

Leverage browser caching of static assets: 75/100

WARNING - (1.8 days) - http://ciscobinary.openh264.org/openh264-win32-v1.3.zip 

Note: I did not name any file as a zip file and when I manually accessed that file, it contained two random files, one being a dll file.

Test via IE8 at webpagetest.org:

Compress Images: 62/100

8.0 KB total in images, target size = 5.0 KB - potential savings = 3.0 KB

FAILED - (8.0 KB, compressed = 5.0 KB - savings of 3.0 KB) - http://example.com/path/to/testphpfile.php

I don't understand where the 8.0 KB comes from when the image I used in the test is over 100KB.

In chrome via webpagetest.org the test seems OK.

In page speed insights, the score is OK but the output is garbled.

Properly formatting and compressing images can save many bytes of data. Optimize the following images to reduce their size by 36.8KiB (20% reduction).

    Losslessly compressing http://example.com/path/to/testphpfile.php could save 36.8KiB (20% reduction).

Also, in page speed insights when tested via mobile, it goes on about configuring a viewport, but I don't think that's possible with an HTTP header only.

speaking of which.... Are the headers causing these results or is there something else I need to do out there to make the image downloading script work and seo friendly?

  • You could tweak your script a bit (if you are using file_get_contents() you don't need the output buffer and there are alternatives to gzencode()) but I'm not sure it would make a difference. Have you tried not-gzipping it? Are these tools intended to test this type of response? Have you tried other real browsers (apart from Opera 11.6)? And looked at the headers/response in these browsers? "Viewport" - you are forcing a download, so what does the viewport have to do with it? "SEO friendly" - you are forcing a download, SEO would seem to be irrelevant here? Is openh264.org your domain? – MrWhite Mar 14 '15 at 13:19
  • Have you compressed the jpg file using lossy compression? not gzip.. – Simon Hayter Mar 14 '15 at 15:48
  • The original jpeg being fed into the file_get_contents() uses no compression, as I want the download to offer the highest quality image possible regardless of speed. I have tried not gzipping it and the results are much worse and I posted those results somewhere else on this website. openh264.org is not my domain at all. This is also part of a site I'm monetizing with adsense and I believe this affects my income because the robots believe the current image download idea causes the whole user experience to be slower for the reasons mentioned above. – Mike Mar 14 '15 at 17:23
  • 1
    The firefox issue is a known incompatibility with Webpagetest and FF, if you get this error on webpagetest it's likely that firefox has just been reinstalled, if you run it again you will get the expected results (so long as the same agent is used). The issue occurs since firefox version 31 I believe, when firefox started shipping the openh264 codec provided by cisco. – Alex Berry Mar 27 '15 at 11:25
1

With regards to the WebPageTest issue about the openh264 zip file, I honestly don't know but I suspect Alex Berry is probably right in his comment, though I couldn't confirm this with any information I was able to find about it.

With regards to the PageSpeed Insights recommendation to use lossless compression, I suspect you will have to change file format from JPEG (.jpg) to Portable Network Graphics (.png) to achieve this optimally.

With regards to the PageSpeed Insights recommendation to specify a viewport, this is done using HTML and is a separate issue altogether from image compression and download speed, and is all about compatibility and accessibility of your website with mobile devices.

To get the best from GZip and browser caching for your photos try something like this:

<?php
$aHeaders = array();

/* Content/Behaviour Headers */
$aHeaders[] = 'Content-Type: image/jpeg';
$aHeaders[] = 'Content-Disposition: attachment; filename="OptimizedPhoto.jpg"';

/* Browser Cache for 35 days */
$iCacheSecs = 3024000; // 60 secs * 60 mins * 24 hours * 35 days
$dtNow = time();
$dtExpires = strtotime( sprintf( '+%s seconds', $iCacheSecs ));
$aHeaders[] = 'Expires: ' . date( 'r', $dtExpires );
$aHeaders[] = 'Last-Modified: ' . date( 'r', $dtNow );
$aHeaders[] = 'Cache-Control: public, must-revalidate, max-age=' . $iCacheSecs );

/* Generate Unique ETag */
$sData = @file_get_contents( 'originalhighqualityphoto.jpg' );
$sETag = md5( $sData );
$aHeaders[] = sprintf( 'ETag: %s', $sETag );

/* Send HTTP 304 response if resource same as held in browser cache */
$sSuppliedETag = isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ?
  $_SERVER['HTTP_IF_NONE_MATCH'] : '';
if( $sSuppliedETag == $sETag ) {
  header( 'HTTP/1.1 304 Not Modified' );
  header( 'Content-Length: 0' );
  exit;
}

/* GZIP Compression, Send Headers, Send Content */
if( !ob_start( 'ob_gzhandler' )) ob_start();
foreach( $aHeaders as $sHeader ) header( $sHeader );
echo( $sData );
exit;
  • Thanks, but after looking at your code, you're asling for more memory because you're buffering data through an array and you're buffering the output through ob_start and I will add ob_end_flush before the exit. I'll +1 you for suggesting if-modified-since comparison in your code. – Mike May 21 '15 at 16:19
  • Hi Mike, perhaps you've had a different experience, but I deliberately exclude ob_end_flush() as have found this can cause numerous problems with various browsers such as IE6, Chromium-based, Webkit-based, leaving the browsers taking more than 30 seconds to load the page instead of less than 2. PHP automatically flushes the output buffer at the end of executation in any case with or without this function being called. The script isn't making heavy use of memory (2048 bytes on a 64-bit linux OS) and use of the array for headers is helpful when avoiding ob_end_flush(). – richhallstoke May 26 '15 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.