Alex Reynolds
Alex Reynolds

Reputation: 96976

How to send compressed (deflated) SVG via Apache2?

I have specified the following attributes in my site's .htaccess file:

AddOutputFilterByType DEFLATE image/svg+xml
DeflateCompressionLevel 9
Header append Vary Accept-Encoding

However, my SVG asset is not being sent in compressed form:

$ curl https://example.org/assets/svg/asset.svg --silent -H "Accept-Encoding: gzip,deflate" --write-out "${size_download}\n" --output /dev/null                 
152655                                                                                                                                                                                                                                  
$ curl https://example.org/assets/svg/asset.svg --silent --write-out "%{size_download}\n" --output /dev/null
152655

I verified that this asset (asset.svg) is being sent with MIME type image/svg+xml using Chrome, but using the Web Developer tools, this specific file is not being compressed when sent to the client.

Adding other MIME types to the .htaccess file is successful (e.g., adding text/html compresses the HTML assets).

This seems specific to how SVG data are handled. What else can I try or troubleshoot to get SVG compression working?

Upvotes: 39

Views: 39121

Answers (5)

Reeno
Reeno

Reputation: 5705

If Apache doesn't know the mime type of the file (here image/svg+xml), you need to tell it specifically (not needed in most Apaches):

AddType image/svg+xml svg svgz

Now when Apache knows about the filetype, just add this to deflate it:

AddOutputFilterByType DEFLATE image/svg+xml

For more information see https://httpd.apache.org/docs/2.4/mod/mod_deflate.html

Upvotes: 75

Fabio Albertoni
Fabio Albertoni

Reputation: 21

Best option I found is to compress everything except images, which mod_deflate isn't able to handle it.

add following lines to httpd.conf file:

LoadModule deflate_module modules/mod_deflate.so

SetOutputFilter DEFLATE

BrowserMatch ^Mozilla/4 gzip-only-text/html

BrowserMatch ^Mozilla/4\.0[678] no-gzip

BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

SetEnvIfNoCase Request_URI \

\.(?:gif|jpe?g|png|exe)$ no-gzip dont-vary

If u want to see logging of what was compressed add the following also:

DeflateFilterNote Input instream

DeflateFilterNote Output outstream

DeflateFilterNote Ratio ratio

LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate

CustomLog logs/deflate_log deflate

Upvotes: 2

Siva Tumma
Siva Tumma

Reputation: 1701

On some inspection in error.log of my apache httpd, It looks like we should not specify DeflateCompressionLevel here...

[Mon Feb 03 23:56:52 2014] [alert] [client 127.0.0.1] /var/www/.htaccess:DeflateCompressionLevel not allowed here

... So I have removed compression level and put only the AddOutputFilterByType DEFLATE image/svg+xml, which makes it work correctly.

Sample outputs...

with deflate...

don@don-NE56R:/var/www$ curl http://mydaddy.com:81/circle.svg -H "Accept-Encoding: gzip,deflate" --write-out "${size_download}\n"
ݶٮ;��uCL*j��z�9.�����#�_]#���̊Ve��p��$�y�D���h��þ ��|�XeP��R�

and without deflate..

don@don-NE56R:/var/www$ curl http://mydaddy.com:81/circle.svg  --write-out "${size_download}\n"
<svg height="100" width="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
  Sorry, your browser does not support inline SVG.  
</svg>

Upvotes: 0

Panama Jack
Panama Jack

Reputation: 24468

Try adding the type as well. Some configurations seem to need it for various reasons. .svg works fine for me using the AddOutputFilterByType DEFLATE image/svg+xml. Try also adding the mime type.

AddType image/svg+xml svg

Upvotes: 1

rmeakins
rmeakins

Reputation: 1329

I suspect this is due to the plus sign in the MIME type, which may need escaping in the AddOutputFilterByType directive. You can also try using the AddOutputFilter directive instead, to process all files with a certain extension:

AddOutputFilter DEFLATE svg

Upvotes: 3

Related Questions