I read about a dozen posts on here, this one seemed closest but didn't quite clear it up for me.
I am building on HTML5 Boilerplate, albeit a custom Modernizr build. I am planning on using the yepnope/modernizr.load functionality for conditional loading.
The .htaccess in H5BP removes Etags and adds expires headers (I guess expires headers are required for Modernizr.load). It also set expirations of "access plus X"
How does this work in relation making the most of cache to 'speed up' the browsing experience. Will every resource who's conditions are met load on every page or will things which are cached be skipped?
What if just one of the components (one of the resources I am loading) is changed yet my version of Modernizr isn't?
After posting I realized this may more suited for the webmasters forum (there's no actual code in the question...) but I guess I am unsure if there will be an answer that involves code so for now, I'll leave it realizing perhaps it should be migrated. Sorry, this level of coding and configuration is new to me.
Thanks
Each resources is cached independently. So, if you load a javascript file named foo.js, this file will be cached for one year: https://github.com/h5bp/html5-boilerplate/blob/master/.htaccess#L245
If you change your modernizr script to a new version, this won't change the cache end date of foo.js which will remain untouched.
In order to bust the cache, you'll need to change the file name (e.g.: foo-v1234123.js), the path or you could add a query string (foo.js?v=1). If you make change to foo.js then just increase this version number by one to force the browser to redownload the file and recache it.
If you're working on a simple website and no big project, using a query string a doing this manually may be the easier solution. Or else, I'd suggest to hooks versions number via git or something similar - but this would need to be automated for your sanity.
Hope this help !
Related
I know that there are a lot of posts about that in web, but none of them satisfied me.
Most of people recommends appending a verizon number to each script/css file. But this sound like a lot of job to me (project is qute bit), maybe there is some way to version only output files, some CLI command I dont know?
My solution was based of simple pinging to API for new version number, when > than stored then reload the page. And here is a tricky part - even location.reload(true) does not refresh the cached angular stuff. Manually CTRL+SHIFT+R does this job nicely. This would be good enough for me if the programmaticly hard reload would work.
I also tried a this.compiler.clearCache(); but also with no effect.
Thanks in advance! :)
The #angular/cli does the cache busting for you. It appends the hash to script/css file names if you run the ng build with the --prod flag.
EDIT: If you are using the angular-cli, the #Tomasz's answer is probably better than the methods listed below.
Ideally you would use a module bundler like Webpack or a task runner like Grunt to automatically 'fingerprint' your files (ie, append a unique identifier to the file name based on it's contents).
But if that is not an option, a simple hack would be to :
set the caching headers on your HTML to avoid caching on the browser
Append a random query parameter to your script tag URLs in your HTML which you can change each time you want a new version.
<script src='/js/some.js?v=1.1.3'></script>
Changing the random query parameter (v in the example) will ensure the browser makes a fresh request as the URL is different than the cached (older) version
I am providing an infrastructure that require the developer to include only one simple java script file that then includes allot others, for instance DOJO toolkit. Later DOJO is loading all\some of my infrastructure files.
When i'm updating the version i'm simply telling my clients to include the version number in the <script src="...?ver=1.2"> so it will not take the files from the cache.
My problem is that (this simple file is being reloaded but) the rest of my files that being loaded by DOJO are still being loaded from the cache.
Is there a way to do the same technick, or maybe other way, to force my browser take the files from the server at this time, and not from the cache ?
As usual, I am posting question and answering myself. But sharing the answer so it will use others and not deleting the post.
Using dojoConfig property cacheBust is the solution.
dojoConfig = {
...
cacheBust="v=1.2.3",
...
}
In DOJO documentation it's stated that when you send true it will add the time as query string. Which means that every load will be from the server and never from the cache. but what we can do is adding constant string as i wrote above v=1.2.3 and this string will be added as the query string as well, and giving us more power on when the version will be loaded from cache or server
My website uses about 10 third party javascript libraries like jQuery, jQuery UI, prefixfree, a few jQuery plugins and also my own javascript code. Currently I pull the external libraries from CDNs like Google CDN and cloudflare. I was wondering what is a better approach:
Pulling the external libraries from CDNs (like I do today).
Combining all the files to a single js and a single css file and storing them locally.
Any opinions are welcome as long as they are explained.
Thanks :)
The value of a CDN lies in the likelihood of the user having already visited another site calling that same file from that CDN, and becomes increasingly valuable depending on the size of the file. The likelihood of this being the case increases with the ubiquity of the file being requested and the popularity of the CDN.
With this in mind, pulling a relatively large and popular file from a popular CDN makes absolute sense. jQuery, and, to a lesser degree, jQuery UI, fit this bill.
Meanwhile, concatenating files makes sense for smaller files which are not likely to change much — your commonly used plugins will fit this bill, but your core application-specific code probably doesn't: it might change from week to week, and if you're concatenating it with all your other files, you'd have to force the user to download everything all over again.
The HTML5 boilerplate does a pretty good job of providing a generic solution for this:
Modernizr is loaded from local in the head: it's very small and
differs quite a lot from instance to instance, so it doesn't make
sense to source it from a CDN and it won't hurt the user too much to
load it from your server. It's put in the head because CSS may be
making use of it, so you want it's effects to be known before the
body renders. Everything else goes at the bottom, to stop your
heavier scripts blocking rendering while they load and execute.
jQuery from the CDN, since almost everyone uses it and it's quite heavy. The user will probably already have this cached before they
visit your site, in which case they'll load it from cache instantly.
All your smaller 3rd party dependencies and code snippets that aren't likely to change much get concatenating into a plugins.js
file loaded from your own server. This will get cached with a
distant expiry header the first time the user visits and loaded from
cache on subsequent visits.
Your core code goes in main.js, with a closer expiry header to account for the fact that your application logic may change from
week to week or month to month. This way when you've fixe a bug or
introduced new functionality when the user visits a fortnight from
now, this can get loaded fresh while all the content above can be
brought in from cache.
For your other major libraries, you should look at them individually and ask yourself whether they should follow jQuery's lead, be loaded individually from your own server, or get concatenated. An example of how you might come to those decisions:
Angular is incredibly popular, and very large. Get it from the CDN.
Twitter Bootstrap is on a similar level of popularity, but you've got a relatively slim selection of its components, and if the user doesn't already have it it might not be worth getting them to download the full thing. Having said that, the way it fits into the rest of your code is pretty intrinsic, and you're not likely to be changing it without rebuilding the whole site — so you may want to keep it hosted locally but keep it's files separate from your main plugins.js. This way you can always update your plugins.js with Bootstrap extensions without forcing the user to download all of Bootstrap core.
But there's no imperative — your mileage may vary.
I know this question was asked quite a few times and the most common answers were:
Auto versioning using the .htaaccess file.
Although this is not at all recommended, using a version number as a query parameter
For example: '/scripts/script1?v=1.0.0'. This will cause the browser not to cache the file but does the job.
I am handling some post release issues and since we don't follow a software project life cycle as such, we update the site as and when the issues are tested and fixed. So, we may have to update the site several times a day sometimes versus no updates for a week.
I am not sure if there is a way I can still take the benefit of caching and at the same time don't need to have the users to refresh the page/clear cache to see latest changes.
Is there a way I can implement the .htaaccess solution in asp.net if that's what I need to do?
I really appreciate any help.
Here is the solution I've used for css files, but should work fine for JS:
In the htaccess have a rule:
RewriteRule ^(.*)_ver_.*(\..*)$ $1$2 [NC,L]
That takes a file name such as "Style_ver_12345.css" and rewrites it to Style.css.
Then when when you include the file append the LastWriteTime of the actual file (File.GetLastWriteTime(filePath).Ticks.ToString() is how I do it) as the version number. An example file name that I would have is Style_ver_634909902200823172.css
This will ensure that any change in the file will immediately cause a new version number, while the physical files does not need to have a different name, and the file will be cached by the browser.
The user would still have to refresh the page, but they wouldn't have to clear their cache. If you needed to, maybe you could force a refresh by having an ajax call that would compare the version number of the script loaded with the version number on the server. A newer version on the server could then force a refresh.
This one should be easy, and I think I know the right answer, but here goes.
For compatibility reasons, should I leave the filename of jQuery as "jquery-1.3.2.min.js" or just rename it to jquery.js?
My guess is leave it as is to avoid conflicts in case another app uses a different version of jQuery. If they've renamed it to "jquery.js" and I do the same, I see potential version conflicts.
Am I wrong or way off base?
Jeff
It's a very good idea to have version-numbered JS (and CSS) files, because that lets you configure your web server to use a far-future Expires header on such files without running into caching problems. When the file gets updated, it gets a new version number, so the browser always fetches the new version, not the old cached one.
You should do this on your other JS and CSS files, too. You want this to be automated, not something you manage by hand. Your development work happens on unversioned files, and your versioning system creates versioned copies and works out the details of updating the references to the CSS and JS files in the HTML files to point to the versioned copies. This can be a bit of work, but well worth it when it comes to speeding up your site. It took me about a day to set my system up. The improvement wasn't subtle.
I would go with jquery-1.3.2.min.js because it's more specific and you can immediately tell if you're reviewing this site in months to come, as well as avoiding any filename confliction in the future.
You shouldn't have any issues with updating, if you're relying on something like an include/template file for the javascript.
In my opinion, its just a personal preference. If you have version in your file name, It helps you easily identify which one you are using with out actually opening the file. It also provides an indirect way of clients downloading the new version file (as it is never cached). If you don't use the ext, upgrading to newer version is easy in coding perspective, but takes the pain of force downloading the new file by all users.
Recommended way to use jQuery in app is using the google's hosting..
google.load("jquery", "1.3.2");
google.setOnLoadCallback(function() {
// Place init code here instead of $(document).ready()
});
Why and how to use jQuery hosted on google
I prefer to leave the version in the file name because there are times when you are changing versions and this is very helpful. At a glance I can see which version I am using on any given webpage.