I have a files that is cached in some cdn.
in my local environment you can read the markup in browser as
<script src="/js/cool.js"></script>
but once it in production it goes like:
<script src="/js/cool.js.pagespeed.ce.l2D9mD1nmX.js"></script>
.pagespeed.ce.l2D9mD1nmX.js means it was being cached
now i was wondering if its advisable or a practice to preload a file that is already being cached in cdn?
because i am doing
<link rel="preload" type="application/javascript" href="/js/cool.js" as="script">
in my <head> and this will give me warning of :
The resource (the preload file) was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate as value and it is preloaded intentionally.
because technically /js/cool.js is no longer existing in the dom
Use a preload plugin in your module bundler.
Q. Is it advisable or a practice to preload a file that is already being cached in cdn?
A. Yes, it is, assuming your cool.js actually needs to be preloaded.
Now, the warning is actually expected. See, cool.js.pagespeed.ce.l2D9mD1nmX.js and cool.js are two different files on the server. Your file cool.js.pagespeed.ce.l2D9mD1nmX.js is actually a clone of code.js produced by your module-bundler for certain reasons. What you are doing is preloading cool.js, the code of which never gets executed in production and thus the warning - ...preloaded using link preload but not used within a few seconds from the window's load event. But, what you actually need to do is preload cool.js.pagespeed.ce.l2D9mD1nmX.js. Assuming you are using webpack as your module-bundler, you need a plugin called preload-webpack-plugin to achieve the same.
Related
This question already has answers here:
How to force browsers to reload cached CSS and JS files?
(57 answers)
Closed 8 years ago.
When rolling out a new website change or web application change, sometimes browsers load old javascript or image files when you navigate to the site. Oftentimes it takes a manual refresh of the page for the browser to load in the newly updated files.
How can I make sure that after an update, users receive the most up-to-date files the first time they load the page, rather than having to manually refresh to clear out any cached files. Is there a very reliable way to do this through sending expires headers or last modified?
I assume you have a build script or a bunch of task scripts to help you with the repetitive process of updating the website/application . Since you tagged your question with javascript tag ,i will offer you a javascript based solution .
You could use (or alredy using) a task runner like Grunt or Glup or any other , and then run a cache busting task that will update your url's from this :
<script src="testing.js"></src>
<link href="testing.css" rel="stylesheet">
<img src="testing.png">
to this :
<script src="testing.js?v=123456"></src>
<link href="testing.css?v=123456" rel="stylesheet">
<img src="testing.png?v=123456">
This will prevent the browser from reusing your assets .
I know only one way how to do that - add some parameters to the end of the file URL.
E.g. you have image picture.png and instead of write it in html like this
<img src="path/to/picture.png">
you have to write it like this:
<img src="path/to/picture.png?specific_parameter_123">
So, changing of this parameter after '?' will force browser to load your picture (or something else) again because for browser the exact path was changed.
You can do it manually by changing parameter (or even generate it random every time by JS) or use something like Grunt and grunt-cache-breaker and it will generate unique URL of file based on md5 hash. So, once file was changed url will be also changed.
Also it is possible to do the same on server side. E.g. if you are using PHP you can try something like this: hash css and js files to break cache. Is it slow?.
More about query string here.
I have used a hash in some projects. That hash (md5 or something fast) is computed from the file contents of the used LESS/SASS files or JS modules. Each time something is changed, e.g. in the LESS source, the compiled CSS file will have a new filename.
You should enable client-side caching with a long caching time. The browser will store the CSS files locally. It only loads a new CSS file after a live-deploy.
Check the data you have available per the system.
I was facing the issue of javascript being cached on users' browsers and not getting updated when changes went to production. Because the site uses multiple embedded iframes, just using f5 wasn't sufficient. The solution I went with is to load a script first that gets all the modified dates for the js files I need and then appends those dates to the js file in each page. Each page looks something like this:
<script type="text/javascript" src="get_dates"></script>//returns the dates for each file in array
<script type="text/javascript">
document.writeln('<script type="text/javascript" src="' + some_path + '?Mod=' + date_array[pos] + '"></script>...repeat for all scripts
</script>
The questions I have are:
How do you tell if the scripts are getting cached until the mod date changes? (I still want them to be cached, just not if they're updated)
How will the caching of the html page affect this?
Does using document.writeln(() affect caching? I.e. will they still be cached if you write the same exact script?
How do you tell if the scripts are getting cached until the mod date changes?
Just set the expiration to infinity (or, say, 1 year - that's long enough). Everytime your Mod parameter changes, the new file will be requested.
How will the caching of the html page affect this?
Not at all. The caching of the get_dates script will, though.
Does using document.writeln(() affect caching? I.e. will they still be cached if you write the same exact script?
No, it does not affect anything. The result - a <script> node referencing an external script will be the same.
Also read on How to force browser to reload cached CSS/JS files?
Sending the right headers from the server should control caching activity.
Or use a script loader to load the other scripts and apply cache-busting to the ones you need not cache.
Apply versioning to your js files in every production release.
Let say
Release1:
<script src="source.js?v1.0"></script>
Release2:
<script src="source.js?v2.0"></script>
and so on...
This way you still allowing clients to cache your js files but on a particular version.
I have a list of js files, css and images which doesn't need to load from server every time, but if there is any update in files or bug fixes, only during that time I want to replace the files from browser cache, I know there is no access to browser cache, but is there any other ways to do so? My application will be used by specific users (known people), where I can install any program in their system, can anybody suggest me efficient way to do so? I don't want to load the files every time from server by setting 'no-cache'.
The most effective way to force the browser to refresh certain files at certain times is to add an arbitrary extra query string to the link:
<script type="text/javascript" src="http://mywebsite.com/js/scripttoload.js"></script>
then change to:
<script type="text/javascript" src="http://mywebsite.com/js/scripttoload.js?V=2"></script>
Next time the page is requested the browser will think this is a new file. There are loads of other ways with headers etc but this works well
No, there isn't.
Javascript doesn't have access to the cache - the browser doesn't expose this information to the javascript engine.
A commonly-used trick is to set the cache for the files to last for ages, so that they aren't requested again. However, when you want them to be updated, you can append a timestamp to the filename after a question mark. EG:
<link rel="stylesheet" href="style.css?123211212"/>
Every time the number changes, the browser thinks it's a different file and will re-download it. If the number doesn't change, then it uses the cached version.
What I do is, as part of the build process, rename all the statically referenced files to something involving their md5 hash. Then I set the headers so that they're cached for the max possible time. As soon as they change, they get a new name, so there's never an issue.
I am currently looking at changing from using css to LESS in my current project. A few things to mention before I get to the question are:
1) The project is purely clientside (Html/Js/Css) so there is no server side component for the website (although there is a web service it calls via CORS)
2) I load almost everything via resource loading frameworks, currently I am using yepnope
So given the above I need to be able to get the LESS styles to be processed clientside, but as I am using a resource loader and more css/less could be loaded after the initial page load has happened I was wondering if:
1) Does Less work with content loaders when using client side processing? As it says:
Client-side usage
Link your .less stylesheets with the rel set to “stylesheet/less”:
<link rel="stylesheet/less" type="text/css" href="styles.less">
Then download less.js from the top of the page, and include it in the <head> element of your page, like so:
<script src="less.js" type="text/javascript"></script>
Make sure you include your stylesheets before the script.
I think I may be able to tell yepnope how to handle less files and give them the required element attributes. If I can providing the less resources are brought in before the less javascript will it be ok?
2) Is there any manual way to tell it what to process in javascript?
This would cover the case where everything has been loaded for the current page, the user clicks a button which dynamically loads a new template which is displayed in the current page, this may require new less resources to be loaded, but the less.js file has already been included.
Hopefully the above gives you some context as to what I am trying to do and what the 2 questions are.
Yes you can.
Reading this post Load less.js rules dynamically and adjusting it a bit:
less.sheets.push(document.getElementById('new-style-1'));
// Add the new less file to the head of your document
var newLessStylesheet = $("<link />").attr("id", "new-style-1").attr("href", "/stylesheets/style.less").attr("type", 'text/less');
$("head").append(newLessStylesheet);
// Have less refresh the stylesheets
less.refresh(true);
You could also generate all the CSS in your development environment and put it in one file.
There are lots of options. The easiests way would be to use an application. You could use apps like http://incident57.com/less/ for Mac. You can even compile online: Search for something as "lessphp".
I'm encountering an issue where most of a page's main logic is offset in a JS file and initialized within a dojo.require call to simplify debugging and development. We're encountering a case where an offload to another page, and then back to the first one and nothing inside our require script loads. I understand this is due in part to how dojo.require re-uses cached pages, but I can't go back to the cached version either. Is there a way, besides pasting all the scripts inside the page itself, to force Dojo to reload any require regardless of if it has been cached or not?
Force it to be reloaded in HTML.
<script type="text/javascript" src="path/to/my/module/name.js"></script>
<script type="text/javascript">
...
dojo.require("my.module.name");
...
</script>
I don't know if there is any problem on doing it but it does work.
Is there a reason you can't do this the "right" way, by putting the relevant code inside a function and then just calling said function again whenever you want?
If you still think you need to mess with the module loader though I think there are two alternatives after a quick check on the dojo.require source code:
Try to manually clear the module cache
delete d._loadedModules['my.module.name'];
Directly call the internal loader:
var relpath = d._getModuleSymbols(moduleName).join("/") + '.js';
d._loadPath(relpath, null);
(Try these at your own risk)