ASP.NET MVC Bundles debug = true and result is still cached - asp.net

In my development environment the Javascript isn't showing the changes I've made, Why is it still caching, What else can I do?
The only documentation I've seen on this is the web.config, compilation debug=true setting,

When you set debug="true", the bundler will emit script or link tags to each resource individually, rather than a one for a single (optionally) optimized resource. As such, the resource will be accessed from the static handler directly by the browser. So, if your application or IIS settings have aggressive settings for caching static content, that would be your problem.

Use Control+F5 to force a re-download of content. This should work in most browsers.

Related

Loading src files once per session in asp.net

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/

ASP Project, workingn the server: Rebuild or clear application cache

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...

How can I make sure that static content is cached client-side?

How can I make sure that static content (images, css, javascript) is cached? What is the best approach?
Will recommend you to go through this tutorial to understand how caching happens on web (HTTP) in general.
Simply speaking, the web server needs to generate appropriate HTTP headers while sending the content to the client in order to control client-side caching. In ASP.NET/IIS environment, its IIS that typically handles the static file contents and therefore, you must configure IIS appropriately to control caching static files as per you needs. See below links for more information about configuring IIS caching for static content:
http://www.iis.net/ConfigReference/system.webServer/staticContent/clientCache
How to configure static content cache per folder and extension in IIS7?
EDIT: As you have asked about the best approach, the most prevalent approach that I see now days is to version static content (say by appending some version identifier at the end of file or URL). Once version-ed, you can treat it as immutable and then emit cache headers for caching it for infinite duration. In ASP.NET application, you can probably append the assembly version (or product version) to each static content URL. So essentially, you will invalidating the cache for every build (or every product release).
You can also make use of the HTML5 Offline web applications manifest. It allows you to set up a manifest where you define which files will be cached locally.
It is a nice, clear to understand broadly implemented, way of avoiding having to learn about IIS and HTML Caching.
http://www.w3schools.com/html/html5_app_cache.asp
(you should totally read up about those things)

Must .aspx files have a page directive?

Around 90% of the pages for our websites have no .Net code embedded in them yet are published as .aspx files. I want these to render as fast as possible so I'm removing as much as I can.
Does the .Net page directive have an impact on performance? I am thinking about two factors; the page speed for each GET and what happens when the file changes. The CMS system re-creates each page daily and I'm wondering if this triggers the ASP.Net compilation process.
If your pages have no .NET code and rendering speed is your goal, you may wish to consider changing the extension to .html. Any .aspx page will be passed to the .NET ISAPI filter by IIS and go through the entire chain of HttpModules, then will be handled by the Page HttpHandler. Using a .html extension would trigger IIS to process the request using the Static Resource ISAPI filter, which has a much shorter pipeline and is tuned for resources that run no code.
The <%# Page %> directive is not required. Without it, the default values for Language and other stuff will be assumed.
By changing a .aspx file, it'll be recompiled (it doesn't recompile the whole app though):
Any changes to a dynamically compiled file will automatically invalidate the file's cached compiled assembly and trigger recompilation of all affected resources. The next time a request to the code is made, ASP.NET recognizes that the code has changed and recompiles the affected resources of the Web application. This system enables you to quickly develop applications with a minimum of compilation processing overhead. (Note that depending on the change to the resources, the result can range from recompiling a single page to recompiling the whole Web site.)
Ok, put them in - just to be sure.
.NET pages are ALL compiled, page directive or not. nothing changes. Post compilation, they are as fast as it goes, as they turn into a class (type loaded once) that just executes.
Note that the post by Mehrdad Afshari is factually wrong (sadly I can not tag it). Any page change triggers a complete recompile AND restart of the appdomain. Acutally any FILE change does so, as long as it is outside App_Data and ASP.NET can see it (i.e. non-hidden flag on the directory / file).

ASP.NET AJAX Load Balancing Issues

This would be a question for anyone who has code in the App_Code folder and uses a hardware load balancer. Its true the hardware load balancer could be set to sticky sessions to solve the issue, but in a perfect world, I would like the feature turned off.
When a file in the App_Code folder, and the site is not pre-compiled iis will generate random file names for these files.
server1 "/ajax/SomeControl, App_Code.tjazq3hb.ashx"
server2 "/ajax/SomeControl, App_Code.wzp3akyu.ashx"
So when a user posts the page and gets transfered to the other server nothing works.
Does anyone have a solution for this? I could change to a pre-compiled web-site, but we would lose the ability for our QA department to just promote the changed files.
Do you have the <machinekey> node on both servers set to the same value?
You can override the machine.config file in web.config to set this. This needs to match otherwise you can get strange situations like this.
Does your load balancer supports sticky sessions? With this on, the balancer will route the same IP to the same server over and over within a certain time window. This way, all requests (AJAX or otherwise) from one client would always hit the same server in the cluster/farm.
Ok, first things first... the MachineKey thing is true. That should absolutely be set to the same on all of the load balanced machines. I don't remember everything it affects, but do it anyway.
Second, go ahead and precompile the site. You can actually still push out new versions, whenever there is a .cs file for a page that page gets recompiled. What gets tricky is the app_code files which get compiled into a single dll. However, if a change is made in there, you can upload the new dll and again everything should be fine.
To make things even easier, enable the "Used fixed naming and single page assemblies" option. This will ensure things have the same name on each compilation, so you just test and then replace the changed .dll files.
All of that said, you shouldn't be having an issue as is. The request goes to IIS, which just serves up the page and compiles as needed. If the code behind is different on each machine it really shouldn't matter, the code is the same and that machine will reference it's own code. The actual request/postback doesn't know or care about any of that. Everything I said above should help simplify things, but it should be working anyway... so it's probably a machinekey issue.
You could move whatever is in your app_code to an external class library if your QA dept can promote that entire library. I think you are stuck with sticky sessions if you can't find a convenient or tolerable way to switch to a pre-compiled site.
If it's a hardware load balancer, you shouldn't have an issue, because all that is known there is the request URL, in which the server would compile the requested page and serve it.
the only issue i can think of that you might have is with session and view state.
Its true the hardware load balancer could be set to sticky sessions to solve the issue, but in a perfect world, I would like the feature turned off.
It appears that the is only for ViewState encryption. It doesn't affect the file names for auto compiled assemblies.
I think asp.net model has quite a bit dependency for encryption and machine specific storage, so I am not sure if it works to avoid sticky IP for session.
I don't know about ASP.NET AJAX (I use MonoRail NJS approach instead), but session state could be an issue for you.
You have to make sure session states are serializable, and don't use InMemory session. You probably need to run ASP.NET Session State Server to make sure the whole frontend farm are using the same session storage. In such case session has to be perfectly serializable (thats why no object in session is preferred, you have to always use ID, and I bet MS stick on this limitation when they do AJAX library development)

Resources