This question already has answers here:
Why pass parameters to CSS and JavaScript link files like src="../cnt.js?ver=4.0"?
(9 answers)
Closed 6 years ago.
I have a question. In old project that I'm currently working on I have found this code:
<script type="text/javascript" language="Javascript" src='<%= Page.ResolveUrl("~/javascripts/CardConnectorManager.js?2016071203")%>'></script>
I have:
/javascripts/CardConnectorManager.js
but don't have
/javascripts/CardConnectorManager.js?2016071203
What that question mark is doing and why anybody write such thing?
Maybe this file exists only on server on some bulid stuff thing?
David R's answer is pretty good, but I want to add a little bit info:
Usually there are two approaches for cache-breaking:
Rename file;
Add some hash to the end of the file.
The first approach may be better for some cases (see this question), but can be more painful. How would you keep this file in version control? What if there are many files like this?
The second approach is much easier. You just add something like app.js?_=<some_string>. The <some_string> can be whatever: timestamp, build number or just a random string.
For this approach, you may find it better to use automatic tools like gulp-rev.
Update: Honestly, it would be much better to have a revision number for all statics in the project: html, images, css, js.
There a lot of tools to make this automatic.
Alternatively, there are some technics, for example angular developers have the $templateCache service which allows the developer to put all the project's html (excluding index.html) in a single js file.
It refers to the same CardConnectorManager.js file.
To prevent caching, suffixing date/timestamp while calling calling a .js file is a common practice among developers.
Hope this helps!
Basically the JS file ending with "?" (question mark) followed by some random number is used to forcefully refresh the browser cache for that particular file. Browser's stores the downloaded js files for that website in it's cache memory, to forcefully refresh this it is suffixed with the random number.
In your example if you observe closely, the number specified is nothing but the date time stamp i.e. - the number 2016071203 represents - 2016-07-12 03. If you have updated this file on server, you just need to update the new time-stamp (you can use any random number). The time-stamp is generally used to avoid duplication of number.
So next time whenever you make changes in that JS file, just update that number, so all the clients accessing this file will get updated JS code, not the cached code.
The Question mark (?) is just to handle the caching. It refreshes the file every time on the browser. We use the same technique to refresh the dynamically generated images also.
Related
There are a lot of questions and answers on SO related to my problem [I want the browser to cache js/css forever. During a new release if some of the js/css files have been updated, the browser should reload and cache them.]
This solution seemed most appropriate to me :
What is an elegant way to force browsers to reload cached CSS/JS files?
However, there is just one thing that I am unable to figure out.
The solution makes use of last_modified_time. However, I am not allowed to use it. I need to use some other mechanism.
What are the options? Is there a possibility of pre-calculating the versions during build and updating(replacing) them in jsps via build script (before deployment, so that the version numbers are not calculated on run time)? Any existing tool for this purpose? I use Java/Jsp.
We always use
file.css?[deploytimestamp]
This way the CSS file is cached for each deployment at the client. The same goes for our minified javascript. Is this an option for you?
It may not be the best way, but this is what I am doing now:
All of my js/css have a [source control = svn] revision number
References in my jsp are like /foo/path1/path2/xyz000000/foo.
Build Step 1 - Generate a map of css|js files and their revision numbers
Build Step 2 - Replace xyz000000 references in jsps with a hash of svn revisions
A rule in url rewriter to direct all /foo/path1/path2/xyz<767678>/foo. to /foo/path1/path2/foo.[js|css]
Infinitely cache the css|js files
Whenever there is a commit, the revision number changes and so do the references in .jsp
Generate an md5-hash of each css file after deployment. Use this hash instead of the timestamp in the url of the css.
file.css?[hash of file.css contents]
It may be wise to calculate the hashes once after deployment and store them to gain some performance. You could store them in a database, or even in a PHP array in a separate file that is included in your website code.
I have a external xxxx.js file where its contents are in non-understandable format.
Eg: {G(d&&!E.6c(d)){E.2A+=(E.2A?" ":"") etc.
I don't understand how this code has been done since I am new to this kind of development. Can anybody help me in finding this code??
Thanks...
Ask whomever provided you with the code for the development/debug version of it. The code you have has been optimised for size and isn't designed to be touched by hand.
The code has been through a "minifier", designed to:
make the code shorter
obfuscate the code
This kind of code are because of the js is in the min form. min form of a js means that it is converted to minimum code as much as possible by shortenning the name of the variables and trimming spaces, removing comments, etc...
There are a number of reasons why compressing your javascript files is a good idea:
Quicker download times for your users.
Reduced bandwidth consumption of your website.
Reduced number of HTTP requests on your server when combining many javascript files into one compressed file, thus reducing the server load and allowing more visitors to access your website.
Comments and whitespace are not needed for javascript execution; Removing them will speed up script execution times.
Scenario:
A web site with x number of pages is being served with a single, concatenated JavaScript file. Some of the individual JavaScript files pertain to a page, others to plugins/extensions etc.
When a page is served, the entire set of JavaScript is executed (as execution is performed when loaded). Unfortunately, only a sub-section of the JavaScript pertains directly to the page. The rest is relevant to other pages on the site, and may have potential side-effects on the current page if written poorly.
Question:
What is the best strategy to only execute JavaScript that relates directly to the page, while maintaining a single concatenated file?
Current solution that doesn't feel right:
JavaScript related to a specific page is wrapped in a "namespaced" init function for that page. Each page is rendered with an inline script calling the init function for that page. It works hunky-dory, but I would rather not have any inline scripts.
Does anyone have any clever suggestions? Should I just use an inline script and be done with it? I'm surprised this isn't more of an issue for most developers out there.
Just use an inline script. If it's one or two lines to initialize the JavaScript you need that's fine. It's actually a good design practice because then it allows re-use of your JavaScript across multiple pages.
The advantages of a single (or at least few) concatenated js files are clear (less connections in the page mean lower loading time, you can minify it all at once, ...).
We use such a solution, but: we allow different pages to get different set of concatenated files - though I'm sure there exists different patterns.
In our case we have split javascript files in a few groups by functionality; each page can specify which ones they need. The framework will then deliver the concatenated file with consistent naming and versioning, so that caching works very well on the browser level.
We use django and a home-baked solution - but that's just because we started already a few years ago, when only django-compress was available, and django compress isn't available any more. The django-pipeline successor seems good, but you can find alternatives on djangopackages/asset-managers.
On different frameworks of course you'll find some equivalent packages. Without a framework, this solution is probably unachievable ;-)
By the way, using these patterns you can also compress your js files (statically, or even dynamically if you have a good caching policy)
I don't think your solution is that bad although it is a good thing that you distrust inline scripts. But you have to find out on what page you are somehow so calling the appropriate init function on each page makes sense. You can also call the init function based on some other factors:
The page URL
The page title
A class set in the document body
A parameter appended to your script URL and parsed by the global document ready function.
I simply call a bunch of init functions when the document is ready. Each checks to see if it's needed on the page, if not, simply RETURN.
You could do something as simple as:
var locationPath = window.location.pathname;
var locationPage = locationPath.substring(locationPath.lastIndexOf('/') + 1);
switch(locationPage) {
case 'index.html':
// do stuff
break;
case 'contact.html':
// do stuff
break;
}
I'm really confused exactly why it doesn't feel right to call javascript from the page? There is a connection between the page and the javascript, and making that explicit should make your code easier to understand, debug, and more organized. I'm sure you could try and use some auto wiring convention but I don't think it really would help you solve the problem. Just call the name spaced function from your page and be done with it..
I have a webapp written in PHP and i generate the headers with header() function.
The problem is that when I'm making changes to the javascript code of my app, on clients side, the old javascript will not be executed because is cached to the clients browsers.
How can I automate the process of header expiration? I assume that is has to be a better way than modifying that function each time I modify the javascript code.
The only bullet-proof solution is to change filenames of server-side resources:
From: Yahoo's Best Practices for Speeding Up Your Web Site:
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[...]
Of course this process must be automated. We are appending JavaScript file contents hash into file name.
Change the URI to the script with each release.
This can be done by adding a query string. You can automate this by, for example, taking the revision number from your version control system and inserting it into your template.
This will allow you to have long expiry times (for optimal caching) and still get fresh JavaScript each time a new release is published (so long as the HTML document isn't loaded from the cache (but they tend to have short cache times compared to JS)).
The best way to version javascript files is to include a version number in their filename. When you rev the code, you bump the version number and then you rev any web pages that include the JS file to refer to the new filename. You then only need to expire the web pages themselves and they will automatically refer to the new JS files. The JS files can have very long expiration (months or years) so you get maximum caching benefit for them.
This also ensures that you get a consistent set of JS files.
This is how jQuery does it with versioning.
Since you don't provide much detail only the general pointer:
Usually you can configure the Expires and other header params in the webserver - either globally and/or per "folder" etc.
You can make the JS file expire for example after 1 hour... this way you would know that 1 hour after a change all clients will be using the new JS file...
IF you need the change to take effect immediately even for clients currently active the header won't help much - you would have to do some AJAX magic...
I asked this sort of question before ( Application fails to dynamically _re_load JavaScript files ) but I couldn't quite resolve the problem (if it has any solution), so I will put this in another fashion, a simpler one:
Can one unload a file from the browser's memory for posterior reloading?
(Removing the tag is not enough apparently.)
Or more relevant, if a reinsert the tag after removing it, is that code rerun (apparently not)?
How can accomplish the latter?
Thanks in advance.
You could generate a random number and then attach it to the end of the filename like this: .../script.js?r=0.25300762383267283. Then the browser would think it's a new file and not reference it from the cache.
I don't think it is possible to unload a script file.
As to the re-run issue, you could try giving each instance you call a JS file a varying GET parameter (e.g. the current timestamp). That might / should cause the browser to re-execute the file.
What are you trying to achieve? There may be smarter ways than re-loading a script file.