I am trying to improve my pagespeed. I have installed nginx and changed my sites to http2. But in the gtmetrix Performance Report my css,png and js files has no expiration dates. (expiration not specified) in the Leverage browser caching recommendation. I think I have set all possible ways to do this and tried different variants.
If their are another improvements in my nginx instrution and htaccess file, feel free to post it.
nginx addictional instructions in Plesk
gzip on;
gzip_vary on;
gzip_min_length 1240;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\\.(?!.*SV1)";
gzip_proxied any;
gzip_types text/plain text/css text/javascript application/javascript application/x-javascript application/json text/xml application/xml application/xml+rss image/x-icon image/bmp image/svg+xml;
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1y;
log_not_found off;
}
htaccess-file
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain text/html
AddOutputFilterByType DEFLATE text/css text/javascript
</IfModule>
<IfModule mod_deflate.c>
<FilesMatch “\\.(js|css|html|xml)$”>
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>
<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>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html "access plus 500 seconds"
ExpiresByType text/xml "access plus 3600 seconds"
ExpiresByType image/gif "access plus 14 days"
ExpiresByType image/ico "access plus 14 days"
ExpiresByType image/jpeg "access plus 14 days"
ExpiresByType image/jpg "access plus 14 days"
ExpiresByType image/png "access plus 14 days"
ExpiresByType text/css "access plus 14 days"
ExpiresByType text/javascript "access plus 14 days"
ExpiresByType application/x-javascript "access plus 14 days"
ExpiresByType application/javascript "access plus 14 days"
ExpiresByType application/x-shockwave-flash "access plus 1000 seconds"
ExpiresByType application/xhtml+xml "access plus 6000 seconds"
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\\.(ico|jpeg|jpg|png|gif|swf)$">
Header set Cache-Control "max-age=2629743, public"
</FilesMatch>
<FilesMatch "\\.(css)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\\.(js)$">
Header set Cache-Control "max-age=216000, private"
</FilesMatch>
#<FilesMatch "\\.(xhtml|html|htm|php)$">
#Header set Cache-Control "max-age=600, private, must-revalidate"
#</FilesMatch>
</IfModule>
AddType application/x-httpd-php .xml
You need to check and setup Etag header for optimization of page loading.
When we setting up browser caching, we should to keep one main rule:
"If file was once loaded by browser,
browser should not load this file again if this file wasn`t changed." Browser should to take this file from cache.
During every reloading of page, browser should to check, which of file was modified on the server and which not.
For those purposes in HTTP protocol we have ETag header which browser receiving from server in first file request
and in the next requests browser will send value of that header as value of header If-None-Match or If-non-modified-since.
This comunication between browser and server will looks like that:
First request:
GET /file.css HTTP/1.1
Host: example.com\r\n\r\n
First response:
HTTP/1.1 200 OK
Content-Type: text/css; charset=UTF-8
Cache-Control: public, must-revalidate
ETag:W/"51f2d-dEW1Z5fvR5lLvYGJeS4DTZdaxAs"
--There is content of file--
Second request:
GET /file.css HTTP/1.1
If-None-Match:W/"51f2d-dEW1Z5fvR5lLvYGJeS4DTZdaxAs"
Host: example.com\r\n\r\n
Second response:
HTTP/1.1 304 Not Modified
--There is no content--
Pay attention for:
ETag:W/"51f2d-dEW1Z5fvR5lLvYGJeS4DTZdaxAs" in first response
and
If-None-Match:W/"51f2d-dEW1Z5fvR5lLvYGJeS4DTZdaxAs"
in second request
In this case when we received "304 Not Modified" Browser will pull up this file from cache
and this file will have endless expiration. If file will be changed, Etag value will be changed and all
browsers will reload this file from server and update their cache.
Even when you have dynamical content rendering with php or something else, nginx will compute value of Etag
after content is rendered and check before send response to browser;
For loading optimization you need to set up Etag header in server.
And this aproach:
ExpiresByType image/jpg "access plus 14 days"
to file caching is incorrect.
You can use that only for main html request.
Because Expiration header is useful for search engines like google.
It tells them when they are need to reindex your page.
How to setup Etag you can see here.
Related
I've fine tuned the .htaccess file but could not make the Leveraged Browser Cache to work. GTMetrix tells me several .png and .svg images have no Expiration set.
1. Expires_module is enabled and running in Apache
2. Set Cache-Control and Enable Browser Cache are setup at the .htaccess.
The .htaccess code is below. Any advice to make browser caching work is welcome. :-)
#Set Cache-Control
<FilesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|svg|js|css|swf)$">
Header set Cache-Control "max-age=84600, public"
#End Cache-Control
</FilesMatch>
#Enable browser cache
<IfModule mod_expires.c>
ExpiresActive On
# Images
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
# Video
ExpiresByType video/mp4 "access plus 1 year"
ExpiresByType video/mpeg "access plus 1 year"
# CSS, JavaScript
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
# Others
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
</IfModule>
#End browser cache
#Enable HSTS
you need to ensure to Enable mod_expires on CentOS and Ubuntu,
Run following command on your CentOS system to see if Apache module mod_expires is enabled or not, It should show following output if enabled, otherwise you’ll see nothing in output.
httpd -M | grep expires
Another way to verify it is via httpd.conf file, open apache configuration file in your favorite text editor application (Vi/ViM, Nano etc) and search for following line. If successfully found, then your Apache has mod_expires enabled.
LoadModule expires_module modules/mod_expires.so
For Ubuntu system, we need to use a2enmod utility to enable Apache modules, simply run following command to enable expires module on Ubuntu.
sudo a2enmod expires
Once done, we need to restart apache for this change to take effect.
sudo /etc/init.d/apache2 restart
or
sudo service apache2 restart
Then go to GTmetrics or Google PageSpeed and test your url for "Browser Leverage caching" and check if cache time is updated as per your entry in .htaccess
I have an EC2 instance running Elastic Beanstalk. I would like to enable GZIP Compression, and I understand I need to modify my .htaccess file.
I have read that the .htaccess file is located in my root folder of the app install. However, I cannot seem to find it. (I am pretty novice and not sure where the root folder is).
I am able to ssh onto the server running Apache Tomcat 8 with a Java 8 app.
Question
Where is .htaccess located?
This is what I have in my root:
$ ls
bin cgroup etc lib local media opt root sbin srv tmp var
boot dev home lib64 lost+found mnt proc run selinux sys usr
UPDATE
I have a .ebextensions/tomcat-settings.config now that works. It enables GZip compression.
option_settings:
aws:elasticbeanstalk:environment:proxy:
GzipCompression: 'true'
ProxyServer: nginx
aws:elasticbeanstalk:environment:proxy:staticfiles:
/pub: public
This does not seem to compress .svg files though. So if possible, I would like to have the following, but not sure where to add it:
## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType image/svg "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType text/html "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"
</IfModule>
## EXPIRES CACHING ##
you need to upload .htaccess file or make it in your ec2 instance on your root folder on that you upload your application, if you are using elastick beanstalk you need to add the .htaccess file to your .zip file on the root folder
How you configured the ec2 instance, by ssh or by the .ebextensions file?
if you configure the instance by ssh and you are using a elastic enviorment then the configuration will be erased when the instance is degraded or change, if you are using only one instance by ec2 the configuration keep working.
if you need to configure it by .ebextensions you need to create a folder named .ebextensions in your .zip file, inside this folder you need to create two files named enable_mod_deflate.conf and myapp.config.
The contents of enable_mod_deflate.conf:
# mod_deflate configuration
<IfModule mod_deflate.c>
# Restrict compression to these MIME types
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xml+rss
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE image/png
AddOutputFilterByType DEFLATE image/gif
AddOutputFilterByType DEFLATE image/jpeg
# Level of compression (Highest 9 - Lowest 1)
DeflateCompressionLevel 9
# Netscape 4.x has some problems.
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
<IfModule mod_headers.c>
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</IfModule>
</IfModule>
The contents of myapp.config:
container_commands:
01_setup_apache:
command: "cp .ebextensions/enable_mod_deflate.conf /etc/httpd/conf.d/enable_mod_deflate.conf"
Then you need to restart the server.
I have a Joomla site, running on an Apache server and am having problems with Firefox and Chrome browsers caching the page and not serving the latest version.
I have added this code to my htaccess file:
<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# Default directive
ExpiresDefault "access plus 60 seconds"
# My favicon
ExpiresByType image/x-icon "access plus 1 month"
# Images
ExpiresByType image/gif "access plus 1 week"
ExpiresByType image/png "access plus 1 week"
ExpiresByType image/jpg "access plus 1 week"
ExpiresByType image/jpeg "access plus 1 week"
# CSS
ExpiresByType text/css "access plus 1 week"
# Javascript
ExpiresByType application/javascript "access plus 1 week"
</IfModule>
If I clear the browser cache in Chrome and Firefox then load the site, I get the correct response headers for images, css and javascript as per the code above.
For the main document I get these respond headers on the first load:
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Expires: Wed, 17 Aug 2005 00:00:00 GMT
Pragma: no-cache
But when I reload the page or even open it in a new tab those expires headers disappear, and the browser loads up the cached web page (with status code 304 not modified).
I'm at a loss to understand what is happening here. I'm on a mac and use Safari which doesn't have any of these issues so I'm puzzled why Chrome and Firefox don't behave the way I expect them to.
Perhaps it could be explained why the page has a different set of response headers in relation to the expires than the default in htaccess. Is this the way mod_expires works?
I hope there's enough info here to answer my query, thanks in advance.
this will help, take ref. by this link
http://php.net/manual/de/function.session-cache-limiter.php
I used Chrome to audit my site and I discovered .js and .css files weren't being cached though I had set up my .htaccess file to do so.
I removed everything from my site's root htaccess file except the code below and I'm still getting the message "The following resources are explicitly non-cacheable. Consider making them cacheable if possible" in Chrome indicating my main external .js and .css files aren't being cached. These files and images represent like 90% of the total download size so not being able to cache them is driving me crazy.
This is currently the code of my .htaccess file. Having it exactly like this still doens't cache anything.
# Disable Etags
Header unset ETag
FileETag None
# Expires
ExpiresActive On
ExpiresDefault "access plus 1 year"
Header unset Last-Modified
Header set Cache-Control "public"
<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi|html?)$">
Header set Cache-Control "private, must-revalidate, proxy-revalidate"
ExpiresDefault A0
ExpiresActive Off
</FilesMatch>
# Enable Compresion
<FilesMatch ".(js|css|html|htm|php|xml)$">
SetOutputFilter DEFLATE
</FilesMatch>
You can see this code not working at http://lujanventas.com
How can I set cache control public to .css, .js and image files?
I'm not an expert with cache controls and expire headers, but I always use this code and it always works (I'm not quite sure if that's what you are looking for but I post it anyway, see if it works for you or not) :
#################
# CACHE HEADERS #
#################
## BEGIN Expire headers
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 7200 seconds"
ExpiresDefault "access plus 1 seconds"
ExpiresByType image/jpg "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
AddType image/x-icon .ico
ExpiresByType image/ico "access plus 2592000 seconds"
ExpiresByType image/icon "access plus 2592000 seconds"
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType text/css "access plus 2592000 seconds"
ExpiresByType text/javascript "access plus 2592000 seconds"
ExpiresByType text/html "access plus 7200 seconds"
ExpiresByType text/html "access plus 1 seconds"
ExpiresByType application/xhtml+xml "access plus 7200 seconds"
ExpiresByType application/xhtml+xml "access plus 1 seconds"
ExpiresByType application/javascript "access plus 2592000 seconds"
ExpiresByType application/x-javascript "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
</IfModule>
## END Expire headers
#################
# CACHE CONTROL #
#################
## BEGIN Cache-Control Headers
<IfModule mod_headers.c>
<FilesMatch "\\.(ico|jpe?g|png|gif|swf|gz|ttf)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\\.(css)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\\.(js)$">
Header set Cache-Control "max-age=2592000, private"
</FilesMatch>
<filesMatch "\\.(html|htm)$">
Header set Cache-Control "max-age=7200, public"
Header set Cache-Control "max-age=1, public"
</filesMatch>
# Disable caching for scripts and other dynamic files
<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$">
Header unset Cache-Control
</FilesMatch>
</IfModule>
## END Cache-Control Headers
########
# ETAG #
########
## KILL THEM ETAGS
Header unset ETag
FileETag none
At the moment of writing, your running server generates headers that way for JavaScript:
Expires: access plus 1 day
This is incorrect, it should have been replaced by effective date and time. So it explains no browser is able to cache the resource properly.
According to documentation, there is no reason why it does not work.
Is there any hidden character in your configuration that prevents Apache2 to parse the line properly ? Try to delete the line ExpiresDefault line and type it again from scratch in an reliable text editor.
If still failing, where does your Apache2 version/binary comes from ?
ExpiresActive On
ExpiresDefault A0
# 1 Week expire
<filesMatch "\.(gif|jpg|jpeg|png|swf|css|js)$">
ExpiresDefault A604800
Header append Cache-Control "public"
</filesMatch>
#No caching
<filesMatch "\.(pl|php|cgi|spl|scgi|fcgi|html)$">
ExpiresActive Off
Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
Header set Pragma "no-cache"
I believe this should work.
In your config file modify:
Header set Cache-Control "public"
to look like
Header set Cache-Control "public max-age=31536000"
So your files get cached for at least a year (max-age is in seconds).
Why? I loaded your page twice and i saw the request sends a max-age=0
Also, check out this page, it gives some insights in the mod_expires module.
I inputted the following into my ".htacces" file in order to start caching the Web Content. According to Google Page Speed and Yslow the pages are still not Cached. Are the modules wrong? Or is it that the apps are not showing the data correctly?
Site is running on Apache 2.0 on Server
.htaccess (part with caching modules):
# Expire headers
<ifModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 seconds"
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 216000 seconds"
ExpiresByType application/javascript "access plus 216000 seconds"
ExpiresByType application/x-javascript "access plus 216000 seconds"
ExpiresByType text/html "access plus 600 seconds"
ExpiresByType application/xhtml+xml "access plus 600 seconds"
</ifModule>
# Cache-Control Headers
<ifModule mod_headers.c>
#month
<filesMatch "\.(ico|jpe?g|png|gif|swf)$">
Header set Cache-Control "max-age=2592000, public"
</filesMatch>
#week
<filesMatch "\.(css|js)$">
Header set Cache-Control "max-age=604800, public"
</filesMatch>
#day
<filesMatch "\.(x?html?|php)$">
Header set Cache-Control "max-age=43200, private, must-revalidate"
</filesMatch>
</ifModule>
# END Cache-Control Headers
# Turn ETags Off
<ifModule mod_headers.c>
Header unset ETag
</ifModule>
FileETag None
# Remove Last-Modified Header
<ifModule mod_headers.c>
Header unset Last-Modified
</ifModule>
Go into httpd.conf and look for the mod_expires line, it should not be commented out. Look for the mod_headers line and make sure it is not commented out.
Or (not for a critical app) there is an easy and dirty test: remove <ifModule mod_expires.c> and </ifModule> leave stuff in between, same goes for <ifModule mod_headers.c> and if your server fails with 500 internet Server Error then your probably missing one or both of those modules and they are not enabled. If so then go into httpd.conf and enable what you need.
You can also test your site's response headers using a tool like REDbot. Simply pick a resource URL like one pointing to an image and paste it in the tool to see what headers get sent back along with some recommendations. Note that it follows the domain's robots.txt rules and will not check the resource if it is disallowed.
And like Gerben said, using the net tab in firefox, chrome dev tools, or some equivalent web developer tool helps see what headers are being sent and received.
You also don't need to set Cache-Control public. And you don't need to use max age if you're also using ExpiresByType calls.
For more info read this great tutorial: http://www.mnot.net/cache_docs/
And learn by example: checkout how it is done in the html5-boilerplate at https://github.com/h5bp/html5-boilerplate/blob/master/dist/.htaccess
For other popular server config examples like lighthttpd, Node.js, Nginx, etc. see:
https://github.com/h5bp/server-configs