-
-
Save Zodiac1978/3145830 to your computer and use it in GitHub Desktop.
# | |
# Sources: | |
# http://stackoverflow.com/questions/7704624/how-can-i-use-gzip-compression-for-css-and-js-files-on-my-websites | |
# http://codex.wordpress.org/Output_Compression | |
# http://www.perun.net/2009/06/06/wordpress-websites-beschleuinigen-4-ein-zwischenergebnis/#comment-61086 | |
# http://www.smashingmagazine.com/smashing-book-1/performance-optimization-for-websites-part-2-of-2/ | |
# http://gtmetrix.com/configure-entity-tags-etags.html | |
# http://de.slideshare.net/walterebert/die-htaccessrichtignutzenwchh2014 | |
# http://de.slideshare.net/walterebert/mehr-performance-fr-wordpress | |
# https://andreashecht-blog.de/4183/ | |
# | |
<IfModule mod_deflate.c> | |
# Insert filters / compress text, html, javascript, css, xml: | |
# mod_deflate can be used for Apache v2 and later and is the recommended GZip mechanism to use | |
AddOutputFilterByType DEFLATE text/plain | |
AddOutputFilterByType DEFLATE text/javascript | |
AddOutputFilterByType DEFLATE text/html | |
AddOutputFilterByType DEFLATE text/xml | |
AddOutputFilterByType DEFLATE text/css | |
AddOutputFilterByType DEFLATE text/vtt | |
AddOutputFilterByType DEFLATE text/x-component | |
AddOutputFilterByType DEFLATE application/xml | |
AddOutputFilterByType DEFLATE application/xhtml+xml | |
AddOutputFilterByType DEFLATE application/rss+xml | |
AddOutputFilterByType DEFLATE application/js | |
AddOutputFilterByType DEFLATE application/javascript | |
AddOutputFilterByType DEFLATE application/x-javascript | |
AddOutputFilterByType DEFLATE application/x-httpd-php | |
AddOutputFilterByType DEFLATE application/x-httpd-fastphp | |
AddOutputFilterByType DEFLATE application/atom+xml | |
AddOutputFilterByType DEFLATE application/json | |
AddOutputFilterByType DEFLATE application/ld+json | |
AddOutputFilterByType DEFLATE application/vnd.ms-fontobject | |
AddOutputFilterByType DEFLATE application/x-font-ttf | |
AddOutputFilterByType DEFLATE application/font-sfnt | |
AddOutputFilterByType DEFLATE application/x-web-app-manifest+json | |
AddOutputFilterByType DEFLATE font/opentype | |
AddOutputFilterByType DEFLATE font/otf | |
AddOutputFilterByType DEFLATE font/ttf | |
AddOutputFilterByType DEFLATE font/sfnt | |
AddOutputFilterByType DEFLATE image/svg+xml | |
AddOutputFilterByType DEFLATE image/x-icon | |
# Exception: Images | |
SetEnvIfNoCase REQUEST_URI \.(?:gif|jpg|jpeg|png)$ no-gzip dont-vary | |
# Drop problematic browsers | |
BrowserMatch ^Mozilla/4 gzip-only-text/html | |
BrowserMatch ^Mozilla/4\.0[678] no-gzip | |
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html | |
# Make sure proxies don't deliver the wrong content | |
<IfModule mod_headers.c> | |
Header append Vary User-Agent env=!dont-vary | |
</IfModule> | |
</IfModule> | |
# mod_gzip is an external extension and last updated 2015, so | |
# if available please use mod_deflate instead | |
# If you are stuck on Apache v1.3 you can use mod_zip to enable Gzip | |
# as mod_deflate is available for Apache v2 or later only. | |
<IfModule mod_gzip.c> | |
mod_gzip_on Yes | |
mod_gzip_dechunk Yes | |
mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$ | |
mod_gzip_item_include handler ^cgi-script$ | |
mod_gzip_item_include mime ^text/.* | |
mod_gzip_item_include mime ^application/x-javascript.* | |
mod_gzip_item_exclude mime ^image/.* | |
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* | |
</IfModule> | |
## EXPIRES CACHING ## | |
<IfModule mod_expires.c> | |
ExpiresActive On | |
ExpiresDefault "access plus 1 week" | |
ExpiresByType text/css "access plus 1 month" | |
ExpiresByType application/atom+xml "access plus 1 hour" | |
ExpiresByType application/rdf+xml "access plus 1 hour" | |
ExpiresByType application/rss+xml "access plus 1 hour" | |
ExpiresByType application/json "access plus 0 seconds" | |
ExpiresByType application/ld+json "access plus 0 seconds" | |
ExpiresByType application/schema+json "access plus 0 seconds" | |
ExpiresByType application/vnd.geo+json "access plus 0 seconds" | |
ExpiresByType application/xml "access plus 0 seconds" | |
ExpiresByType text/xml "access plus 0 seconds" | |
ExpiresByType image/x-icon "access plus 1 month" | |
ExpiresByType image/vnd.microsoft.icon "access plus 1 month" | |
ExpiresByType text/html "access plus 1 minute" | |
ExpiresByType text/javascript "access plus 1 month" | |
ExpiresByType text/x-javascript "access plus 1 month" | |
ExpiresByType application/javascript "access plus 1 months" | |
ExpiresByType application/x-javascript "access plus 1 months" | |
ExpiresByType image/jpg "access plus 1 month" | |
ExpiresByType image/jpeg "access plus 1 month" | |
ExpiresByType image/gif "access plus 1 month" | |
ExpiresByType image/png "access plus 1 month" | |
ExpiresByType image/svg+xml "access plus 1 month" | |
ExpiresByType image/bmp "access plus 1 month" | |
ExpiresByType image/webp "access plus 1 month" | |
ExpiresByType audio/ogg "access plus 1 month" | |
ExpiresByType video/mp4 "access plus 1 month" | |
ExpiresByType video/ogg "access plus 1 month" | |
ExpiresByType video/webm "access plus 1 month" | |
ExpiresByType text/plain "access plus 1 month" | |
ExpiresByType text/x-component "access plus 1 month" | |
ExpiresByType application/manifest+json "access plus 1 week" | |
ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds" | |
ExpiresByType text/cache-manifest "access plus 0 seconds" | |
ExpiresByType application/pdf "access plus 1 month" | |
ExpiresByType application/x-shockwave-flash "access plus 1 month" | |
ExpiresByType application/vnd.ms-fontobject "access plus 1 month" | |
ExpiresByType font/eot "access plus 1 month" | |
ExpiresByType font/opentype "access plus 1 month" | |
ExpiresByType application/x-font-ttf "access plus 1 month" | |
ExpiresByType application/font-woff "access plus 1 month" | |
ExpiresByType application/font-woff2 "access plus 1 month" | |
ExpiresByType application/x-font-woff "access plus 1 month" | |
ExpiresByType font/woff "access plus 1 month" | |
ExpiresByType font/woff2 "access plus 1 month" | |
</IfModule> | |
## EXPIRES CACHING ## | |
#Alternative caching using Apache's "mod_headers", if it's installed. | |
#Caching of common files - ENABLED | |
<IfModule mod_headers.c> | |
# 1 Month | |
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$"> | |
Header set Cache-Control "max-age=2592000, public" | |
</FilesMatch> | |
# 2 DAYS | |
<FilesMatch "\.(xml|txt)$"> | |
Header set Cache-Control "max-age=172800, public, must-revalidate" | |
</FilesMatch> | |
# 2 HOURS | |
<FilesMatch "\.(html|htm)$"> | |
Header set Cache-Control "max-age=7200, must-revalidate" | |
</FilesMatch> | |
</IfModule> | |
<IfModule mod_headers.c> | |
<FilesMatch "\.(js|css|xml|gz|html|ttf)$"> | |
Header append Vary: Accept-Encoding | |
</FilesMatch> | |
</IfModule> | |
# Set Keep Alive Header | |
# This *just* sets the header - maybe your hoster is not allowing this feature | |
# Please check if it is working with tools like http://www.webpagetest.org | |
<IfModule mod_headers.c> | |
Header set Connection keep-alive | |
</IfModule> | |
# If your server don't support ETags deactivate with "None" (and remove header) | |
<IfModule mod_expires.c> | |
<IfModule mod_headers.c> | |
Header unset ETag | |
</IfModule> | |
FileETag None | |
</IfModule> |
Hi. Very nice code.
I use it and still pingdom tells me
Leverage browser caching
The following cacheable resources have a short freshness lifetime. Specify an expiration at least one week in the future for the following resources:
https://assets.pinterest.com/js/pinit.js
https://assets.pinterest.com/js/pinit_main.js?0.9677980106789619
https://connect.facebook.net/en_US/all.js
https://apis.google.com/js/plusone.js
https://platform.twitter.com/widgets.js
https://fonts.googleapis.com/css?family=Oswald%3A400%2C700%2C300&ver=4.6.1
<<<<
Why?
Update: Found out myself.
Had to add following line:
AddOutputFilterByType DEFLATE text/javascript
<<<
Works on two sites, but one site gives me an "Internel Server Error 500", when adding following line:
Header append Vary User-Agent env=!dont-vary
<<<
PageSpeed Insights Errors:
/fonts/RobotoBold/RobotoBold.woff (expiration not specified)
/fonts/RobotoRegular/RobotoRegular.woff (expiration not specified)
/js/common.js (expiration not specified)
/js/libs.min.js (expiration not specified)
How it fix?
@fengler-it These assets are all from an external server, so your change shouldn't have any impact.
@fengler-it I missed to add a check to this line. Is fixed now. Thanks for the heads up!
@Vvvetal-90 Woff is already compressed, no need to do it again, see: https://gist.github.com/Zodiac1978/3145830#gistcomment-1681099
About js files: Have you tried AddOutputFilterByType DEFLATE text/javascript
?
Hey Thorsten, my Javascripts weren't correctly cached, I think you should update your gist with the following (after that everything has been cached perfectly):
AddOutputFilterByType DEFLATE text/javascript
Edit: Sorry, just read your post above. Isn't it a good idea to update the gist anyway?
@ginocremer I've added the line. Thanks for the reminder!
Hi Zodiac1978. I just stepped into this and have been having trouble with fluctuating CPU performance jumping anywhere from 30% to beyond 77% in an instance. Not a whole lot of traffic when this is happening. This is my complete .htaccess file now.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# Default directive
ExpiresDefault "access plus 1 month"
# My favicon
ExpiresByType image/x-icon "access plus 1 year"
# Images
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 month"
# Javascript
ExpiresByType application/javascript "access plus 1 year"
</IfModule>
# END WordPress
i added the ifmodule mod_expires portion. can you give me complete i can use so as to cover everything else. Still getting low performance from test on gtMetrics. Here's message i get now.
There are 12 static components without a far-future expiration date.
https://fonts.googleapis.com/css?family=Poppins%3A300%2C400%2C500%2C600%2C700%7CLibre+Baskerville%3A400italic&subset=latin%2Clatin-ext&ver=4.8.2
https://bestfitbybrazil.com/wp-content/plugins/wp-spamshield/js/jscripts.php
https://www.livehelpnow.net/lhn/widgets/chatbutton/lhnchatbutton-current.min.js
https://apis.google.com/js/platform.js?onload=renderBadge
https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit2
https://www.google-analytics.com/analytics.js
https://translate.googleapis.com/translate_static/css/translateelement.css
https://translate.googleapis.com/translate_static/js/element/main.js
https://loader.wisepops.com/get-loader.js?v=1&user_id=2166
https://popup.wisepops.com/my-wisepop?uid=2166
https://translate.googleapis.com/translate_a/l?client=te&alpha=true&hl=en&cb=_callbacks____0j8stitkp
https://www.livehelpnow.net/lhn/scripts/livehelpnow.min.aspx?lhnid=19096&iv=0&ivid=0&d=0&ver=5.3&rnd=0.8954146259070273
The second "High priority" fix needed is:
Make fewer HTTP requests | F (0) | CONTENT | HIGH |
---|---|---|---|
What's this mean?This page has 82 external Javascript scripts. Try combining them into one.This page has 39 external stylesheets. Try combining them into one. |
Why not combine some of the rules, for example.
#Alternative caching using Apache's "mod_headers", if it's installed.
#Caching of common files - ENABLED
<IfModule mod_headers.c>
<FilesMatch "\.(ico|pdf|flv|swf|js|css|gif|png|jpg|jpeg|txt|html|htm)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\.(js|css|xml|gz)$">
Header append Vary Accept-Encoding
</FilesMatch>
# Set Keep Alive Header
# This *just* sets the header - maybe your hoster is not allowing this feature
# Please check if it is working with tools like http://www.webpagetest.org
Header set Connection keep-alive
</IfModule>
@bestfitbybrazil 11 of 12 of these files are not on your server, but on 3rd-party-sites, so you cannot cache them with a server setting on your server. ;) The second one is on your server, but is dynamically generated (PHP file generating JS I assume). Not meant to be cached.
82 JS files + 39 CSS files are really a huge amount of files. You should definitely try to get rid of them. Caching is good, but doesn't solve the issue of having too much files loaded.
If you have reduced this to a smaller amount of files you can try to combine them with a tool like Autoptimize.
@APlusDesign Nice idea, but I prefer the longer, more readable version. :)
how to fix?!
The following cacheable resources have a short freshness lifetime. Specify an expiration at least one week in the future for the following resources:
http://..../wp-content/themes/Life/svg/f_discord1.svg
This should not happen because of https://gist.github.com/Zodiac1978/3145830#file-htaccess-L63
Please check the MIME type the server is using for this SVG @PSAiridas
Thanks for sharing!
I'm using Wordpress with VueJS and i can't get the wp-json responses gzipped
Copied this htaccess to both my /
where the Frontend is located and for /be
where my wordpress is located
This is what pingdom is telling me:
The following cacheable resources have a short freshness lifetime. Specify an expiration at least one week in the future for the following resources:
https://site.com/be/wp-json/wp-api-menus/v2/menu-locations/footer-menu
https://site.com/be/wp-json/wp-api-menus/v2/menu-locations/header-menu
https://site.com/be/wp-json/wp/v2/projects
The following resources are missing a cache validator. Resources that do not specify a cache validator cannot be refreshed efficiently. Specify a Last-Modified or ETag header to enable cache validation for the following resources:
https://site.com/be/wp-json/wp-api-menus/v2/menu-locations/footer-menu
https://site.com/be/wp-json/wp-api-menus/v2/menu-locations/header-menu
https://site.com/be/wp-json/wp/v2/projects
The following publicly cacheable, compressible resources should have a "Vary: Accept-Encoding" header:
https://site.com/be/wp-json/wp-api-menus/v2/menu-locations/footer-menu
https://site.com/be/wp-json/wp-api-menus/v2/menu-locations/header-menu
https://site.com/be/wp-json/wp/v2/projects
mod_deflate is now the recommended option over mod_gzip.
Hi @mortensassi this should be working if your host is using mod_deflate
because of these lines:
https://gist.github.com/Zodiac1978/3145830#file-htaccess-L30-L31
Hi @codeclinic - what do you recommend to change (as this gist is using mod_gzip
and mod_deflate
)?
mod_gzip
is legacy module Apache 1.3 and bellow.
mod_deflate
is compatible with Apache 2.0 and above.
@yashodhank Thanks for the explanation. I will add some more explanations as comments!
Thanks for the Gist ! Very helpful.
In our case, we used the "modification" flag for the mod_expires
.
Example :
ExpiresByType text/javascript "modification plus 1 year"
Update: Added some more font mime types: font/sfnt
, application/font-sfnt
, font/otf
and font/ttf
If using CDN, will editing .htaccess have any effect? Since the request is served by the CDN and not the server?
@Barnabas2 No, if the item is loaded from an external CDN the settings from your server (htaccess) have, of course, no effect.
Hello, according to google page speed I don't have the compression of the following files enabled
…css/bootstrap.min.css , …remixicon/remixicon.css, …jquery/jquery.min.js and more but checking the compression in https://www.websiteplanet.com/es/webtools/gzip-compression/ compression is active ... why could google pagespeed not recognize compression?
@cutcool I recommend to use https://www.webpagetest.org/ - this will give you more insights. If you use this .htaccess
settings from above this shouldn't happen if those files are hosted on your server, because CSS and JS files should be compressed.
Are those files really hosted on your server and not from a CDN? Is your server using the mod_deflate
module? You can check via phpinfo()
(under "Loaded Modules"). (Or mod_gzip
if you are on Apache <=1.3)
Hello, thank you for sharing that
But, is that work with WordPress ?
@monty88 Yes, it is working with WordPress.
Is there an advantage to caching using both mod_expires ( ExpiresByType...) and mod_headers (Header set Cache-Control...) or is it better to choose one or the other?
Can we use this code for all type of websites like custom base and cms base? I want to optimize speed of my custom retail packing box website. Is it possible with this code?
@wagersantonio Yes, there is no specific CMS required. It works if you are using Apache and you have the permission to adjust settings via .htaccess
file. Just read the inline comments and modify according to your setup.
Cool. Gave me 2 % better performance! :-)