I profiled my ASP.NET MVC application and I saw strange a function calls.
You can see it on image
Always when mvc render layout we invoke system.web.optimization.scripts.render which invoke JsMinify.Process and Minifier.MinifyJavaScript, but I thought what minification should be one time on the start app.
Am I right?
Maybe must I set some settings for optimization it?
Conditions:
localhost
release
BundleTable.EnableOptimizations = true;
Great Question!
Intuitively, you are right, minification of assets should be performed on application Startup. You assume that assets are delivered identically to all browsers. But Microsoft believes that much of JS and CSS is browser specific.
If you check asp.net site's reference on ASP.NET 4.5 Bundling and Minification, they specifically state:
Bundling and minification in ASP.NET 4.5 is performed at runtime, so
that the process can identify the user agent (for example IE, Mozilla,
etc) , and thus, improve the compression by targeting the user browser
(for instance, removing stuff that is Mozilla specific when the
request comes from IE).
:
What about caching?
Bundling isn't as obtuse as a profiled would have you think. If you look up MVC 4 Bundling and Minification reference, they point out:
Bundle Caching
Bundles set the HTTP Expires Header one year from when the bundle is
created. If you navigate to a previously viewed page, Fiddler shows IE
does not make a conditional request for the bundle, that is, there are
no HTTP GET requests from IE for the bundles and no HTTP 304 responses
from the server.
This is far more information than you need, but the message is that, JSMinify has a check for relevant cached minified assets.
When you factor in further that we already use minified version of our assets (eg jquery.min.js, jquery-ui.min.js), you can appreciate that .Net minification is a supplemental process.
Why does Minification of all types have to happen
Related
I was wondering whether it is possible to deploy two ASP.Net MVC sites to do the following.
Main Website: contains all the controllers and views
CDN website: contains all the JavaScript and CSS (bundles JS and CSS that is consumed by the first site)
I was expecting that in the solution you would have two website projects. I think in debug mode this would work fine because the bundle names are consistent.
However, in production where you are not running in debug mode (turned off in web.config), the file names have a query parameter that varies e.g. http://www.test-domain.com/bundles/bootstrap?v=2Fz3B0iizV2NnnamQFrx-NbYJNTFeBJ2GM05SilbtQU1 (where bootstrap is the name of the bundle).
Does anyone know how to reference the bundles in the CDN website from the Razor views in the main website?
Answer
I realised that you don't have to include the query parameter for bundle name
If your MVC 5 project work well in Release mode in your local machine, it will work on Production too.
Only few more considerations you need to take care on production are :
Make sure CORS is enabled since you have js & css resources at different site(if domain name is different)
Make sure you references at MVC5 site having hosting views & back-end logic have correct references as you have created in CDN
Firewall/hosting port is allowed on both hosting machine to communicate.
Hope this helps.
BTW querystring appended to end of URL just make sure every request is differently served by Server not as cached, nothing to impact your application.
I am about to start work on a non SPA ASP.NET MVC application and I was wondering what the best practices are for bundling and minifying.
I've been using webpack for react but this does not seem to fit in with a non SPA website or would this be a good fit?
I've used requirejs in the past where I used the data-main attribute to specify a file for the current view but I'm not sure how this would work with minified code where we would potentially only have 1 file.
I know .NET has its own ScriptBundler but is this still supported and should I perhaps use gulp instead?
If you're using ASP.NET MVC 5 or lower, then you can use both gulp and the script/style bundlers.
For instance, you could use gulp to do the minifying and use the script/style bundling to do the rest. This way you can use the non-minified scripts and styles during development (debug mode) whereas you only use the minified and bundled scripts in release mode.
Depending on your requirements, you can make multiple bundles and add those to your views. Performance wise, I'd suggest you use 2 bundles per page: 1 script bundle (near the closing body tag) and 1 style bundle (in the head section). Don't forget about common scripts and styles: those can be located the _Layout partial view. So you end up with 2 bundles per type per page.
I use this approach for my own projects. However, for ASP.NET Core applications, you should consider only using gulp. As far as I know, there isn't a real replacement for the bundling as we know it in ASP.NET MVC 5 applications, it just works a bit differently. But if you use gulp already, then you won't have big problems migrating to asp.net core (which you will at some point I guess).
I have at least 15+ javascript libraries & references in my MVC web application project. For each of these libraries they are independently bundled and minified. This means that when a page is requested the client browser is having to make 15+ connections to the server to retrieve resources.
Would it be considered bad practice to bundle all of these related files into a maximum of say 5 bundles so that the number of requests is kept low even though the scripts have nothing to do with each other and are completely unrelated?
Normally we would end up with few bundles. Some are
put all the scripts which are used again and again on ifferent pages as common.js
page type specific bundles, like in an eCommerce site we would potentially have productpage.js and checkout.js
I'm building a CDN, and looking for a ways to utilize .NET minification/bundling mechanism (System.Web.Optimization) there.
The question is how can I return minified bundle from MVC controller.
Note: I'm looking to use native .NET 4.5 capabilities, I do not want 3rd party solutions.
I'm only looking for ways to utilize this on CDN side. Not on client application side.
Additional question: If the above is possible at all, please explain how can I take advantage of caching, which is normally achieved through adding unique query string parameter to request.
The asp.net bundling and minification uses WebGrease internally.
Grab it off nuget and add just start using it. It looks like the codeplex site doesnt have any examples on there so you will need to look at the source code or download/decompile the asp.net source code to see how they use it.
For the query string parameter I believe that is mainly to prevent/aid client side caching it doesnt neccessarily have anything to do with your server side.
You haven't said how you plant to serve up the JS files from your custom CDN so I can't help much with the caching, I would highly suggest not serving them through mvc though, there will be a lot of extra things happening in the pipeline that you dont really need if all you're doing is serving static files.
Perhaps look at having some process that parses the files and sticks them in a certain directory that IIS can serve directly without delegating to asp.net
I understand how to use asp.net's new bundling and minification features. They are helpful during development.
Is there any benefit to using them in a production deployment though? Would the system perform better if you just placed the bundled/minified files on the web server? It seems that overall, less code would run if they were just static files.
Note: I understand the benefit of having js/css bundled and minified. I am only questioning the value of using an active runtime process to generate those files in a production system as opposed to simply storing them on disk and referencing them as static files.
Bundling and Minification is more useful in production than in development.
It can significantly improve your first page hit download time.
Bundling reduces the number of individual HTTP requests to server by combining multiple CSS files and Javascript files into single CSS file and javascript file.
Minification reduces the file download size of CSS and javascript files by removing whitespace, comments and other unnecessary characters.
Such small advantages are more pronounced in a production environment than in development. So it is better to go with Bundling and Minification in production.
Specific to your question there is no palpable benefit in bundling/minification during runtime. This feature is there just to make the developer's work easier. So it is even better to go with manually bundled/minified assets in production if you are sure about what you are doing.
Update:
According to MSDN there is a real benefit in bundling/minification during runtime
Bundling and minification in ASP.NET 4.5 is performed at runtime, so that the process can identify the user agent (for example IE, Mozilla, etc.), and thus, improve the compression by targeting the user browser (for instance, removing stuff that is Mozilla specific when the request comes from IE).`
The power of dynamic bundling is that you can include static JavaScript, as well as other files in languages that compiles into JavaScript.`
For example, CoffeeScript is a programming language that compiles into JavaScript
Bundling and minification provide 2 basic functionality in order to improve the performance of page load.
Bundling - Bundle all the provided scripts/ CSS in one file so that only browser need to load one file instead of multiple.
Note-> Generally browsers can may only 6 simultaneous requests to get resources from the server. Additional requests are queued by the browser for later processing. Hence, if we have multiple files then it may have to wait in the request queue.
Minification - Minification process generates a minified file by removing comments, extra white spaces and renames the variable names. So this reduces the file size and results in faster download.
Minification- smaller files, less kb on the wire, faster page load.
Bundling- browsers limit connection per http host. This means that a user goes to your page, and you have (let's say) 24 script and link (css) tags, your browser is handling them 6 (most browser's limitation) at a time - slowing the page load.
Bundling makes the browser treat all your files a single file - overriding this limitation.
Another benefit of bundling is it reduces caching issues. When we use bundling its loading to the page with a key, like below.
<script src="/bundles/jquery?v=FVs3ACwOLIVInrAl5sdzR2jrCDmVOWFbZMY6g6Q0ulE1"></script>
Each time we change our scripts it generates different key. So the file will be cached if we change something. But when we don't use this since script file has the same name, sometimes we have to clear cache to see the change.