Preload Images with javascript - image-preloader

Here is my preload script:
<script type="text/javascript">
Image_1 = new Image(1,1);
Image_1.src = "images/sprites.png";
</script>
And it works fine. I can see in the headers the image loading.
Here's my question. Even though I have preloaded sprites.png, I notice that when I go to a page on my site that simply displays that entire image, the headers tell me my browser is requesting the server to send the image again.
I'm hoping to not sound too naive. But, why would the browser request the image when I preloaded it earlier? Are there other reasons the browser would need to re-request?
Also, I put the dimensions as Image(1,1). Sometimes I don't know the dimensions, as that image gets updated from time to time. Maybe that's a reason?

You need to send an Expires header with the image from the server to enable caching in the browser.
e.g. in Apache (in .htaccess)
enable expires:
ExpiresActive On
by date:
ExpiresDefault "access plus 30 days"
or by filetype:
ExpiresByType image/gif "modification plus 5 hours 3 minutes"

Related

.htaccess ExpiresDefault 1 day

If I add only these 2 lines to the .htacces file, will all the files on the website be kept in the cache for 1 day?
ExpiresActive On
ExpiresDefault "access plus 1 day"
Is it enough and it works?
ExpiresActive On
ExpiresDefault "access plus 1 day"
If you have no other overriding directives then these directives do indeed instruct the browser to cache the response for 1 day, by sending back the appropriate Expires and Cache-Control: max-age HTTP response headers. (Expires is required for old browsers. All modern browsers will use the Cache-Control header instead.)
Is it enough and it works?
Whether it is "enough" is entirely dependent on the nature of your site. Depending on your site, some responses perhaps shouldn't be cached at all, whilst other static resources should be cached for much longer.
And it's entirely possible you have other directives or even a front-end proxy or CDN that overrides these response headers.

Enable caching of css and js files in Apache

Using Apache 2.4 on Debian 8.2, I am trying to enable caching of all css and js files. Caching of images works fine; that is, the browser receives a 304 status, so it doesn't download again. But I cannot get caching of other files working.
I use this inside a virtual host file:
<IfModule mod_expires.c>
<FilesMatch "\.(jpe?g|png|gif|js|css)$">
ExpiresActive On
ExpiresDefault "access plus 1 week"
</FilesMatch>
</IfModule>
The expires module is enabled. I did restart apache, cleaned browser cookies, etc. No success.
The response for a gif image, from browser developer tools:
Cache-Control:max-age=604800
Connection:Keep-Alive
Date:Wed, 25 Nov 2015 21:37:50 GMT
ETag:"4174a-4e69c97fbf080"
Expires:Wed, 02 Dec 2015 21:37:50 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.10 (Debian)
The response for a css file:
Accept-Ranges:bytes
Cache-Control:max-age=604800
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:135
Content-Type:text/css
Date:Wed, 25 Nov 2015 21:37:50 GMT
ETag:"5116-525639d271c78-gzip"
Expires:Wed, 02 Dec 2015 21:37:50 GMT
Keep-Alive:timeout=5, max=99
Last-Modified:Wed, 25 Nov 2015 20:50:52 GMT
Server:Apache/2.4.10 (Debian)
Vary:Accept-Encoding
It looks like the expires heading is set correctly, but the browser keeps requesting the file (200 OK).
I tried with Chrome and Firefox.
Summary:
1.) When I follow links inside the web site, the browser uses the cached files. But when I press F5, they re-download the css and js files, but they don't re-download images. Images give 304. That is fine.
2.) When I press Ctrl-F5, naturally enough, all files are re-downloaded. That's fine too.
3.) So the problem is how to enable caching (just like images) for other files. Why is apache discriminating between images and other files? I didn't put anything special to images in the config files.
Q: How to properly enable caching of css and js files?
Another Q: is there a special http header that says to the browser never to request the file. The reason is, sending even a request to check if the file is modified takes 100-200 ms, which is too much. I am sure the files will not be modified. And if they are modified, I can easily put a version string at the end of the css file, such as myFile.css?v=1.1 So I hope there should be a way to stop sending requests completely.
SOLVED
First, there is a bug in apache as mentioned in the answer below.
Second, there was a misunderstanding on my part. I guess this is how modern browsers work:
1.) Follow links inside a web site: No request is sent, even to check if the file has been modified.
2.) F5: Send a request. If file is not modified then the server responds 304.
3.) Ctrl+F5: Full download.
The behavior about F5 does not make sense to me. Anyway.
In case anybody needs it, here is a working solution that I put into virtual host file:
RequestHeader edit "If-None-Match" "^\"(.*)-gzip\"$" "\"$1\""
Header edit "ETag" "^\"(.*[^g][^z][^i][^p])\"$" "\"$1-gzip\""
LoadModule expires_module /usr/lib/apache2/modules/mod_expires.so
ExpiresActive On
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
ExpiresDefault "access plus 4 weeks"
</FilesMatch>
Turn off Etags, they don't play well in Apache when gzip is on for 304s.
See here: Apache is not sending 304 response (if mod_deflate and AddOutputFilterByType is enabled)
As images are already compressed they are typically not gzipped and hence why they work.
ETags are not that useful in my opinion in their current implementation (see my blog here for a more in depth discussion as to why) so, coupled with above bug, I turn them off.
For your second question just set a long expiry.
As discussed in the comments below there are three scenarios:
Normal browsing - in which caching should be used and 304s only used if cache is still valid after expiry (in which case it's set to valid again for same expiry).
F5 or Refresh button. This is an explicit action by the user to confirm the page and all its resources are still valid so they all will be double checked (even those still in cache and still valid according to expiries header) and 304s sent when they haven't changed. It does not mean "just redownload anything which has expired but leave cached items alone as they are still valid" as you think it should. Personally I think the current implementation the browsers use makes sense and your method would be confusing to end users. While some sites may version assets like images, css and JavaScript so rechecking is a waste of time, not all such sites do this.
Ctrl+F5. This is a force refresh. It means "Ignore cache and download everything". It's rarely needed except by developers who change files requested on development servers.
Hope that all makes sense.
Edit 12 May 2016: Looks like Firefox is bringing in the functionality you actually want: https://bitsup.blogspot.ie/2016/05/cache-control-immutable.html?m=1
If nothing else seems to work, don't forget to turn the disable cache from devtools in you browser!!!

what is the correct caching directive syntax for mod_expires?

We're considering using the following caching directive in our .htaccess file
ExpiresByType text/html "access"
Is that valid syntax? And what does it mean?
My understating (and testing, in 4 major browsers has shown) is that when a client accesses the HTML file, it will remain in it's cache and be pulled from it's cache, until we modify the HTML file on our server, at which time the client will pull the file from our server and use the modified/updated copy.
The apache docs for mod_expires clearly shows the additional arguments are optional.
ExpiresByType text/html "access"
Well, it's "valid", but this effectively expires the cache instantly (unless there is another caching mechanism in place - see below).
The ExpiresByType directive simply controls the Expires and Cache-Control: max-age headers. The above directive results in the Expires header being set to now (the current time) and max-age: 0 - in other words a zero cache time.
when a client accesses the HTML file, it will remain in it's cache and be pulled from it's cache, until we modify the HTML file on our server
This is not related to the ExpiresByType directive (as mentioned above), which explicitly states "access", not "modification".
What you are probably seeing is caching as a result of the Last-Modified (Response) header and the If-Modified-Since (request) headers, but this is quite separate and not controlled by mod_expires.

apache ExpiresDefault - just doesn't work

we all know that setting expire date for static files is very useful and the way i found to do so is through the ExpiresDefault property in a .htaccess file but it just doesn't work. I am using YSlow and page_speed to test the HTTP response, but it just keep on telling me that I need to set an expire date for my JS, CSS and images to speed up my application.
I tried to test ExpiresDefault "access plus 1 year" , locally ( apache server ) and on the web ( hostgator reseller account. if I have any options to make use of !?! ) but it just doesn't work. And it also doesn't return 500 error.
I feel like I am missing the main point or doing it wrong. How the whole thing should be done ?
First, identified mod_expires is compiled inside your apache.
Try
PATH_TO_YOUR/httpd -M | sort /* <-- look for expires_module*/
And your apache configuration should be like
ExpiresActive on
ExpiresDefault "access plus 1 year"
And always restart apache after configuration changed

ExpiresActive On .htaccess explanation

[i]ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/png A2592000
BrowserMatch "MSIE" brokenvary=1
BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
BrowserMatch "Opera" !brokenvary
SetEnvIf brokenvary 1 force-no-vary[/i]
saw this code in a sample .htaccess recently.
Presumably ExpiresByType sets an expiry time on images - is that related to the visitors browser cache? and what does A2592000 translate to?
and what does the "brokenvary=1" imply? I gather it's looking for a UserAgent, but then what?
thanks!
Presumably ExpiresByType sets an expiry time on images - is that related to the visitors browser cache?
Yes. mod_expires allows an easy setup of expiration rules based on the type.
But the expiration time specifies only the freshness time of a certain response. This does not necessarily mean that the response is cacheable. But in general, any successful response is cacheable unless there are restrictions:
Unless specifically constrained by a cache-control (section 14.9) directive, a caching system MAY always store a successful response (see section 13.8) as a cache entry, MAY return it without validation if it is fresh, and MAY return it after successful validation.
So unless you specify the response not to be stored at all (i.e. using no-store), the response may be stored by both public caches (shared caches) and private caches (local caches).
And what does A2592000 translate to?
The freshness time of a response can be expressed using either an absolute time value (e.g “2010-10-09”) or a relative time value (e.g. “tomorrow”). The date format A2592000 uses a latter time value as A denotes access time and 2592000 is the number of seconds that are added. So A2592000 means “2592000 seconds from the time of access on”.
And what does the "brokenvary=1" imply? I gather it's looking for a UserAgent, but then what?
Apache has some special purpose environment variables where force-no-vary is one of them:
This causes any Vary fields to be removed from the response header before it is sent back to the client. Some clients don't interpret this field correctly; setting this variable can work around this problem. Setting this variable also implies force-response-1.0.
Now the Vary header field is used to specify a list of header field names the server used to select the response among multiple representations:
A server SHOULD use the Vary header field to inform a cache of what request-header fields were used to select among multiple representations of a cacheable response subject to server-driven negotiation.
So if you’re using content negotiation and a requested generic URL like /document.html is requested and there are multiple representations of that resource (e.g. in English and German) and your server selects the German variant as Accept-Language states the value de, the server would include a Vary field containing Accept-Language to let the caches know that the selection was based on the value of Accept-Language.
But some user agents don’t get this right. And in that cases the Vary header field should not be sent that can be done by setting the special purpose environment variable force-no-vary.
ExpiresByType is an Apache Directive of the mod_expires module that generates 'Expires' and 'Cache-control' http response headers. These headers tell a browser that it is allowed to cache the resource for a specific amount of time.
From the documententation ( http://httpd.apache.org/docs/2.0/mod/mod_expires.html ) :
'A' means the client's access time should be used.
An example from the same page might explain things:
# enable expirations
ExpiresActive On
# expire GIF images after a month in the client's cache
ExpiresByType image/gif A2592000
# HTML documents are good for a week from the
# time they were changed
ExpiresByType text/html M604800