Should I use RequireJS or ASP.NET bundling, or both - asp.net-mvc

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

Related

Best way to use Vue 3 components built elsewhere in an ASP.NET project's views?

I'm rewriting some templates and functionality previously developed using AngularJS 1.x which are currently managed and developed as static assets in an ASP.NET MVC application and are used alongside razor syntax (.cshtml). There are no components either. Imagine the AngularJS modules as a huge bunch of jQuery code linked and coupled with views.
This time, I'm implementing everything we need in a Vue 3 app in a separate git repository and I'm also using Vuex 4.
I'm hoping to be able to do the following:
Build the Vue app
Load the assets in BundleConfig.cs
Link the assets to my _layout.cshtml to have them on all my pages.
Use the components wherever I need them.
I'm going well on developing the components and functionalities within its standalone project, yet I'm facing several problems and/or ambiguities.
I have pages that are mostly if not entirely rendered by the client-side. These pages may or may not be handled by a client-side router such as vue-router.
I also have pages that are mostly rendered by the server and then stuff is added or dynamic contents are loaded by the client-side. These pages can't use a client-side router.
I'm not using a router and I'm having a hard time developing and testing those pages that are mostly rendered by Vue.
if I use a router I think I won't be able to do what I'm planning to do about those pages that are mostly rendered by the server. I really need all pages (whichever kind they are) to have access to my Vuex store.
What do you recommend I do to make it easier for myself both in development and production?
Should I create several static HTML files for each of my pages in Vue's public directory tweak Webpack's configuration in order to simulate what will happen in production (use within the ASP.NET project)?
Should I start having a router, put all pages that are mostly CSR under its control, and somehow configure it to have nothing to do with my other pages that are mostly SSR?
I need to be able to debug and test stuff when I run npm run serve and then do what I'm tasked to do. Unless the whole plan is a bad/wrong idea somehow.
I might also be able to build my Vue app as a library and then, in the ASP.NET project, init a small Vue app that imports that library and that itself is bundled with the back-end project. The whole reason I'm doing this is to make the client-side stuff reusable and easy to maintain. I don't want to take a GET SHIT DONE approach.
Thanks

Bundling unrelated javascript script resources

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

ASP.NET Web Optimization - Minification without bundling

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.

What is the benefit of ASP.NET bundling and minification in runtime?

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.

Why are there so many javascript files in my empty MVC 2 project?

When creating an empty MVC 2 project, I have a lot of javascript files in my Scripts folder. Why? Will removing them affect my application?
No removing them won't affect anything, unless they are being used in pages. However you said this is an empty MVC project so you'll be fine.
They're there for you to use, to make your life easier. For example, JQuery is included.
Take for example JQuery file, It provieds functions which has solutions for crossbrowser related issues which makes developement easy. Similarly other files has functions whcih are providing readymade functionalities which can be used for rapid developement.
Unfortunatly as JS is traveling to browsers its downloaded on the client. Its suprising for not JS people as its not like .NET api where one or more dll is sufficient for all the api and developer dont have to worry(some times :)) about from where they are coming.
I will suggest you to study included JS files and include/use only those which you really wanted to use.

Resources