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.
Related
I'm a bit confused on what I should be using, or if somehow the two can/should be combined. Some of the libraries I use (such as jQuery) are AMD modules, while others (such as bootstrap) are not, so I am having to use shim config to declare the dependency on jQuery.
Now, prior to starting to learn RequireJS, I was bundling jQuery, bootstrap, and some other very commonly used libraries, and loading them in the layout. This provided me with a single file that had to be downloaded.
Since I am now using RequireJS, all those scripts are pulled individually based on the needs of each page. I like the modular code, but isn't there a performance impact of having to load all these individually, even if it is RequireJS doing it asynchronously?
Should I somehow be using a combination of both technologies, and if so, how do I go about doing this?
EDIT:
I found this article as an example (http://therealmofcode.com/posts/2014/03/aspnet-mvc-bundling-minification-requirejs.html), but all the scripts in the ScriptBundle are modules, which allows RequireJS to find all the modules in the bundle. However, I want to be able to bundle other scripts that aren't AMD modules.
To answer the first part of the question...
Ideally both.
Loading scripts individually (async or otherwise) has a performance impact (more HTTP connections), but so does downloading larger bundled files.
Generally speaking, adding a few more KB to a bundle is better than making an extra HTTP request. Adding many more KB to a site-wide bundle is worse than making a new HTTP request for scripts that are only used on a few pages.
So the exact formula will be different for each site, depending on the number of scripts, their size, and their distribution throughout the site.
With this in mind I tend to create several bundles, one containing any site-wide scripts and several that are actually combinations of scripts as used by various pages throughout the site.
bundles.Add(new ScriptBundle("~/bundles/mainjs").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js",
"~/Scripts/site.js"));
bundles.Add(new ScriptBundle("~/bundles/forms").Include(
"~/Scripts/jquery.validate*",
"~/Scripts/dropzone.js",
"~/Scripts/bootstrap-datetimepicker.min.js",
"~/Scripts/trumbowyg.min.js",
"~/Scripts/select2.min.js",
"~/Scripts/autosize.min.js",
"~/Scripts/forms.js"));
Then load these bundled files with RequireJS.
The problem with this approach is...
It breaks RequireJS's modularity
As you point out, unless each script is an AMD then you can't use RequireJS's bundling feature.
So you will have to treat each bundle as a module in its own right (rather than a collection of modules) and make them dependant upon each other using a shim (not overly familiar with RequireJS so don't have a code example).
This approach loses a lot of the best functionality of RequireJS... so although It will generally perform better, it's still not and ideal solution.
Unfortunately we'll be stuck in this state of limbo with this until all of the useful libraries are AMD/UMD modules (Bootstrap 4 is coming with AMD/UMD support).
I'm using LESS CSS and Dot Less in my ASP.NET MVC project.
I'm directly referring LESS using bundles
bundles.Add(new LessBundle("~/styles/templates").Include("~/Content/Stylesheets/Templates.less"));
But this link saying if we use less.js in the html it will degrade the user performance. But i'm not using less.js in my project.
I've the following questions.
Shall I refer the less bundle directly in page?
If I refer LESS bundle directly, will it increase the performance?
You can not compare client side in browser version of less.js with Dot Less and bundle. The in browser version of less.js compiles your Less code client side (and does that again for each page request) and should not be used for production.
DOT Less compiles your Less code server side and bundle ensures that only the compiled CSS code loads in browser. Less code will only be compiled once and the compiled CSS will be used for each page request. You definitely should read: http://www.asp.net/mvc/overview/performance/bundling-and-minification
Use in your pages #Styles.render("~/styles/templates") this should not influence your performance.
NB consider using http://bundletransformer.codeplex.com/wikipage?title=Bundle%20Transformer%3a%20LESS cause it uses a newer version of Less.
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 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
Is it possible to use ASP.NET Web Optimization for minification without bundling?
Lets say I have a page Example.cshtml and corresponding javaScript file for that page Example.js. I would like to be able to do something like #Scripts.Render("~/Scripts/Views/Example.js") which will product minified file when not in debug mode. I could of course maintain many single JavaScript file bundles to do this but it seams like unnecessary chore.
Of course there are other solutions for javaScript compression but I think that single approach with run-time compression is the best way to go.
You would have to create a bundle with just one file to accomplish this currently.