How to bundle javascript files using Casette's Bundles.Reference() - optimization

In my MVC project I use both Web Optimizer and Cassette. The main reason I choose Cassette is because it has the ability to "inject" javascript and css to the html header/bottom body section from partial view or child action (or from anywhere). The reason I still use Web Optimizer is because it can have different bundles for files in the same directory (in comparison that Cassette default one bundle per folder, which does not work sometimes, for example, many different themes are in just one folder because they share files).
In my project I used a lot of third party jQuery plugins in different places. I bundled them together, and then in different pages I use the Bundles.Reference() to add to a page when it is needed. For example, in one page, I could use 5 plug-ins, and another page could use 6 plug-ins.
Bundles.Reference("content/plugins/plug1.js", "body");
Bundles.Reference("content/plugins/plug2.js", "body");
Bundles.Reference("content/plugins/plug3.js", "body");
When the page is rendered, Cassette would generate a tag for each of the references.
The main reason we use bundle is to try to reduce the requests to server whenever it is possible. But in this situation, the Cassette does not reduce the requests for javascript. It just like the same thing that I add the tag for each plugin (but I cannot inject to header/body bottom from partial view/child action).
So my question comes: is it possible that Cassette can "bundle" the different References that I use in different pages into just one single tag?
Many thanks in advance!

Related

Preloading webchunks based on route in VueJs

When I build my VueJs application, it automatically imports the app.js and chunk-vendor.js files with the preload attribute. This is great as it speeds up the page load time of my application.
I've looked at #vue/preload-webpack-plugin and I can see that I can preload specific webchunks or assets. This has the effect of preloading those files on all routes.
The thing I would really like to do is preload webchunks based on the initial route that is loaded (the first route the user visits).
Lets say I have two routes; home and accounts. Both of these routes are lazy loaded. When a user opens /home as their first page, I would like to preload the js and css webchunks related to the homepage. If the user initially opens the /accounts page, I would like to preload the webchunks related to the accounts page.
Its not possible to use wildcards in preload statements, so I know I can't do this statically.
Any ideas of how this could work? Has anyone heard of such a project being suggested elsewhere?
EDIT: Something I tried as an experiment was injecting preload headers into my index.html file using the beforeRouteEnter method. Whilst I could see the preload header in my DOM, I found that browsers did not observe the header in time, so the image I was experimenting with was not pre-loaded. In any case, this wouldn't have worked for a dynamically named file, but useful to know.
With SSR it is possible and framework like Nuxt does it automatically, because it builds separate html file for each route. So this html can be "tailored" for this specific route and include/preload all the code route needs...
Without SSR it much harder. #vue/preload-webpack-plugin works by injecting preload links into the index.html at build time and since there is only one index.html for a whole app, you can't make it route dependent (with this plugin). So what Vue CLI does is prefetching all the async chunks by default (clearly preferring speed over bandwidth usage)
I can imagine a solution in the form of Webpack plugin, which replaces preload-webpack-plugin and instead of generating preload/prefetch links at build time just generates some inline script with the map of "route name => chunk name" (some well defined naming convention would be needed) that would inject the links dynamically to the DOM base on the current URL. But even with my "googling skills" I wasn't able to find anything like that...

Jquery add loading=lazy to all images

I have a bigger webpage and it would take days to add the loading=lazy attribute to all img tags on my site. Is it useful to use something like $('img'). attr('loading', 'lazy') (does this work?) to the site, or will it just make the site more slower?
It doesn‘t necessarly have the expected effect - if you‘re adding the attributes via JavaScript, the page itself has already been parsed by the browser and their preloading scripts as well and all of those images would be been put to the download queue, as if the attribute wouldn‘t have existed on them.
So I would heavily recommend to add those attributes within the source code itself already.

ASP.Net Core route template behaviour

I've seen in some sample code that a route template ("{id:int}") on top of razor page causes the links to that page to use another pattern:
https://localhost/Movies/Edit/6
instead of
https://localhost/Movies/Details?id=6
My question is how asp.net manages to change all the links to that pattern, does it know about that page before rendering it?
Does it collaborate with other pages when processing a page?
When the application first starts, a collection of attribute routes are built. The routes are built for any Razor file with an #page directive in the root Pages folder, and for any other routes that have been defined via PageRouteConventions.
When you use the Url helper to generate links, or the anchor tag helper (which uses the Url helper behind the scenes), the link that gets generated is based on the attribute route that was built for the page that you pass to the helper.
In attribute routing, route parameters are added as segments in the URL, which is why the values are not appended as query string values. If you prefer query strings, don't declare route values as part of the #page directive.
Run the dotnet publish -c Release command and take a look inside the bin/Release folder.
You will not find your .cshtml files with html in them. What happaned where did all the html go? And how does this relate to the question?
You gotta remember that cshtml will endup being your regular ol' c# and all that fancy razor templating syntax end's up being c#. This process has many names and transpilation is one of them performed by transpilers.
Okey so now that we can safely assume that when you have a Index.cshtml file it will get populated in to some sort of an object, let's call it RazorPage.cs this will just store all the configuration for this page. Now let's say this index page is living in a folder called Home now we can have a dictionary Dictionary<string, RazorPage> and let's say that the key will be "/Home/Index". Following along based on transpiled #page "{id:int}" syntax, it might generate a template string for the route and store that in the RazorPage in a RouteTemplate parameter.
So when you use asp-page tag helper it will find the correct RazorPage and it can know the template for the url, populating it with the values you provided.
I haven't seen the actual implementation this is just my guess.
My question is how asp.net manages to change all the links to that pattern, does it know about that page before rendering it?
Yes it knows everything about the page at run time. Most likely the services.AddMvc() service takes care of loading in all the razor pages / views / controllers, at startup.
Does it collaborate with other pages when processing a page?
Highly likely no, unless you mean components/layouts/partials. It will however struggle to resolve a page if you have identical route for 2 pages.

Alfresco File Upload forms in a Share dashlet

I'm sometimes working on Alfresco dashlets that need a file-upload functionality. Instead of making stuff up, I want to use the YUI Uploader provided by Alfresco. For new pages that I build, it's easy, just list the components and put them in the page template. But for dashlets, I always have to put the upload components in the dashboard-1-column*, dashboard-2*... etc, in all of the dashboards.
I think that this is a needless HTML on a page, especially for those sites or users that don't use the dashlet in question.
Is there a neat way to include Alfrescos' file-upload forms (classes/alfresco/site-webscripts/org/alfresco/components/upload/* components) only in a dashlet?

MVC4 Bundling Strategy

I'm using the new Bundling feature in ASP.NET MVC4. Currently I have the following bundles configured:
~/js/jquery
~/js/forms
˜/js/bootstrap
Depending on the view I'm serving I usually call a combination of these three (e.g. the home page on needs the jquery bundle, while the contact page needs jquery + bootstrap, while forms need all three).
My question would be: is there a way to call the three bundles to be rendered as one file from the view? I don't want to make bundles for every possible combination:
˜/js/formsAndBootstrap
˜/js/formsAndJQueryAndBootstrap
And so on...
bundles.Add(new ScriptBundle("~/bundles/formsAndBootstrap").Include(
"~/Content/Scripts/jquery-1.7.2.js",
"~/Content/Scripts/bootstrap.js",
"~/Content/Scripts/form.js"))
It appears you have to define a bundle. It can't be done "on-the-fly" from the view.