I am curious to know how asp.net bundling works.
I know we've to add the all scripts and css and images to the bundle so that browser will initiate single request for all the resources.
I 've some confusion how the pages will refer these bundled resources from client browser.
Let's take a look at what happens when we use the bundling in System.Web.Optimization.
In this example I used the "Empty ASP.NET MVC 4 template" and grabbed the latest "Microsoft.AspNet.Web.Optimization" package from nuget.
I then proceeded to register 2 javascript files. One for jquery and another for bootstrap.
public static void RegisterBundles(BundleCollection bundles)
{
var javascriptBundle = new Bundle("~/bundles/javascripts")
.Include("~/Scripts/jquery-{version}.js")
.Include("~/Content/bootstrap/js/bootstrap.js");
bundles.Add(javascriptBundle);
}
Now that we have our setup done, let's see what happens when we view the page.
You can see that both the javascript files were just included as we would normally do. This is what happens when you have the "debug" flag set in your web.config.
Let's turn this to false and see what happens now.
Now what we see is a single reference was added but with a very unique looking location. By clicking on it, we see that it spits out a minified and combined version of both of the javascript files that were referenced in our bundle.
This funny query string parameter v=loMmcAiXrKwMoVsM8Ok8Q5jVmuFQUI3fiiRVJQC33Hs1 is a reference to our content and we can see that no matter how many times we hit the website, it's going to stay the same. (i.e. refreshing multiple times).
Let's see what fiddler says about the reference to our javascript files.
We can see that the response is cachable. The cache expiration has been set for "Wed, 26 Mar 2014 06:49:06 GMT". Almost a year from today.
Subsequent requests to the resource will get read from the browser's cache.
"This HTTP/304 response indicates that the existing cached response remains fresh. Cache-lifetime headers on a HTTP/304 response may be used to update the cached response's freshness."
If you require any more information, see also http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification
Related
I've updated some scripts within our TypeScript files, but users still seem to get the old versions of the bundled script. How do I know? Because I'm seeing (remote) JavaScript errors in our logs that refer to a class that 100% exists within the new latest version.
It has been more then 6 hours ago and I can verify that the ?={hash} has changed.
I have the feeling the suspects are, one way or in combination any of these:
Static content (IIS)
Scripts.Render("")
TypeScript compilation
Azure
I have the feeling it's in some kind of cache or that it has to do with static content serving. Or with the Script.Render().
What can the reason be? It drives me crazy, because I know the site is broken for some users, but I can't get a fix out.
I've included the headers below.
This is the code for the bundle. Note that core.js is being generated by TypeScript.
{
var bundle = new Bundle("~/scripts/main-bundle");
bundle.IncludeDirectory("~/scripts/fork", "*.js", searchSubdirectories : true );
bundle.IncludeDirectory("~/scripts/app", "*.js", searchSubdirectories : true );
bundle.Include("~/scripts/bundles/core.js");
bundles.Add( bundle );
}
Update
If they are getting the old HTML because it might be cached, so the hashbomb doesn’t change - shouldn’t they still have a consistent pair of JS and HTML?
https://poules.com/us doesn't have a cache-control:max-age specified so you probably have some users on browser cached html which would use the old scripts.
There is a s-maxage set, but that is only an override for public cache max-age which isn't set and this page cache is set to private; so I don't think it is doing anything.
Also, you can check Azure to see what is deployed if you have access to the Azure portal.
best way i find around any web interface that requires a forcing of update client is to use a manifest file, and have that specify the scripts. Your bundle needs to then update the manifest with the correct hash. I normally just use a grunt task for this and placeholders within the manifest.
You then manage the manifest in code. with listeners for updateReady and completed so you know when to refresh the browser.
On another note, Application Cache is for older browsers, for new browsers you have to use the Service worker in order to provide a facility to update your app.
With both applied you will have a release schedule you can manage and mitigate issues like you have been getting at the moment.
Another method if you have an API, is to allow the API to serve up Javascript, based on a given version number for the users current web front end. This way you can then inform the users that a more recent version is up to date, and offer a reload button.
However Application cache through manifest or service workers, is more accessible to other teams, if you have a split, front end and backend setup.
+++++++++++++++++++++
Another reason why, could be because your web font is blocked by ad blockers like Ghostery and AdGuard. This in turn creates a unhandled error
auth-dialog-window?openerOrigin=https%3a%2f%2fpoules.com&color=FF533C&pool=&openerType=iframe:82 Uncaught ReferenceError: WebFont is not defined
at auth-dialog-window?openerOrigin=https%3a%2f%2fpoules.com&color=FF533C&pool=&openerType=iframe:82
This could potentially stop other things from working and loading in the right way. You need to make sure that you are picking up and catching all errors and events for all of the users, no matter what plugins they use.
To be fair, on looking it could very well be the adBlockers that are your main issue here.
Anyway hope this all helps
Even if the hashbomb stays the same, the asset/bundle files do expire at their own pace but only after a day; at the moment of writing I see the following dates
Date: Fri, 25 May 2018 17:11:21 GMT
Expires: Sat, 25 May 2019 17:11:22 GMT
If you update your main-bundle at Fri 18:00:00, it might not be used until after Sat 17:11:22.
I also notice you are mixing public and private cache locations; by caching the bundles public, any proxy server (if one is involved) maintains its own cache by which the browser might get served, which might also result in a delay.
Is it an option to not cache your webpages so that the hashbomb is always up to date?
I also usually server my assets without caching but with the Last-Modified header,
doing so ensures that the browers at leasts makes a request for each asset providing the If-Modified-Since header, upon which IIS responds with te 304 status code if there's no change (so that no bytes go over the wire).
We have an ASP MVC 5 applications. We use bundles with optimization enabled by default. But we have heard several times from users, that they get errors, that we think are caused by old versions of user scripts. Their browsers somehow take scripts from cache, despite the fact, that we have edited that script files and bundles should be updated. The worst part of the problem is that we can't imitate or recreate this problem. We don't know how. We already have tried to make test-changes to scripts like adding some "console.log('test')" lines in order to see, if the browser takes the cached version, but everything was ok, the hash in the end of <script src="....?v='hash'"> changed and the browser took the newest version from first time. I should mention, that our site is a single page application. Don't know, maybe its somehow related with the problem.
Have you faced this kind of problem?
There's not enough information here to give a definitive answer. The bundler detects changes in files and will regenerate the bundle along with the link to that bundle, which will include an updated query string param. Since the query string is part of the URI, it's considered a totally different resource at this point, and the browser should fetch it again, because there is technically no cache available. The only logical reason this would not occur is if the HTML with the link to the bundle is not being updated. This can happen if you're using OutputCache or otherwise caching the HTML document. It can also happen if the client's browser is aggressively caching the HTML document. Unfortunately, there's not much you can do about that, as the client browser ultimately has control over what is or is not cached and for how long.
That said, given that this is a single page app, it's very possible that it's also including a cache manifest. This manifest will very often include the HTML file itself, and the browser will not refetch any file in the manifest unless the manifest itself is updated.
I have way too many pages in the application that basically load the same set of xml and js files for client side interaction and validation. So, I have about dozen lines like this one <script type="text/javascript" src="JS/CreateMR.js"></script> or like this one <xml id="DefaultDataIslands" src="../XMLData/DataIslands.xml">.
These same files are included in every page and as such browser sends request to read them every time. It takes about 900ms just to load these files.
I am trying to find a way to load them on just the login page, and then use that temp file as source. Is it possible to do so? If yes, how and where should I start?
P.S. A link to a tutorial will work too, as I have currently no knowledge about that.
Edit:
I can't cache the whole page, because the pages are generated at runtime based on the different possible view modes. I can only cache the js and xml file. Caching everything might be a problem.
Anyway, I am reading through the articles suggested to figure out how to do it. So, I may not be able to accept any answer right away, while I finish reading and try to implement it in one page.
Edit:
Turns out caching is already enabled, it is just that my server is acting crazy. Check the screenshot below.
With Cache
Without cache
As you see, with cache, it is actually taking more time to process some of the requests. I have no idea what that problem is, but I guess I should go to the server stack exchange to figure this out.
As for the actual problem, turns out I don't have to do anything to enable caching of xml and js files. Had no idea browsers automatically cache js files without using specific tag.
Totally possible and in fact recommended.
Browsers cache content that have been sent down with appropriate HTTP caching headers and will not request it again until the cache has expired. This will make your pages faster and more responsive and your server's load much lighter.
Here is a good read to get you started.
Here is ASP.NET MVC caching guide. It focuses on caching content returned from controllers.
Here is a read about caching static content on IIS with ASP.NET MVC.
Basically, you want to use browser caching mechanism to cache the src files after the first request.
If you're using F12 tools in your browser to debug network requests, make sure you have disable cache option unchecked. Otherwise, it forces browser to ignore cached files.
Make sure your server sends and respects cache headers - it should return HTTP status 304 Unmodified after first request to a static file.
Take a look at Asp.Net Bundling and minification - if you have for example multiple js source files, you could bundle them into one file that will be cached on the first request.
Additionally, if you use external js libraries, you could download them from a CDN instead of your server - this will both offload your server and enable user browser to use cached script version (meaning - if some other page that user has visited also used the same script, browser should already have it cached).
One approach is caching static files via IIS by adding <clientCache> element in web.config file. The <clientCache> element of the <staticContent> element specifies cache-related HTTP headers that IIS and later sends to Web clients, which control how Web clients and proxy servers will cache the content that IIS and later returns.
How to configure static content cache per folder and extension in IIS7?
Client Cache
for more info on client side caching read this part of Ultra-Fast ASP.NET 4.5 book:
Browser Cache and Caching Static Content
Other approach is caching portions of page.
if your are using Web Form:
Caching Portions of an ASP.NET Page
and if you are using MVC, use Donut Hole Caching
ASP.NET MVC Extensible Donut Caching
Donut Caching and Donut Hole Caching with Asp.Net MVC
The browser has to ask the server if the file has been modified or not since it put it to the cache, therefore the http statuscode 304. Read more from https://httpstatuses.com/304.
As this is asp.net please make sure you are first running it with
<compilation debug="false"/>
as enabling debugging has some side effects which include.
"All client-javascript libraries and static images that are deployed via
WebResources.axd will be continually downloaded by clients on each page
view request and not cached locally within the browser."
More read from https://blogs.msdn.microsoft.com/prashant_upadhyay/2011/07/14/why-debugfalse-in-asp-net-applications-in-production-environment/
I'm working on a .Net/ASP project and my responsibility is to work on the design part of the application only (mostly changing css, js, images, and cshtml files)
I'm working directly on the server, so my app is not running in visual studio or locally or any environment where I can rebuild the app.
That being said, any changes I make to the website takes about 45 minutes before it shows up (I do clear browser cache every time as well).
Is there any way I can manually clear the application cache or rebuild it on the server so my changes start showing immediately?
This is something I added to the we.config but still not helping:
<caching>
<outputCacheSettings enableOutputCache="false"/>
</caching>
Well, if I'm not mistaken the cache you're targetting is not about this kind of resources as they're simply not processed by .NET. This outputcache is rather about the final HTML rendered. So I don't think that's where you should be looking. But there may be some kind of proxy somewhere caching those resources aswell.
To avoid client/server caching problems with CSS and javascript, I usually add a time ticker to every request avoiding them to be cached client-side. It should also override any "server caching" of those resources, and I would advise testing it manually before putting an automatic solution in place. so, if you're including js file that way :
<script src="/mypath/myscript.js"></script>
you could just do that :
<script src="/mypath/myscript.js?123></script>
and see if you get the changes in the file immediately now. If yes, just automate the addition of that number (ideally a timestamp so it's always different on each request) to every javascript/css inclusion you make...
I have an ASP.NET 3.5 web application written in VS 2010. I have an aspx with a script reference to a .js file that resides in a Scripts folder.
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="Scripts/HeaderControl.js" type="text/javascript"></script>
Within the .js file I'm using jQuery to do some various operations, one of which was simply a debugging statement that used alert to spit out a value on the page so I could see what it was.
if ($) {
$(document).ready(function () {
$("input[id='q']").click(function($e) {
alert("clicked");
});
});
}
This all worked great until I went to remove the debug statement (the alert "clicked"). Upon completely removing it from the .js, I rebuilt the project, hit F5 to run it on my localmachine, but as soon as I clicked upon the input tag above the alert still popped up and said "clicked". I tried one thing after another trying to get the web app to realize that the .js had been changed, but it kept displaying the alert every time that I'd click on the input tag. I finally decided to rename the .js to something completely different, at which time the web app realized that the .js had been changed and it quit displaying the alert when I'd click upon the input tag.
So why was this .js file being cached? It's a very annoying behavior and I'd love to know what exactly was causing it. Any help would be appreciated. Thanks!
EDIT:
Browser was IE7. I didn't check to see if it did it in Mozilla as well. Regardless, I've done at least a 100 different .js files and I've never noticed this behavior before. The only difference for me is that this .js is in a web app, whereas usually I'm creating them in ASP.NET web site projects.
You need to Shift + Refresh, or, just clear your browser's cache.
This is normal behavior:
Javascript and CSS files do not even check for a new version (an If-Modified-Since request) if the old version is still valid according to the cache headers in the response sent the first time.
I believe that if you put in any query string, even just ?, at the end of the url (i.e., Scripts/jquery-1.4.1.min.js?) some browsers (Firefox at least) will change to check for a new version of the file every time like it will for images. This could be useful during development.
Some developers will also append a version to the file (?123) so that they can cause the browser to ignore the cache completely when a new version of a web app is released. I'm not sure how effective this is if you already have a question mark at the end, since it will be looking for an updated version anyway (again, not sure about all browsers).