had a quick question.
Let's say I create file stylesheet.css. In this file:
body {
background: #000000;
}
Now let's say I change the background colour, making this file version 1.0:
body {
background: #FFFFFF;
}
Would I change the link to the stylesheet to include ?v=1.0? Would that force the browser to load the stylesheet all over again with the new changes so old settings aren't cached? Also, assuming all the previous is correct, would it be good practice to commit changes based on version? So like I make changes in a stylesheet and dub them serious enough to warrant a v2.0, then just commit the stylesheet as "v2.0"? Thanks!
<link rel="stylesheet" href="stylesheet.css?v=1.0">
If the URL (this includes the querystring) is not in the browser's cache, then a new file will be requested.
Yes, this is a valid methodology for forcing version control.
This does force all browsers to reload the CSS entirely, as discussed here:
What does '?' do in a Css link?
The answer says:
That is there to add some uniqueness to the filename, so that when
they change the CSS file, they can change the extra bit to be totally
sure that every client will reload the CSS rather than use a cached
version.
The webserver will ignore the parameter and serve /Content/all.min.css
normally
StackOverflow uses this technique, by the way.
If you change the link to ?v=1.0, then you will override any caching mechanism that your server has set in place, the browser will see a new url for the style sheet, and re-download your new changes, ensuring that the user sees the new changes immediately.
If you do not append a query string, then the user will update their style sheet according to the caching settings configured on your web application, which can vary significantly depending on how it is configured / what framework you are using.
Related
I know that a common practice is to set an expire time far in the future for css, javascript and image files and then make sure that all browsers fetches the latest content as soon the files changes by appending a querystring (or changing filename) like this
From this <link rel="stylesheet" type="text/css" href="base.css">:
to this:
<link rel="stylesheet" type="text/css" href="base.css?v=1234">
or:
<link rel="stylesheet" type="text/css" href="base_1234.css">
But what about images referenced in a css file?
// Inside base.css
background: url(/img/logo.png)
// Is this necessary(?):
background: url(/img/logo.png?v=1234)
Or will /img/logo.png be reloaded when base.css changes filename to base.css?v=1234 or base_1234.css automatically?
And also, what about images in src for img-tags?
The browser is making these requests after determining an absolute path, so if you are 'cache busting' your static assets in this way, you do need to do it for each file individually, no matter where it's called. You can, however, make it easer on yourself by making it a variable on the backend.
You can append the string as a variable that you only have to update in one place on your backend, probably in conjunction with a CSS pre-processor like LESS or SASS to get all your images.
Or use relative paths to your advantage by adding the version to the base url (site.com/folder/styles.css => site.com/v123/folder/styles.css). This can be added to an existing static asset base url variable in your app, then on the server you can just use a UrlRewrite to strip out the version. This way all the images relatively referred to from your CSS automatically get the version too, having the same 'cache busting' effect.
You could be extra clever and set the variable automatically as part of your build process as the last commit hash from you version control system - which will also make future debugging easier.
From my experience the cache busting of the css is not recursive. So the querystring at the end of the image referenced in css is required to bust the cache.
To be sure all images are fresh you may want to also cache bust with the querystring version (img.png?v=1234).
Chrome seems to be the worse of the browser-bunch for not updating it's cache (perhaps due to the new predictive caching methods it's using) and the way to do this is indeed with a querystring.
This website takes it one step further and uses the simple JavaScript Date().getTime(); method (with or without jQuery) that is attached to all img tags.
Another solution is to write a javascript code so that the browser does not pick up image
from the cache and loads it everytime.
The benefit of the above is that individual image-file renaming, for the sake of the querystring, is not needed as the JavaScript handles this in one pass.
While it does use a single line of JavaScript to accomplish this, it's not as high-maintenance as tracking down every img element in a large CSS file, which can take time and add to the file size.
I noticed some websites put the version numbers (especially) in the CSS file path. For example:
<link rel="stylesheet" type="text/css" href="style.css?v=12345678" />
What is the main purpose to put the version number? If the purpose is to remember when the CSS file was updated last time, shouldn't the version number added as a comment inside the CSS file?
From HTML5 ★ Boilerplate Docs:
What is ?v=1" '?v=1' is the JavaScript/CSS Version Control with
Cachebusting
Why do you need to cache JavaScript CSS? Web page designs are getting
richer and richer, which means more scripts and stylesheets in the
page. A first-time visitor to your page may have to make several HTTP
requests, but by using the Expires header you make those components
cacheable. This avoids unnecessary HTTP requests on subsequent page
views. Expires headers are most often used with images, but they
should be used on all components including scripts, stylesheets etc.
How does HTML5 Boilerplate handle JavaScript CSS cache? HTML5
Boilerplate comes with server configuration files: .htacess,
web.config and nginx.conf. These files tell the server to add
JavaScript CSS cache control.
When do you need to use version control with cachebusting?
Traditionally, if you use a far future Expires header you have to
change the component's filename whenever the component changes.
How to use cachebusting? If you update your JavaScript or CSS, just
update the "?v=1" to "?v=2", "?v=3" ... This will trick the browser
think you are trying to load a new file, therefore, solve the cache
problem.
It's there to make sure that you have the current version. If you change your website and leave the name as before, browser may not notice the change and use old CSS from its cache. If you add version, the browser will download the new stylesheet.
If you set caches to expire far in the future adding ?v=2 will let the server know this is a new file but you won't need to give it a unique name (saving you a global search and replace)
HTM5 boilerplate also includes it in their project.
Check this video also: HTML5 Boilerplate Walkthrough.
One of the reason could be to bypass file caching. Same name CSS files can be cached by the servers and may result in bad display if new version has has layout changes.
This is to optimise browser-caching. You can set the header for CSS files to never expire so the browser will always get it from its cache.
But if you do this, you'll get problems when changing the CSS file because some browsers might not notice the change. By adding/changing the version-parameter it's "another" request and so it won't be taken from the cache (but after the new version is cached, it's taken from there in the future to save bandwidth/number of requests until the version changes again).
A detailed explanation can be found at html5boilerplate.com.
My knowledge is pretty much out of date regarding websites, but the variable stored in the 'href' argument is received by the browser through HTTP. Using the usual tricks in URL-rewriting you could actually have an arbitrary script that produces CSS-output when called. That output can differ, depending on the argument.
I found out that some websites use css tag like style.css?ver=1. What is this?
What is purpose of ?ver=1?
How do I do it in code?
To avoid caching of CSS.
If the website updates their CSS they update the ver to a higher number, therefore browser is forced to get a new file and not use cached previous version.
Otherwise a browser may get a new HTML code and old CSS and some elements of the website may look broken.
Adding '?ver=1' makes the HTTP request look like a GET query with parameters, and well-behaved browsers (and proxies) will refuse to cache parameterized queries. Of course well-behaved browsers (and proxies) should also pay attention to the 'Cache-control: no-cache', 'Expires', 'Last-Modified', and 'ETag' response headers (all of which were added to HTTP to specify correct caching behavior).
The '?ver=1' method is an expensive way to force behavior when the site developer doesn't know how (or is too lazy) to implement the correct response headers. In particular, it means that every page request is going to force requesting that CSS file, even though, in practice, CSS files change rarely, if at all.
My recommendation? Don't do it.
The purpose of the ?ver=1 is to parameterize the css file, so when they publish a new style.css file they up the version and it forces the client to download the new file, instead of pulling from the cached version.
If you are developing a web application in HTML and CSS or any other technology, and you are using some external CSS or JS files, you might notice one thing that in some cases if you made any changes to your existing .css or .js files then the browsers are not reflecting the changes immediately.
What happens in that case is that the browser do not download a fresh copy of the latest version of the .css and .js files, instead it uses those files stored in your local cache. As a result the changes you made recently are not visible to you.
<link rel="stylesheet" href="style.css?v=1.1">
The above case when you load the web page the browser will treat "style.css" as a different file along with "?v=1.1". Hence the browser is forced to download a fresh copy if the stylesheet or the script file.
I think that ?ver=1 is for the version no. of the web app. Every time a new build is created, the app can update the ver to the new version. This is so that the browser will load the new CSS file and not use the cached one (both use different file names).
You can refer to this site: http://www.knowlegezone.com/36/article/Technology/Software/JavaScript/CSS-Caching-Hack----javascript-as-well
IMO a better way to do this would be to include a hash generated off of the file size or a checksum based on the file contents or last-modified date. That way you don't have to update some version number and just let the number be driven off of the file's changing properties.
.button {
background: url(../Images/button.png);
}
Problem: for performance reason all static content has expiration headers and is cached by browser. When image changes user must refresh cache (Ctrl+F5 in IE). I want images to be cached, but when necessary they must be automatically reloaded.
Question: is next approach 'valid'?
.button {
background: url(../Images/button.png?v=1234);
}
where v=1234 is version of my site. I do not know whether it is 100% valid to write such things in CSS and I do want browsers to still cache images if version is the same. Do all modern browsers correctly cache data with URL parameters part?
Thanks.
That looks like a good approach to me, it'll work fine in CSS in modern browsers - the browser will look at the address of the image (including the ?v=1234), see that it's not cached, and send a fresh request.
This is discussed in rule 3 of High Performance Web Sites: "Add an Expires or a Cache-Control Header". One of the approaches recommended is to version the files rather than the site.
From the accompanying blog:
Keep in mind, if you use a far future Expires header you have to change the component's filename whenever the component changes. At Yahoo! we often make this step part of the build process: a version number is embedded in the component's filename, for example, yahoo_2.0.6.js.
I was browsing the html of my favorite site...ahem...and I saw this in the markup:
<link href="/Content/all.min.css?d=20090107" rel="stylesheet" type="text/css" />
what does "?d=20090107" do? I'm assuming it's a date of some kind, but I'm not sure why it's in the path to the file. Any ideas?
That is there to add some uniqueness to the filename, so that when they change the CSS file, they can change the extra bit to be totally sure that every client will reload the CSS rather than use a cached version.
The webserver will ignore the parameter and serve /Content/all.min.css normally
Note: While it's possible the CSS is dynamically generated, this is a common idiom for ensuring a reload, and given the parameter is a date, it seems quite likely.
Edit: Podcast 38 mentioned this...
We’ve been using the Expires or
Cache-Control Header since we
launched. This saves the browser
round-trips when getting infrequently
changing items, such as images,
javascript, or css. The downside is
that, when you do actually change
these files, you have to remember to
change the filenames. A part of our
build process now “tags” these files
with a version number so we no longer
have to remember to do this manually.
It's to "clear the cache" every time the style is updated. I would speculate that whoever is responsible for those styles increments it every time there is a change. It's because the browser sees a different URL in the style field, so it will grab the latest version, even though it's technically in the same place on the server.
As helpfully pointed out in the comments, css files often have their expiry set well into the future, this method is a nice sidestep to cache related headers.
Quite a useful trick.
It is to make the browser think it is a new file every-time to it refreshes its cache.
Very useful when your stylesheets change regularly...