MVC javascript file segregation/performance - javascript

Lets say an MVC3 project has a number of JavaScript files and libraries. These are referenced by a shared layout view, at the bottom of this page. The idea being the page loads faster as the libraries are included after the page main content. There is also no in-line JavaScript in the views.
The project has a number of areas and each has a number of controllers. There is however just 1 JavaScript file that contains all of the custom scripting and events for the whole site. So code unique to a particular controller will be included for all page loads.
Is there a better way to structure the files or to segregate the code so only relevant scripting is executed?
Edit:
So a strategy of splitting 1 large script file, or to only have scripting execute that's relevant to the current context. NO use initializing lots of event handlers for elements that do not exist on a page. Even manually checking if each element exists beforehand is an overhead in site wide file.

Related

Dynamic HTML content pages like Dropbox and Soundcloud

Check out the source code of Dropbox's main page or any Soundcloud page. You can see they've got a lot of Scripts going on, and little pure HTML content (article, main, p, div). I've been searching and it seems that way of generating pages is called dynamic content/HTML (correct me if wrong).
So, the function I think it has is to be able to edit multiple external separate files in Javascript (if that's the language it uses since they're scripts) so that the HTML documentes where they're linked to are generated dynamically.
Also, other possible function would be to have one external document, which let's say it's a navigation bar, and so you place it in multiple pages, and when you have to update, you just edit the external document and not each page (hooray!).
Questions:
Is it actually named Dynamic content?
What languages does it requires besides HTML, CSS, and JS? Like PHP or ASP (supposing if any is necesary at all).
Does creating pages in that way affects negatively/positively your website positioning in Google? Since I think when Googlebot reaches the page all it see are scripts.
There are two subtly different definitions of the word dynamic, which may be confusing your search for information about this. I'll answer your questions separately for each.
Dynamic as in "generated from content held in a database"
For example, on this page your reputation score was fetched from Stack Overflow's database and injected into the HTML.
Yes, this would be referred to as dynamic content. In contrast to static content, which would just be fixed files, dynamic content would be built up from its parts for each user who requests it.
Your second set of languages (PHP, etc.) are what read from the database and spit out the corresponding HTML.
Google's bot is smart: it can render pages and will see similar content to what you get in a browser. So generating pages dynamically instead of statically won't count against the site for SEO; dynamically generating lots of pages that are very similar might count against it though.
Dynamic as in "page content that updates without you having to refresh the whole page"
For example, as you wrote your question Stack Overflow tried to find similar questions and show them to you in case it had already been asked. JavaScript was sending a request to their server and updating part of the page in response.
This would also be referred to as dynamic content. The key difference is that it's JavaScript in the page that's making further calls to the server to fetch more content, which is what you're seeing on the minimalist sites you mention. This used to be called dynamic HTML (DHTML); more modern references are more likely to discuss it in terms of AJAX or "single page website".
Typically you'd have PHP or similar running on the web server, responding to the requests for content.
Again, Google's bot is smart enough to cope with this. That won't necessarily be the case for all search engines though.

javascript segregation/performance in an ASP.NET MVC Application

We have an MVC 4 web application with a number of areas.
There is a main layout view that is used by all the pages on the site and it contains all of the CSS includes, the render body tag, then all the JavaScript libraries.
<head>
<link rel="stylesheet" media="screen" href="~/Content/jquery-ui-1.10.3.custom.min.css" />
..
</head
<body>
<div id="main-content">#RenderBody()</div>
<script type="text/javascript" src="~/Scripts/jquery-1.10.2.min.js"></script>
..
</body>
The JavaScript consists of common libraries such as jquery, jqueryui and plug-ins.
There is also a single JavaScript file that contains the custom code for the whole site
Since there is only 1 large JavaScript file with thousands of lines, code routines are initialized by checking for the existence of a particular DOM element to decide if it proceeds.
runExample = function() {
if ($(".Example").length > 0){
// execute code
}
}
..
runExample();
This is of course problematic since there is a great deal of script included for all files, while there is code that applies to all pages, most of the code only applies to certain areas or pages.
Is there a better way to split the JavaScript up for the site? Keep in mind it is the custom code that is conditional, not necessarily the plug ins
Even if there way a way to create a JavaScript file for each area, how
would that be referenced within the main layout?
Is it best to load the JavaScript include files at the end of the include file?
What is the effect of minification on performance and would it benefit the custom code file?
Any advice would be appreciated.
First, use bundling. Give BundleConfig.cs under the App_Start folder in your project a gander. By simply minifying and bundling all your JS together, it's sometimes inconsequential that certain code is not actually being used on the current page (the savings you gain from having one cached JS file that every page uses is sometimes better than loading a new different bit of JS on each page.)
If you need more fine grained control, you can use something like Require.js. You essentially write your JS in modules that depend on other modules to run (all of your plugins, jQuery, etc. become "modules" in this scenario). You'll need to manually minify and combine your JS as much as logically possible, but this will allow you to integrate various scripts together without having to worry about load order and missing dependencies.
As a side note, I would respectfully disagree with Kevin B. If maintainability dictates that your JS has to be in the head, I would say that's a symptom of a larger problem with your code design. The only good reason to add JS in the head is when it's essential that the JS be run before the page is rendered. A good example is Modernizr, which for one adds classes to the html element to allow you to specify different styles and such depending on whether certain features are available in the user's browser or in the case of IE, what version the user is running. Without loading in the head, your style would changed after page load leading to flashes of unstyled content and such. Other than situations like these, all JS should go before the closing body tag, as JS is blocking: the browser will completely stop what it's doing and all rendering of the page, and run the script completely before continuing. Too much of this in the head, and your users stare at a blank page for far too long.
Also all script (and CSS for that matter) should be minified. There's no good reason not to, and the difference in bytes the user has to download is often quite dramatic. Especially in this day and age of mobile-everything and far-too-limited data plans, every byte truly does count.

Are there templating systems that allow you to edit HTML, CSS and Javascript in the same file?

When you have a small HTML template, wouldn't it be nice to have the CSS and Javascript that relate to it (binding of events, etc.) in the same file right next to the HTML?
You could just put them in and tags, but normally you don't want to do this, because when you render the template many times you'll end up multiplying the code over and over again in the DOM. Besides, every respecting webdeveloper wants their CSS and Javasciprt in separate files.
But it's actually pretty simple to implement a system that goes through all your templates, removes all the tags with their contents and puts them into one big .css file and then the with contents to .js file, so that you can load them from separate files, and finally the tempalates are left with only HTML in them.
I'v done this and i'm still learning with the best practices on how to use it (eg. what parts of Javasript do you want to put there?), but it feels like the way i'd always want to develop web apps. So i'm wondering if there are any systems that use the same method.
Parsing HTML to remove duplicate tags as a standard practice seems wrong. Separating content, style and behavior should be a first class priority in any case. Why combine something just to rip it apart again? Imagine your CSS differs slightly among files. How does your parser know which one to keep?
IMO a proper templating approach for Javascript has a main HTML file, which is loaded using a HTTP request, which again links the CSS and JS for the rest of the application. This first file can as well link JS template files (like e.g. .jst) or these are loaded later on demand using an AJAX request. Nevertheless are these templates usually only containing structure, content comes from e.g. a JS model using a JSON connection to some kind of storage, "styling" is provided by the previously loaded CSS files.
Related: backbone.js and sammy.js

Javascript and website loading time optimization

I know that best practice for including javascript is having all code in a separate .js file and allowing browsers to cache that file.
But when we begin to use many jquery plugins which have their own .js, and our functions depend on them, wouldn't it be better to load dynamically only the js function and the required .js for the current page?
Wouldn't that be faster, in a page, if I only need one function to load dynamically embedding it in html with the script tag instead of loading the whole js with the js plugins?
In other words, aren't there any cases in which there are better practices than keeping our whole javascript code in a separate .js?
It would seem at first glance that this would be a good idea, but in fact it would actually make matters worse. For example, if one page needs plugins 1, 2 and 3, then a file would be build server side with those plugins in it. Now, the browser goes to another page that needs plugins 2 and 4. This would cause another file to be built, this new file would be different from the first one, but it would also contain the code for plugin 2 so the same code ends up getting downloaded twice, bypassing the version that the browser already has.
You are best off leaving the caching to the browser, rather than trying to second-guess it. However, there are options to improve things.
Top of the list is using a CDN. If the plugins you are using are fairly popular ones, then the chances are that they are being hosted with a CDN. If you link to the CDN-hosted plugins, then any visitors who are hitting your site for the first time and who have also happened to have hit another site that's also using the same plugins from the same CDN, the plugins will already be cached.
There are, of course, other things you can to to speed your javascript up. Best practice includes placing all your script include tags as close to the bottom of the document as possible, so as to not hold up page rendering. You should also look into lazy initialization. This involves, for any stuff that needs significant setup to work, attaching a minimalist event handler that when triggered removes itself and sets up the real event handler.
One problem with having separate js files is that will cause more HTTP requests.
Yahoo have a good best practices guide on speeding up your site: http://developer.yahoo.com/performance/rules.html
I believe Google's closure library has something for combining javascript files and dependencies, but I havn't looked to much into it yet. So don't quote me on it: http://code.google.com/closure/library/docs/calcdeps.html
Also there is a tool called jingo http://code.google.com/p/jingo/ but again, I havn't used it yet.
I keep separate files for each plug-in and page during development, but during production I merge-and-minify all my JavaScript files into a single JS file loaded uniformly throughout the site. My main layout file in my web framework (Sinatra) uses the deployment mode to automatically either generate script tags for all JS files (in order, based on a manifest file) or perform the minification and include a single querystring-timestamped script inclusion.
Every page is given a body tag with a unique id, e.g. <body id="contact">.
For those scripts that need to be specific to a particular page, I either modify the selectors to be prefixed by the body:
$('body#contact form#contact').submit(...);
or (more typically) I have the onload handlers for that page bail early:
jQuery(function($){
if (!$('body#contact').length) return;
// Do things specific to the contact page here.
});
Yes, including code (or even a plug-in) that may only be needed by one page of the site is inefficient if the user never visits that page. On the other hand, after the initial load the entire site's JS is ready to roll from the cache.
The network latency is the main problem.You can get a very responsive page if you reduce the http calls to one.
It means all the JS, CSS are bundled into the HTML page.And if your can forget IE6/7 you can put the images as data:image/png;base64
When we release a new version of our web app, a shell script minify and bundle everything into a single html page.
Then there is a second call for the data, and we render all the HTML client-side using a JS template library: PURE
Ensure the page is cached and gzipped. There is probably a limit in size to consider.We try to stay under 400kb unzipped, and load secondary resources later when needed.
You can also try a service like http://www.blaze.io. It automatically peforms most front end optimization tactics and also couples in a CDN.
There currently in private beta but its worth submitting your website to.
I would recommend you join common bits of functionality into individual javascript module files and load them only in the pages they are being used using RequireJS / head.js or a similar dependency management tool.
An example where you are using lighbox popups, contact forms, tracking, and image sliders in different parts of the website would be to separate these into 4 modules and load them only where needed. That way you optimize caching and make sure your site has no unnecessary flab.
As a general rule its always best to have less files than more, its also important to work on the timing of each JS file, as some are needed BEFORE the page completes loading and some AFTER (ie, when user clicks something)
See a lot more tips in the article: 25 Techniques for Javascript Performance Optimization.
Including a section on managing Javascript file dependencies.
Cheers, hope this is useful.

Is it better to minify javascript into a single bundle for the whole site, or a specific-to-each-page bundle?

When minifying JavaScripts together in web-development, is it better from the user-loading-time point of view to:
make one single big bundle of JavaScript containing all the script, and include this on each page - so each page will probably not need all of it, but once the user has it cached, they don't need to get any further scripts (until it expires from their cache, of course) - optimising for number-of-requests
make one bundle of JavaScript per page, so that each page loads just the script that it needs and nothing else - so each page when first loaded will definitely require a JS request (but still subsequently have that cached. Optimising for size-of-requests.
I'm interested in some data upon which to base the decision for which strategy to go with. I can arrive at conclusions based on anecdote as easily as everyone else :-)
It really depends on the sizes and functions of the script. It's common to have a single master.js for all your pages, which contains all the functionality required by every page of your site, whilst having other js files for functionality that might only be needed on certain pages.
Take Stack Overflow, for instance. They have a master.js file included on every page of the site, but when you visit a question page or the "ask a question" page you'll notice wmd.js. This script includes all the functionality for the editor which is needed on fewer pages.
I would much rather have 1 minified js file for the entire site. Over a period of time this always performs better than having multiple js files.
Check out this link for more details
It depends entirely on what's in your scripts. If you've got loads of small functions which are used by a wide selection of pages then yes, a single file will be best. If you've got a large script that's only used by one page, you wouldn't typically want to slow down the initial front-page load time by including it in the shared script.
So what you will typically end up with is a compromise, with base functions shared across all pages in one script, and the more complex and specific functions in per-page or per-page-group scripts. It'll very rarely be beneficial to go the whole option-2 hog and have a completely separate script for each page.
Having shared functions in one file and separate page-specific complex scripts is also typically more maintainable.
If you are implementing websites in ASP.NET MVC, then you may find the following approach as the most sensible, one which I use all the time.
Make a list of all of the JavaScript files used in the project - ones used everywhere and those used by many or most pages. This defines your common bundle, which you should include from your master page. MVC4's Bundle & Minification feature does the magic there, you just need to list them.
The rest of JavaScript is usually for local use, i.e. within just one view, effectively implementing the view. And for that reason it should reside within the view, completely uncompressed.
For example, I make extensive use of AngularJS within views, so each such view contains its own angular controller and other local elements as needed. Depending on the view complexity, it can even have its own set of directives, services and factories, although typically those go into a partial view of one-two levels up.
The bottom line is, do not try to burden yourself with bundling JavaScript that's meant for local use. Bundle only the most generic stuff, and do it in just one place - your product's master page. Leave local JavaScript uncompressed in local files where it is used. This has no real effect on performance, while making your code much easier to understand and maintain.

Categories

Resources