Want to subscribe to topics you're interested in?
Become a Member

Nginx Varying HTTP Headers Sent for SVG Files <1KB?

Discussion in 'Nginx, PHP-FPM & MariaDB MySQL' started by deltahf, Apr 3, 2016.

  1. deltahf

    deltahf Active Member

    207
    101
    43
    Jun 8, 2014
    Ratings:
    +154
    Local Time:
    7:31 PM
    I'm re-designing my site, making extensive use of SVG graphics. When I loaded the new images onto my server and began testing, I noticed that all but three of the SVGs "flickered" or blinked between each page load. The effect only occurs in Google Chrome - other browsers are unaffected. Because they are in the header, this is a very annoying effect and must be fixed.

    I investigated by looking at the headers; sure enough, different headers are sent for the images which do not flicker and those which do.

    Here are the headers for an SVG Facebook icon, which does not flicker:
    Code:
    accept-ranges:bytes
    cache-control:max-age=2592000
    cache-control:public, must-revalidate, proxy-revalidate
    content-length:674
    content-type:image/svg+xml
    date:Sat, 02 Apr 2016 19:39:37 GMT
    etag:"56fef1c8-2a2"
    expires:Mon, 02 May 2016 19:39:37 GMT
    last-modified:Fri, 01 Apr 2016 22:10:16 GMT
    server:nginx
    status:200
    Here are the headers for an Instagram SVG icon, which does flicker:
    Code:
    cache-control:max-age=2592000, public, must-revalidate, proxy-revalidate
    content-encoding:gzip
    content-type:image/svg+xml
    date:Sat, 02 Apr 2016 19:39:37 GMT
    etag:W/"56ff1731-13bd"
    expires:Mon, 02 May 2016 19:39:37 GMT
    last-modified:Sat, 02 Apr 2016 00:49:53 GMT
    server:nginx
    status:200
    vary:Accept-Encoding
    Here are the major points of difference that I found:
    • The non-flickering images are less than 1KB in size. To verify this, I added comments into the SVG markup for the Facebook icon to boost its size over 1KB; its headers then matched the other images and it began to flicker between page loads.
    • The non-flickering images are not gzipped.
    • The non-flickering images have multiple "cache-control" headers.
    • The flickering images do not have a "content-length" header.
    • The flickering images do not have "vary" or "accept-ranges" headers.
    There are no changes to my Nginx configuration that I'm aware of which would be affecting this. I'm using the default staticfiles.conf setup included in Centminmod. Any ideas as to what might be causing this difference, and how I might be able solve this problem?
     
  2. eva2000

    eva2000 Administrator Staff Member

    30,166
    6,784
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +10,136
    Local Time:
    9:31 AM
    Nginx 1.13.x
    MariaDB 5.5
    Centmin Mod default static files include file at /usr/local/nginx/conf/staticfiles.conf handles .svg and other static files via Nginx. This include file is usually included in the default generated Nginx site domain vhost i.e. domain.com.conf or domain.com.ssl.conf. Can you post contents of your /usr/local/nginx/conf/staticfiles.conf. Might want to use CODE tags for code How to use forum BBCODE code tags :)

    Also might want to check /usr/local/nginx/conf/nginx.conf and the gzip_min_length setting as SVG files are compressable you may have that option set to ~1000 bytes or roughly 1KB example at centminmod/nginx.conf at 123.09beta01 · centminmod/centminmod · GitHub

    Code (Text):
        gzip on;
        gzip_vary   on;
        gzip_disable "MSIE [1-6]\.";
            gzip_static on;
            gzip_min_length   1400;
            gzip_buffers      32 8k;
            gzip_http_version 1.0;
            gzip_comp_level 5;
            gzip_proxied    any;
            gzip_types text/plain text/css text/xml application/javascript application/x-javascript application/xml application/xml+rss application/ecmascript application/json image/svg+xml;

    You can see gzip_types includes image/svg+xml
    Code (Text):
    gzip_types text/plain text/css text/xml application/javascript application/x-javascript application/xml application/xml+rss application/ecmascript application/json image/svg+xml;

    Since Nginx has gzip_static enabled by default, you can try just pre-gzipping your .svg images instead of getting Nginx to gzip compress on the fly i.e. image.svg

    use pigz multi threaded compression level 4 with keeping copy of non-gzipped flag
    Code (Text):
    pigz -4k image.svg

    note if you pre-gzip, then whenever you update the image, you need to re-compress the updated image, otherwise you end up serving the old pre-gzipped image due to gzip_static setting
     
    • Informative Informative x 1
  3. eva2000

    eva2000 Administrator Staff Member

    30,166
    6,784
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +10,136
    Local Time:
    9:31 AM
    Nginx 1.13.x
    MariaDB 5.5
    Also might want to read Let me google that for you

    are images in CSS ? see html - Weird CSS3 Transition (flickering) - Stack Overflow

     
  4. deltahf

    deltahf Active Member

    207
    101
    43
    Jun 8, 2014
    Ratings:
    +154
    Local Time:
    7:31 PM
    Yeah, I've had a look at that. It should be the Centminmod default:
    Code (Text):
        location ~* \.(3gp|gif|jpg|jpeg|png|ico|wmv|avi|asf|asx|mpg|mpeg|mp4|pls|mp3|mid|wav|swf|flv|exe|zip|tar|rar|gz|tgz|bz2|uha|7z|doc|docx|xls|xlsx|pdf|iso)$ {
            gzip_static off;
            #add_header Pragma public;
            add_header Cache-Control "public, must-revalidate, proxy-revalidate";
            access_log off;
            expires 30d;
            break;
            }
    
        location ~* \.(js)$ {
            #add_header Pragma public;
            add_header Cache-Control "public, must-revalidate, proxy-revalidate";
            access_log off;
            expires 30d;
            break;
            }
    
        location ~* \.(css)$ {
            #add_header Pragma public;
            add_header Cache-Control "public, must-revalidate, proxy-revalidate";
            access_log off;
            expires 30d;
            break;
            }
    
        location ~* \.(html|htm|txt)$ {
            #add_header Pragma public;
            add_header Cache-Control "public, must-revalidate, proxy-revalidate";
            access_log off;
            expires 1d;
            break;
            }
    
        location ~* \.(eot|svg|ttf|woff)$ {
            #add_header Pragma public;
            add_header Cache-Control "public, must-revalidate, proxy-revalidate";
            access_log off;
            expires 30d;
            break;
            }

    Yeah, my gzip section looked exactly the same as what you posted above.

    I removed image/svg+xml from gzip_types, restarted Nginx, and did a hard reload and now all of the images are "flicker free"! Looks like that is definitely the problem!
    Just installed pigz and gave it a try. It just made a ".gz" copy of my image, which I think replaced the original with, but the image won't display in the browser. I don't think I'm using it right... :ROFLMAO:

    I have Googled the problem extensively since I discovered this yesterday. There have been a lot of SVG rendering problems reported over the years, but they all seem to deal with in-browser transformations, which I'm not doing. The SVGs are just standard background images defined in CSS. This "flicker" only occurs when you are clicking between pages, and the browser re-draws the new page.

    Actually, this can be seen on other websites. On the popular web design blog A List Apart, if you click on the various tabs in their header in Chrome, you'll see that their "laurel" logo in the top left corner "flickers" or "blinks" between each page load, which is annoying and shouldn't happen. If you look at their headers, they are using Nginx+GZIP too, via Cloudflare.

    I think it's a bug in Chrome.
     
  5. eva2000

    eva2000 Administrator Staff Member

    30,166
    6,784
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +10,136
    Local Time:
    9:31 AM
    Nginx 1.13.x
    MariaDB 5.5
    that's right, but not sure about browser issue that chrome only or all browsers ?

    yeah you can remove the gzip_types definition for images/svg+xml as a workaround. If you're using ngx_pagespeed the images should auto convert to .webp instead for smaller sizes too so don't need svg images and it's all done on the fly. Nginx pagespeed reduces total image served size by ~50% site wide. See Nginx PageSpeed - Benefits of ngx_pagespeed | Centmin Mod Community

    yeah could be, which version of Chrome ? tried Canary Chrome Browser ?
     
  6. deltahf

    deltahf Active Member

    207
    101
    43
    Jun 8, 2014
    Ratings:
    +154
    Local Time:
    7:31 PM
    Ohhh - I didn't realize Nginx would automatically find and use the ".gz" pre-compressed version of a file! That's really cool! Got it working now.

    Thanks for the suggestion. :D

    Yeah, I'm not using ngx_pagespeed; I'm afraid it will cause some problems and will introduce some more complexity into troubleshooting in the future. Those image file size savings are huge, though... I will have to get brave and enable it soon enough. :eek:
     
  7. eva2000

    eva2000 Administrator Staff Member

    30,166
    6,784
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +10,136
    Local Time:
    9:31 AM
    Nginx 1.13.x
    MariaDB 5.5
    yup nginx serves up .gz version as normal image without .gz :)
    well my forums here been using ngx_pagespeed for nearly 2yrs now - fyi next month is this forum's 2yr anniversary :D
     
    • Like Like x 1
  8. deltahf

    deltahf Active Member

    207
    101
    43
    Jun 8, 2014
    Ratings:
    +154
    Local Time:
    7:31 PM
    ARRRGGHH!!!

    I just did more testing and found the images "flicker" using pre-compression as well!!! :mad::mad::mad:

    Now I guess my only option is to serve them uncompressed or try ngx_pagespeed.
     
  9. eva2000

    eva2000 Administrator Staff Member

    30,166
    6,784
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +10,136
    Local Time:
    9:31 AM
    Nginx 1.13.x
    MariaDB 5.5
    Last edited: Apr 3, 2016
  10. deltahf

    deltahf Active Member

    207
    101
    43
    Jun 8, 2014
    Ratings:
    +154
    Local Time:
    7:31 PM
    Very interesting discussion.

    I'm not just using SVGs for file size, though. They are a lot easier to work with in the design (you can use the same image at multiple sizes, for example) and I want the pixel-density-independence so the site's template will look great on all the new retina screens coming out. I'll just bite the bullet and go with the uncompressed SVGs for now.
     
    • Informative Informative x 1