In a Vue.js project created with Vue CLI (internally using webpack), I implement code splitting and lazy loading with dynamic imports like so:
import(/* webpackChunkName: "my-feature" */ "./my-feature.js");
As a result I get the expected set of files:
dist/myApp.umd.min.js
dist/myApp.umd.min.vendors~my-feature.js (my-feature dependencies)
dist/myApp.umd.min.my-feature.js
The Vue application is built as a library and then used for an existing web site. What I do is include myApp.umd.min.js in <head> (common to all pages), and then in <body> request code I need for that page (for example myApp.umd.min.my-feature.js). Dependencies (myApp.umd.min.vendors~my-feature.js) are automatically requested by the earlier script.
Problem
When I navigate to a page, that uses the Vue app (and specifically my-feature), all 3 of the above files are loaded. That is expected for the first visit, but if I move to a different page and then return, only the first file (myApp.umd.min.js) is loaded from cache. The other ones are loaded from server every time I visit the page.
What approach to take for the lazy-loaded scripts to come from cache once already loaded? Thank you!
So far I have not found anything better than including all the scripts, I need on the page, in its <head> section. Moreover only using <script> tag helped; <link href="..." rel="preload" as="script"> was useless.
Use a version parameter for the script url.
There's a code snippet that showcase this:
<script type="text/javascript" src="myApp.umd.min.js?v=123"></script>
Also this is a valid solution:
<link rel="preload" href="myFont.woff2" as="font"
type="font/woff2" crossorigin="anonymous">
From docs:
A rel value of preload indicates that the browser should preload this resource with the as attribute indicating the specific class of content being fetched. The crossorigin attribute indicates whether the resource should be fetched with a CORS request.
Here is an image of my recent webpage test:
Is there any way to start as many http requests as early as possible? For example, the google font file requests start very late. Similarly, I want to move the jQuery request to as early as the script.min.js request which is hosted on the domain. Basically, I am looking for any way to make these requests more efficient.
First of all, make sure the request are done straight from HTML whenever possible, and not dynamically via JavaScript. Put your JS and CSS requests into <head> if possible. That way, the preload scanner of the browser will request those files as soon as possible.
Be careful though about where the CSS is placed - see https://csswizardry.com/2018/11/css-and-network-performance/ for more.
If you can't put everything into <head> of the HTML, you're looking for <link rel="preload">, which was created exactly for that purpose; it tells the browser to download some resources, but not execute them yet.
Some literature:
https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
https://developers.google.com/web/updates/2016/03/link-rel-preload
https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf
https://caniuse.com/#feat=link-rel-preload
Note though that as of late 2018, it's disabled in Firefox, with no ETA when this will ship.
Also, be careful when using preload as the preloaded requests get the highest priority, which sometimes might mean than other critical but not preloaded resources will wrongly get deprioritized.
In some cases (depending on browser, order of entries in HTML etc.), preload can lead to double fetches (particularly for webfonts). Make sure to check for that.
I've found many explanations about caching, some of them even have examples but, it is kind of foggy to understand it and how to use it. I've tried to use it many times, but I've failed (I want to improve speed, I want only the necessary to be loaded from the server). Can you help me to make this page below be saved in the browser's cache, If possible give me an explanation or a different way on how to do it (it can be JS too!)?
P.S.: It can be Appcache if you give me a suitable example for this page ;).
Thanks in advance.
My Appcache file's name: offline.appcache.
CACHE MANIFEST
/style.css
http://sistema.agrosys.com.br/sistema/labs/CSS_HTML/html1.html
<!DOCTYPE html>
<html lang="en" manifest="/offline.appcache">
<head>
<meta name="viewport" content="width=device-width" />
<title>page1</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="testing_class">Test</div>
<div class="testing_clas">Test</div>
<div class="testing_cla">Test</div>
<div class="testing_cl">Test</div>
<div class="testing_c">Test</div>
<div class="testing_">Test</div>
</body>
</html>
Reconsider using AppCache. Using it doesn't necessarily imply that your site will work offline. Basically, here are the steps that AppCache takes, regardless of the browser connection status:
Asks the server for the manifest file.
If the manifest file hasn't changed, it serves the local files.
If the manifest file has changed, it downloads the new files, saves them and then serves them.
Since you mention that
I want to improve speed, I want only the necessary to be loaded from the server
AppCache is a perfectly valid solution.
EDIT: A quick example of using AppCache:
In the beginning of your original HTML:
<!DOCTYPE html>
<!--[if lte IE 9]>
<style>.scrollingtable > div > div > table {margin-right: 17px;}</style>
<![endif]-->
<html manifest="example.appcache">
<head>
You just need the "manifest" in the tag. Then, the example.appcache file would be:
CACHE MANIFEST
CACHE:
http://code.jquery.com/ui/1.11.4/themes/redmond/jquery-ui.css
http://code.jquery.com/jquery-1.10.2.js
http://code.jquery.com/ui/1.11.4/jquery-ui.js
NETWORK:
*
http://*
https://*
Just include in the CACHE section whatever static content your site uses.
You can also put a version number or date in the manifest file to make sure the browsers gets the new content when needed.
Caching is used to avoid redownloading files that are reused very often (across several pages or several sessions), but it targets mainly those files that fall under the category of "assets" (CSS, javascript, images, etc.), and which are expected to remain frozen. However, the content of webpage (the HTML) is NOT expected to remain frozen (eg. search results, etc.), and is usually reasonable in size, so there's no real reason to bother caching it (who still has a 56k connection really ?).
Then, there is the case of HTML "static pages", but usually those pages contain only text, and text is very light (unless you have a full book) compared to other media, so most people don't bother about it.
Now if you really want to "cache" the HTML, well it's exactly the same as keeping an offline version, so why not Appcache ?.
Is there a way I can put some code on my page so when someone visits a site, it clears the browser cache, so they can view the changes?
Languages used: ASP.NET, VB.NET, and of course HTML, CSS, and jQuery.
If this is about .css and .js changes, then one way is "cache busting" by appending something like "_versionNo" to the file name for each release. For example:
script_1.0.css // This is the URL for release 1.0
script_1.1.css // This is the URL for release 1.1
script_1.2.css // etc.
or after the file name:
script.css?v=1.0 // This is the URL for release 1.0
script.css?v=1.1 // This is the URL for release 1.1
script.css?v=1.2 // etc.
You can check this link to see how it could work.
Look into the cache-control and the expires META Tag.
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">
Another common practices is to append constantly-changing strings to the end of the requested files. For instance:
<script type="text/javascript" src="main.js?v=12392823"></script>
Update 2012
This is an old question but I think it needs a more up to date answer because now there is a way to have more control of website caching.
In Offline Web Applications (which is really any HTML5 website) applicationCache.swapCache() can be used to update the cached version of your website without the need for manually reloading the page.
This is a code example from the Beginner's Guide to Using the Application Cache on HTML5 Rocks explaining how to update users to the newest version of your site:
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
// Browser downloaded a new app cache.
// Swap it in and reload the page to get the new hotness.
window.applicationCache.swapCache();
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
}, false);
See also Using the application cache on Mozilla Developer Network for more info.
Update 2016
Things change quickly on the Web.
This question was asked in 2009 and in 2012 I posted an update about a new way to handle the problem described in the question. Another 4 years passed and now it seems that it is already deprecated. Thanks to cgaldiolo for pointing it out in the comments.
Currently, as of July 2016, the HTML Standard, Section 7.9, Offline Web applications includes a deprecation warning:
This feature is in the process of being removed from the Web platform.
(This is a long process that takes many years.) Using any of the
offline Web application features at this time is highly discouraged.
Use service workers instead.
So does Using the application cache on Mozilla Developer Network that I referenced in 2012:
Deprecated This feature has been removed from the Web standards.
Though some browsers may still support it, it is in the process of
being dropped. Do not use it in old or new projects. Pages or Web apps
using it may break at any time.
See also Bug 1204581 - Add a deprecation notice for AppCache if service worker fetch interception is enabled.
Not as such. One method is to send the appropriate headers when delivering content to force the browser to reload:
Making sure a web page is not cached, across all browsers.
If your search for "cache header" or something similar here on SO, you'll find ASP.NET specific examples.
Another, less clean but sometimes only way if you can't control the headers on server side, is adding a random GET parameter to the resource that is being called:
myimage.gif?random=1923849839
I had similiar problem and this is how I solved it:
In index.html file I've added manifest:
<html manifest="cache.manifest">
In <head> section included script updating the cache:
<script type="text/javascript" src="update_cache.js"></script>
In <body> section I've inserted onload function:
<body onload="checkForUpdate()">
In cache.manifest I've put all files I want to cache. It is important now that it works in my case (Apache) just by updating each time the "version" comment. It is also an option to name files with "?ver=001" or something at the end of name but it's not needed. Changing just # version 1.01 triggers cache update event.
CACHE MANIFEST
# version 1.01
style.css
imgs/logo.png
#all other files
It's important to include 1., 2. and 3. points only in index.html. Otherwise
GET http://foo.bar/resource.ext net::ERR_FAILED
occurs because every "child" file tries to cache the page while the page is already cached.
In update_cache.js file I've put this code:
function checkForUpdate()
{
if (window.applicationCache != undefined && window.applicationCache != null)
{
window.applicationCache.addEventListener('updateready', updateApplication);
}
}
function updateApplication(event)
{
if (window.applicationCache.status != 4) return;
window.applicationCache.removeEventListener('updateready', updateApplication);
window.applicationCache.swapCache();
window.location.reload();
}
Now you just change files and in manifest you have to update version comment. Now visiting index.html page will update the cache.
The parts of solution aren't mine but I've found them through internet and put together so that it works.
For static resources right caching would be to use query parameters with value of each deployment or file version. This will have effect of clearing cache after each deployment.
/Content/css/Site.css?version={FileVersionNumber}
Here is ASP.NET MVC example.
<link href="#Url.Content("~/Content/Css/Reset.css")?version=#this.GetType().Assembly.GetName().Version" rel="stylesheet" type="text/css" />
Don't forget to update assembly version.
I had a case where I would take photos of clients online and would need to update the div if a photo is changed. Browser was still showing the old photo. So I used the hack of calling a random GET variable, which would be unique every time. Here it is if it could help anybody
<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...
EDIT
As pointed out by others, following is much more efficient solution since it will reload images only when they are changed, identifying this change by the file size:
<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"
A lot of answers are missing the point - most developers are well aware that turning off the cache is inefficient. However, there are many common circumstances where efficiency is unimportant and default cache behavior is badly broken.
These include nested, iterative script testing (the big one!) and broken third party software workarounds. None of the solutions given here are adequate to address such common scenarios. Most web browsers are far too aggressive caching and provide no sensible means to avoid these problems.
Updating the URL to the following works for me:
/custom.js?id=1
By adding a unique number after ?id= and incrementing it for new changes, users do not have to press CTRL + F5 to refresh the cache. Alternatively, you can append hash or string version of the current time or Epoch after ?id=
Something like ?id=1520606295
<meta http-equiv="pragma" content="no-cache" />
Also see https://stackoverflow.com/questions/126772/how-to-force-a-web-browser-not-to-cache-images
Here is the MDSN page on setting caching in ASP.NET.
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
Response.Cache.SetValidUntilExpires(False)
Response.Cache.VaryByParams("Category") = True
If Response.Cache.VaryByParams("Category") Then
'...
End If
Not sure if that might really help you but that's how caching should work on any browser. When the browser request a file, it should always send a request to the server unless there is a "offline" mode. The server will read some parameters like date modified or etags.
The server will return a 304 error response for NOT MODIFIED and the browser will have to use its cache. If the etag doesn't validate on server side or the modified date is below the current modified date, the server should return the new content with the new modified date or etags or both.
If there is no caching data sent to the browser, I guess the behavior is undetermined, the browser may or may not cache file that don't tell how they are cached. If you set caching parameters in the response it will cache your files correctly and the server then may choose to return a 304 error, or the new content.
This is how it should be done. Using random params or version number in urls is more like a hack than anything.
http://www.checkupdown.com/status/E304.html
http://en.wikipedia.org/wiki/HTTP_ETag
http://www.xpertdeveloper.com/2011/03/last-modified-header-vs-expire-header-vs-etag/
After reading I saw that there is also a expire date. If you have problem, it might be that you have a expire date set up. In other words, when the browser will cache your file, since it has a expiry date, it shouldn't have to request it again before that date. In other words, it will never ask the file to the server and will never receive a 304 not modified. It will simply use the cache until the expiry date is reached or cache is cleared.
So that is my guess, you have some sort of expiry date and you should use last-modified etags or a mix of it all and make sure that there is no expire date.
If people tends to refresh a lot and the file doesn't get changed a lot, then it might be wise to set a big expiry date.
My 2 cents!
I implemented this simple solution that works for me (not yet on production environment):
function verificarNovaVersio() {
var sVersio = localStorage['gcf_versio'+ location.pathname] || 'v00.0.0000';
$.ajax({
url: "./versio.txt"
, dataType: 'text'
, cache: false
, contentType: false
, processData: false
, type: 'post'
}).done(function(sVersioFitxer) {
console.log('Versió App: '+ sVersioFitxer +', Versió Caché: '+ sVersio);
if (sVersio < (sVersioFitxer || 'v00.0.0000')) {
localStorage['gcf_versio'+ location.pathname] = sVersioFitxer;
location.reload(true);
}
});
}
I've a little file located where the html are:
"versio.txt":
v00.5.0014
This function is called in all of my pages, so when loading it checks if the localStorage's version value is lower than the current version and does a
location.reload(true);
...to force reload from server instead from cache.
(obviously, instead of localStorage you can use cookies or other persistent client storage)
I opted for this solution for its simplicity, because only mantaining a single file "versio.txt" will force the full site to reload.
The queryString method is hard to implement and is also cached (if you change from v1.1 to a previous version will load from cache, then it means that the cache is not flushed, keeping all previous versions at cache).
I'm a little newbie and I'd apreciate your professional check & review to ensure my method is a good approach.
Hope it helps.
In addition to setting Cache-control: no-cache, you should also set the Expires header to -1 if you would like the local copy to be refreshed each time (some versions of IE seem to require this).
See HTTP Cache - check with the server, always sending If-Modified-Since
There is one trick that can be used.The trick is to append a parameter/string to the file name in the script tag and change it when you file changes.
<script src="myfile.js?version=1.0.0"></script>
The browser interprets the whole string as the file path even though what comes after the "?" are parameters. So wat happens now is that next time when you update your file just change the number in the script tag on your website (Example <script src="myfile.js?version=1.0.1"></script>) and each users browser will see the file has changed and grab a new copy.
Force browsers to clear cache or reload correct data? I have tried most of the solutions described in stackoverflow, some work, but after a little while, it does cache eventually and display the previous loaded script or file. Is there another way that would clear the cache (css, js, etc) and actually work on all browsers?
I found so far that specific resources can be reloaded individually if you change the date and time on your files on the server. "Clearing cache" is not as easy as it should be. Instead of clearing cache on my browsers, I realized that "touching" the server files cached will actually change the date and time of the source file cached on the server (Tested on Edge, Chrome and Firefox) and most browsers will automatically download the most current fresh copy of whats on your server (code, graphics any multimedia too). I suggest you just copy the most current scripts on the server and "do the touch thing" solution before your program runs, so it will change the date of all your problem files to a most current date and time, then it downloads a fresh copy to your browser:
<?php
touch('/www/sample/file1.css');
touch('/www/sample/file2.js');
?>
then ... the rest of your program...
It took me some time to resolve this issue (as many browsers act differently to different commands, but they all check time of files and compare to your downloaded copy in your browser, if different date and time, will do the refresh), If you can't go the supposed right way, there is always another usable and better solution to it. Best Regards and happy camping. By the way touch(); or alternatives work in many programming languages inclusive in javascript bash sh php and you can include or call them in html.
For webpack users:-
I added time with chunkhash in my webpack config. This solved my problem of invalidating cache on each deployment. Also we need to take care that index.html/ asset.manifest is not cached both in your CDN or browser. Config of chunk name in webpack config will look like this:-
fileName: [chunkhash]-${Date.now()}.js
or If you are using contenthash then
fileName: [contenthash]-${Date.now()}.js
This is the simple solution I used to solve in one of my applications using PHP.
All JS and CSS files are placed in a folder with version name. Example : "1.0.01"
root\1.0.01\JS
root\1.0.01\CSS
Created a Helper and Defined the version Number there
<?php
function system_version()
{
return '1.0.07';
}
And Linked JS and SCC Files like below
<script src="<?= base_url(); ?>/<?= system_version();?>/js/generators.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="<?= base_url(); ?>/<?= system_version(); ?>/css/view-checklist.css" />
Whenever I make changes to any JS or CSS file, I change the System Verson in Helper and rename the folder and deploy it.
I had the same problem, all i did was change the file names which are linked to my index.html file and then went into the index.html file and updated their names, not the best practice but if it works it works. The browser sees them as new files so they get redownloaded on to the users device.
example:
I want to update a css file, its named styles.css, change it to styless.css
Go into index.html and update , and change it to
in case interested I've found my solution to get browsers refreshing .css and .js in the context of .NET MVC (.net fw 4.8) and the use of bundles.
I wanted to make browsers refresh cached files only after a new assembly is deployed.
Buinding on Paulius Zaliaduonis response, my solution is as follows:
store your application base url in the web config app settings (the HttpContext is not yet available at runtime during the RegisterBundle...), then make this parameter changing according to the configuration (debug, staging, release...) by the xml transform
In BundleConfig RegisterBundles get the assembly version by the means of reflection, and...
...change the default tag format of both styles and scripts so that the bundling system generates link and script tags appending a query string parameter on them.
Here is the code
public static void RegisterBundles(BundleCollection bundles)
{
string baseUrl = system.Configuration.ConfigurationManager.AppSettings["by.app.base.url"].ToString();
string assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
Styles.DefaultTagFormat = $"<link href='{baseUrl}{{0}}?v={assemblyVersion}' rel='stylesheet'/>";
Scripts.DefaultTagFormat = $"<script src='{baseUrl}{{0}}?v={assemblyVersion}'></script>";
}
You'll get tags like
<script src="https://example.org/myscriptfilepath/script.js?v={myassemblyversion}"></script>
you just need to remember to to build a new version before deploying.
Ciao
2023 onward
At the time of writing, many web browsers support the Clear-Site-Data HTTP header [MDN reference]. To instruct the client web browser to clear the cache for the website domain and subdomains, set the following header in the HTTP response from the server:
Clear-Site-Data: "cache"
Alternatively, the following header may be better supported across browsers, but it clears other website data, such as localStorage and cookies, in addition to the cache.
Clear-Site-Data: "*"
However note that intermediate caches (e.g. a CDN) may not understand or respect this header, so intermediate caches may still respond with previously cached data.
Do you want to clear the cache, or just make sure your current (changed?) page is not cached?
If the latter, it should be as simple as
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
Instead of having an external .js file, we can inline Javascript directly in HTML, i.e.
Externalized version
<html>
<body>
<script type="text/javascript" src="/app.js"></script>
</body>
</html>
Inlined version
<html>
<body>
<script type="text/javascript">
// app.js inlined
</script>
</body>
</html>
However, it's not recommended:
https://developer.yahoo.com/performance/rules.html#external
Put javascript and css inline in a single minified html file to improve performance?
The main reason is caching and pre-compiling - in the externalized version, the browser can download, pre-compile and store the file once for multiple pages, while it cannot do the same for inlined version.
However, is it possible to do something along these lines:
Inlined keyed version
<html>
<body>
<script type="text/javascript" hash="abc">
// app.js inlined
</script>
</body>
</html>
That is, do this:
In the first invocation, send the whole script and somehow tell the browser that the script hash is abc
Later, when the browser loads that or other pages containing the same script, it will send this key as a cookie. The server will only render the contents of the script if the key has been received.
That is, if the browser already knows about the script, the server will render just this:
Inlined keyed version, subsequent fetches (of the same or other pages)
<html>
<body>
<script type="text/javascript" hash="abc">
</script>
</body>
</html>
where notably the script contents are empty.
This would allow for shorter script fetching with a natural fallback.
Is the above possible? If not, is some other alternative to the above possible?
I don't know of a way to do what you asked, so I'll provide an alternative that might still suit your needs.
If you're really after a low latency first page load, you could inline the script, and then after the page loads, load the script via url so that it's in the browser cache for future requests. Set a cookie once you've loaded the script by direct url, so that your server can determine whether to inline the script or provide the external script url.
first page load
<script>
// inlined my-script.js goes here.
</script>
<script>
$(function(){
// load it again, so it's in the browser cache.
// notice I'm not executing the script, just loading it.
$.ajax("my-script.js").then(function(){
// set a cookie marking this script as cached
});
});
</script>
second page load
<script src="my-script.js"></script>
Obviously, this has the drawback that it loads the script twice. It also adds additional complexity for you to take care of when you update your script with new code - you need to make sure you address the cookie being for a old version.
I wouldn't bother with all this unless you really feel the need to optimize the first page. It might be worth it in your case.
The Concept
Here's an interesting approach (after being bugged by notifications :P)
You could have the server render your script this way. Notice the weird type attribute. That's to prevent the script from executing. We'll get to that in a second.
<script type="text/cacheable" data-hash="9182n30912830192c83012983xm019283x">
//inline script
</script>
Then create a library that looks for these scripts with weird types, get the innerHTML of these scripts, and execute them in the global context as if they were normally executing (via eval or new Function). This makes them execute like normal scripts. Here's a demo:
<script type="text/cacheable" data-hash="9182n30912830192c83012983xm019283x">
alert(a);
</script>
<script type="text/cacheable" data-hash="9182n30912830192c83012983xm019283x">
alert(b);
</script>
<script>
// Let's say we have a global
var a = "foo";
var b = "bar"
// Getting the source
var scripts = Array.prototype.slice.call(
document.querySelectorAll('script[type="text/cacheable"]')
);
scripts.forEach(function(script){
// Grabbing
var source = script.innerHTML;
// Create a function (mind security on this one)
var fn = new Function(source);
// Execute in the global scope
fn.call(window);
});
</script>
However...
Since you have the script source (the innerHTML), you can cache them somewhere locally (like in localStorage) and use the hash as its identifier. Then you can store the same hash in the cookie, where future page-requests can tell the server "Hey, I have cached script with [hash]. Don't print the script on the page anymore". Then you'll get this in future requests:
<script type="text/cacheable" data-hash="9182n30912830192c83012983xm019283x"></script>
That covers up the first half. The second phase is when your library sees an empty script. The other thing your library should do is when it sees an empty script, it should look up for that script with that hash in your local storage, get the script's source and execute it like you just did in the first place.
The Catch
Now there's always a trade-off in everything, and I'll highlight what I can think of here:
Pros
You only need one request for everything. Initial pageload contains scripts, subsequent pages become lighter because of the missing code, which is already cached by then.
Instant cache busting. Assuming the hash and code are 1:1, then changing the content should change the hash.
Cons
This assumes that pages are dynamic and are never cached. That's because if you happen to create a new script, with new hash, but had the client cache the page, then it will still be using the old hashes thus old scripts.
Initial page load will be heavy due to inlined scripts. But this can be overcome by compressing the source using a minifier on the server. Overhead of minification can also be overcome by caching minified results on the server.
Security. You'll be using eval or new Function. This poses a big threat when unauthorized code manages to sneak in. In addition, the threat is persistent because of the caching.
Out of sync pages. What happens if you get an empty script, whose hash is not in the cache? Perhaps the user deleted local storage? You'll have to issue a request to the server for it. Since you want the source, you'll have to have AJAX.
Scripts are not "normal". Your script is best put at the end of the page so that all inline scripts will be parsed by then. This means your scripts execute late and never in the time they get parsed by the browser.
Storage limits. localStorage has a size limit of 5-10MB, depending on which browser we're talking about. Cookies are limited to 4KB generally.
Request size. Note that cookies are shipped up to the server on request and down to the browser on response. That additional load might be more of a hassle than it is for good.
Added server-side logic. Because you need to know what needs to be added, you need to program your server to do it. This makes the client-side implementation dependent on the server. Switching servers (say from PHP to Python) wouldn't be as easy, as you need to port over the implementation.
If your <script> is not introduced as type=text/javascript, it will simply not be executed.
So you could have many tags like theses:
<script type="text/hashedjavascript" hash="abc">...</script>
<script type="text/hashedjavascript" hash="efg">...</script>
Then when the DOM is loaded, pick one and evaluate it.
I made an example here: http://codepen.io/anon/pen/RNGQEM
But it smells, real bad. It's definitely better to fetch two different files.
Actually what you should do, is have a single file my-scripts.js that contains the code for each of your script, wrapped in a function
// file: my-scripts.js
function script_abc(){
// what script abc is supposed to do
}
function script_efg(){
// what script efg is supposed to do
}
Then execute whatever your cookie tells you to. This is how AMD builders concatenate multiples files in one.
Also look for an AMD library such as requirejs
Edit: I misunderstood your question, removed the irrelevant part.