My latest project is using a javascript framework (jQuery), along with some plugins (validation, jquery-ui, datepicker, facebox, ...) to help make a modern web application.
I am now finding pages loading slower than I am used to. After some js profiling (thanks VS2010!), it seems a lot of the time is taken processing inside the framework.
Now I understand the more complex the ui tools, the more processing needs to be done. The project is not yet at a large stage and I think would be average functions. At this stage I can see it is not going to scale well.
I noticed things like the 'each' command in jQuery takes quite a lot of processing time.
Have others experienced some extra latency using JS frameworks?
How do I minimize their effect on page performance?
Are there best practices on implementation using JS frameworks?
Thanks
My personal take is to use the framework methods and tools where they make sense and make life easier, for example selectors and solving cross-browser quirks, and to use plain old vanilla JavaScript where there is no need to use the framework methods, for example, in simple loops.
I would check and double check the code that you have that uses the framework to ensure that it will perform as well as it can; it is all too easy to use a framework in a poor performing fashion and sometimes one doesn't discover this until one profiles it :)
Frameworks do introduce extra latency as there are usually a number of functions that are executed as a result of using the entry point function into using them.
EDIT:
Some general points with regards to using jQuery:
1.cache your jQuery objects in local variables if you are going to use them more than once. Querying the DOM is a relatively expensive operation and therefore should be done as little as is needed. If you have related selectors, take a look at performing a wide selection and then using the methods such as find(), filter() next(), prev() etc to filter the collection to get the relevant elements that you would have usedanother selector function to get.
2.Inside of functions, don't wrap objects in jQuery objects unneccessarily. If there is a cross browser way of accessing an object property value that is reliable, then use that. For example, the value property of a text input HTMLElement
$('input:text').each(function() {
// use
this.value
// don't worry about this
$(this).val();
});
3.Try to avoid adding large script files where you're using only a small piece of the functionality. There can be a lot of time spent parsing and executing code on page load that you're never going to use! If possible, extract only the relevant code that is needed. I appreciate that this can be hard and is not always possible, particularly when it comes to versioning, but it's worth pointing out nonetheless.
Related
For example if you write a plugin you could do this $('#myDiv').doAction() instead of doAction($('#myDiv')). and you have to admit, the first one looks more intuitive. Are there any clear drawbacks of this like performance hits?
You won't see any noticeable performance hit from this, but there is one potential drawback: namespacing your code is very valuable, and makes it easier to maintain (as you probably know). Throwing everything into jQuery.fn may not be the best way to do this.
Personally, I shy away from extending jQuery with very specific things (like app-specific logic or something) but whole-heartedly recommend it for general, DOM-level things (.hasAttr() and .scrollHeight() are two I use a lot). The reason is that there are better places to put app-specific logic (in the module in charge of that area of the app, for example).
A simple heuristic: would it be useful to other people if I made this a public extension? Or is this only relevant to this particular project?
That said, there is no concrete problem with doing this in your code. It's more a semantic issue: is that the best place for it?
Write a jQuery plugin so that you do not need to repeat this over and over again.
There are literally minimal performance issue with this, and mindful that this is at client side, it does not attribute to your server resources.
There aren't any performance hits choosing one approach over the other. It's more of a question of, do you need it as a jquery plugin? I create regular functions if it's a utility function and doesn't need to act upon a jquery object. If it does, then it should be a plugin (no need to pass in the jquery object as a parameter, and you can chain)
You seem to be using jQuery as a framework. It is not one.
Please use a client-side MVC style library like backbone/knockout/sammy/eyeballs for seperations of concerns and structure
Please use an AMD loader like curl/requirejs for modularisation of your code.
This is more of a question of style and preference than anything, though it's possible that there might be performance considerations as well.
If you're using a framework (say jQuery for the sake of argument, though it could be any framework) and you need to write a new function. It's a simple function, and you could easily accomplish it without using the framework.
Is there an advantage to using the framework anyway, because it's already loaded in the browser's memory, has a readily-accessible map of the DOM, etc.? Or will plain-vanilla js always parse faster because it's "raw" and doesn't depend on the framework?
Or is it simply a matter of taste?
The answer is going to depend greatly on what you're working to accomplish. In general, you're guaranteed at least a minor performance penalty for function overhead if you use a framework to achieve something that can be accomplished using "vanilla" JavaScript. This performance penalty is typically nominal and can be disregarded when taking other advantages of your framework into mind (speed of development, cleaner code, ease of maintenance, reusable code, etc).
If you absolutely have to have the most efficient code possible then you should try to write pure JavaScript that's highly optimized. If, like in most real world scenarios, you're not concerned about a handful of milliseconds in performance difference, stick with your Framework to maintain consistency.
There's always something to learn when you're solving problems with pure JS as opposed to having external code do it for you. In the long run, it's more maintainable because it's your code. It's not going to change. You know what it does. That's where the value of solving your own problems really comes into play. If you do your research on MDC, MSDN, and the ECMAScript spec, cross-browser scripting becomes a lot easier to process. Sure, Microsoft has their own ideas and their own DOM, but that's where the fun (read: challenge) is.
Cross-browser scripting in pure JS really heightens your problem-solving ability along with your understanding of the language. If there still are things that confound you, then jQuery can come into the mix and bridge the mental gap, so to speak. It's great to drive around in a luxury vehicle, but what use is it if you don't know how to change a tire when it goes flat? The best jQuery devs are the ones that know JavaScript well and know when to use jQuery, and when to use plain JS.
Sometimes, you just have to roll up your sleeves and do some hard work. There isn't a jQuery plugin for everything, and jQuery can't hide you from all the quirks that various browsers have to offer. Getting the job done with your own code is very rewarding, even if you had to sweat it out to make it work.
It's perfectly acceptable to use many different tools to complete a singular task. You just need to know when and where to use them.
From my understanding of jQuery it doesn't actually maintain a map of the dom in Memory and just has cross browser methods for walking the dom. Somethings will natually be faster in some browsers over others (such as a class based selector in Firefox will be faster than in IE because IE doesn't have a built in function for getElementsByClassName and Firefox does). If you don't need the frameworks methods for doing things I would say go ahead and use the native JS as that is generally what you chosen framework will use.
I would say do it with the framework, just because it will bring consistency inside the project. If you are using the framework everywhere even in small function, it will be easier to maintain.
As for the other factor it really depends on what you are trying to do.
I've been working on a javascript-heavy project. I've found that almost every time I had a cross-browser bug in my code, it was in a place where I had code like this:
var element = $(selector);
// lots of code ...
element[0].someVanillaOperation();
and that vanilla wasn't exactly the same across all browsers. What I love about jQuery is that (most of the time) it hides the browser differences and its functions work the same across them all.
If you're selecting elements by ID then plain Javascript is faster. It doesn't, however, provide any of the selection niceties that you get with jQuery - selecting multiple elements by class in a single call, for example.
Take a look at this link: http://www.webkit.org/perf/slickspeed/ which runs a speed test. It's an older version of jQuery, but the results in terms of raw speed speak for themselves.
Personally, I tend to use jQuery for everything - it keeps the code cleaner and the fact it pretty much dispenses with cross-browser JS support issues is worth any performance overhead in my book.
Coming from Java, I'm wondering if a Java best practice applies to JavaScript.
In Java, there's a separation of interface and implementation, and mixing them up is considered a bad practice. By the same token, it is recommended to hide implementation details of your library from end developers.
For example, log4J is one of the most popular logging libraries out there but it is recommended to write code to the slf4j library or the Commons Logging library that "wraps" log4j. This way, if you choose to switch to another logging framework such as logback, you can do so without changing your code. Another reason is that you, as a user of a logging library, how logging is done is none of your concern, as long as you know what logging does.
So back to JavaScript, most non-trivial web applications have their own custom JavaScript libraries, many of which use open source libraries such as jQuery and dojo. If a custom library depends on, say jQuery, not as an extension, but as implementation, do you see the need to add another layer that wraps jQuery and makes it transparent to the rest of JavaScript code?
For example, if you have the foo library that contains all your custom, front-end logic, you'd introduce the bar library that just wraps jQuery. This way, your foo library would use the bar library for jQuery functions, but it is totally oblivious to jQuery. In theory, you could switch to other libraries such as dojo and google web toolkit without having a big impact on the foo library.
Do you see any practical value in this? Overkill?
Although it makes sense from a theoretical standpoint, in practice I'd say it's overkill. If nothing else for these two reasons:
Anything that adds to the size of
the request (or adds more requests)
is bad - in web world, less is more.
If you're using say jQuery, the
chances of you switching to
something like Mootools is (imho) slim to none. From what I've seen, the top libraries each aim to solve different problems (at least in the case of Mootools and jQuery - see this great doc for more info on that). I'd assume that you'd incur a tremendous amount of headache if you were to try to implement a middleware library that could easily switch between the two.
In my experience and being a Java developer myself, sometimes we tend to take the whole "abstraction" layer pattern too far, I've seen implementations where someone decided to completely abstract a certain framework just for the sake of "flexibility" but it ends up making things more complicated and creating more code to maintain.
Bottom line is you should look at it on a case by case basis, for example you wouldn't try to create an abstraction layer on top of struts, or on top of JPA, just in case you then go to a different framework (which I've rarely seen done).
My suggestion is, regardless of the framework you are using, create objects and components that use the framework internally, they should model your problem and be able to interact between them without the need of any specific framework.
Hope this helps.
There are a lot of good answers here, but one thing I don't see mentioned is feature sets. If you try to write a library to wrap the functionality provided by, say, jQuery, but you want to be able to easily swap out for something like prototype, you have a problem. The jQuery library doesn't provide all the features prototype provides, and prototype doesn't provide all the features jQuery provides. On top of that, they both provide their features in radically different ways (prototype extends base objects -- that's damn near impossible to wrap).
In the end, if you tried to wrap these libraries in some code that adds 'abstraction' to try to make them more flexible, you're going to lose 80% of what the frameworks provided. You'll lose the fancy interfaces they provide (jQuery provides an awesome $('selector') function, prototype extends base objects), and you'll also have to decide if you want to leave out features. If a given feature is not provided by both frameworks, you have to either ditch it or reimplement it for the other framework. This is a big can of worms.
The whole problem stems from the fact that Java is a very inflexible language. A library provides functionality, and that's it. In JavaScript, the language itself is insanely flexible, and lets you do lots of crazy things (like writing a library, and assigning it to the $ variable). The ability to do crazy things lets developers of javascript libraries provide some really creative functionality, but it means you can't just find commonalities in libraries and write an abstraction. I think writing javascript well requires a significant change in perspective for a Java developer.
Someone wise once said "premature optimization is the root of all evil." I believe that applies in this case.
As others have expressed, you don't want to abstract for the sake of flexibility until you have an actual need for the abstraction. Otherwise you end up doing more work than necessary, and introducing unnecessary complexity before it is required. This costs money and actually makes your code more brittle.
Also, if your code is well organized and well tested, you should not be afraid of major changes. Code is always changing, and trying to anticipate and optimize for a change that may or may not come will almost always get you in more trouble than it saves you.
Acknowledgement: I should give credit to Agile programming and my practice and readings on the topic. What I've said comes directly from my understanding of Agile, and I've found it to be an extremely good razor to cut out the extra fat of my work and get lots done. Also none of what I've said is actually JavaScript specific... I'd apply those principles in any language.
There are good arguments calling this development practice - wrapping in order to switch later - into question in any language.
A good quote by Oren Eini, from his writeup on wrapping ORMs:
Trying to encapsulate to make things
easier to work with, great. Trying to
encapsulate so that you can switch
OR/Ms? Won’t work, will be costly and
painful.
This is definitely something that is done in enterprise environments.
Take for example a company that has their own custom javascript framework that is used on all of their projects. Each of the projects decide to use their own framework (jQuery, Dojo, Prototype) to add functionality to the underlying modules of the company framework. Employees that move between projects can now easily do so because their API with working the project's codebase is still the same, even though the underlying implementation could be different for each project. Abstraction is helpful in these situations.
It is overkill. Javascript is not Java and is not in any way related to Java. It is a completely different language that got J-a-v-a in the name for marketing reasons.
If you are concerned with availability of add-on libraries, then choose a framework with a large ecosystem. In an enterprise environment you will be further ahead by standardising on a vanilla off-the-shelf uncustomised web framework that you can upgrade every year or so tracking the rest of the world. And then supplement that with a SMALL in-house add-on library which you will, of course, have to maintain yourself, not to mention training any new programmers that you hire.
Since you are talking about Javascript in the client (web browser) it is more important that you limit the complexity of the things that people do with it. Don't build huge amounts of client side code, and don't make stuff that is so brittle that another programmer can't maintain it. A web framework helps you both keep the linecount down, and keep your own code reasonably simple.
It is not a question of Javascript best practice, because that would be different for server-side JS such as Rhino or node.js.
Adapter pattern is not a common solution in this case. The only example I know to use this pattern is extjs. Javascript projects are usually too small and they aren't worth the effort you would make by creating such an abstraction layer.
The common solution for this problem is that you try to use multiple frameworks together for example with jquery.noConflict.
I've done this before, and can talk a bit about the experience of writing a library/toolkit wrapper.
The plan was to move from Prototype to some other library. Dojo was the first choice, but at the time I wasn't sure whether that's the library to move everything to (and by everything I mean ~5MB of Prototype-happy JS). So coming from a world of clean interfaces, I was set to write one around Prototype and Dojo; an awesome interface that would make switching out from dojo a breeze, if that was in fact necessary.
That was a mistake that cost a lot of time and effort for a few reasons. The first one is that although two libraries can provide the same functionality, (a) their API will almost always be different, and most importantly (b) the way you program with one library will be different.
To demonstrate, let's take something as common as adding a class-name:
// Prototype
$("target").addClassName('highlighted');
// Dojo
dojo.addClass("target", "highlighted");
// jQuery
$("target").addClass("highlighted");
// MooTools
$('target').set('class', 'highlighted');
Pretty straight-forward so far. Let's complicate it a bit:
// Prototype
Element.addClassName('target', 'highlighted selected');
// Dojo
dojo.addClass("target", ["highlighted", "selected"]);
// jQuery
$("target").addClass(function() {
return 'highlighted selected';
});
// MooTools
$("target").set({
"class": "highlighted selected"
});
Now after choosing an interface for your version of the addClass you have two options: (1) code to the lowest common denominator, or (2) implement all of the non-intersecting features of the libraries.
If you go with the 1st -- you'll loose the "personality" / best qualities of each of the library. If you go with #2 -- your addClass' code will be at 4 times larger than the ones provided by any of the libraries, since for example when Dojo is included, you'll have to write the code for the function as the first param (jQuery) and the Object as the first param (MooTools).
Therefore, although it is theoretically possible, it isn't practical, but is a very nice way to understand the intricacies of the libraries out there.
With the availability of JQuery, is there any need to learn direct DOM manipulation with Javascript in order to be a professional web developer/site builder/etc.?
This probably could be asked with Prototype, MooTools, etc. too, but I'm not familiar with them apart from their names.
Note: This question was rephrased so
my answer reflects the initial
question but I kept on adding.
Absolutely. Jquery IS Javascript and while it does abstract a lot of the cross-browser DOM discrepancies, one is still prone to the same exact parsing errors, scope misunderstandings, and so forth.
Using jQuery without knowing basic DOM knowledge or necessary Javascript knowledge is what I would consider dangerous, somewhat like giving a very powerful gun to a child who just may accidentally shoot himself in the foot without knowledge of how to use such a powerful tool the proper way.
A person that's taught straight with jQuery would have absolutely no idea how to debug issues if the error being thrown refers to anything in the DOM. For something as simple as comparing to see if an element is another element ( for things like current state ), they would try something maybe like:
if ( $('a.current') == $('a.current') ) { }
Which would return false since two unique jQuery objects are created. If they had known how to grab the reference to the DOM nodes they could have just done $('#el')[0] == $('#el')[0].
Anytime you use a jQuery plugin and run into some mysterious behaviour, without DOM knowledge you pretty much have to rely on someone else to help you out. Developers with DOM knowledge would be more able to debug and know the root of the problem, so you're only setting yourself up to lose more time scratching you head puzzled in jQuery land.
Furthermore, if one wishes to ever get to a high knowledge level and not just be an ordinary joe jQuery developer then he would greatly need a vast knowledge of the DOM discrepancies and Javascript in general otherwise you're limiting your skill level by a huge margin.
If you stick around Stackoverflow for awhile you'll see this in day to day questions, in which people who took the easy shortcut lack the basic JS/DOM knowledge necessary to solve their issues.
In some circumstances, you could conceivably not want the overhead of a DOM manipulation library.
E.g. for mobile development, mobile internet connections are still a bit slow at the moment, so you might want to save bandwidth by forsaking a library and going with native DOM code. (And possibly save a bit of execution time, as mobile devices are currently a bit slower at running JavaScript than desktop computers.)
But the devices, libraries and internet connections should all get faster as time goes on, so I reckon it’s unlikely you’ll do a lot of direct DOM scripting in mainstream day-to-day web development.
If you don't want to learn the underlying basics, sure it is :)
If you're not interested in how stuff works, sure it is....
If you want to cry for help each time you hit the limits of jQuery, sure it is!
If you want to depend on people here answering you simple questions, sure it is :D (reps for us...)
"The fool wonders the wise man asks."
In other words, know how the tools you use work, otherwise you'll end up with a horrible dependency.
You can use a library like jQuery with little knowledge of Javascript and almost no knowledge of the DOM, but that will only get you as far as the library lets you. You will only be able to do things that others have done before you.
Knowing how the underlying system works will also let you use the library more efficiently. Knowing what the library has to deal with lets you know why there is a big performance difference for certain ways of using the library, and why some things doesn't work at all.
There's a great many things that jQuery simplifies for you, but knowledge of the underlying JavaScript that jQuery calls can make things a little faster:
$('<div />').appendTo($('body'));
and
$(document.createElement('div')).appendTo($('body'));
are both equivalent, but the latter is a shade faster (albeit only in the order of milliseconds), since you're using JavaScript directly, rather than having jQuery calling document.createElement() on your behalf. Again, this is definitely a ridiculous micro-optimisation.
Other examples are working with Date, Math and string objects/functions. jQuery doesn't implement replacements for these (wisely so, since they're fairly easy to work with already).
We started a new project and realized that we needed a general purpose javascript library that contains a nice set of string functions, MD5, base64, allows extensions, etc. Also, copying and pasting functions from other libraries doesn't sound very attractive.
So, I guess the question is which javascript library contains the most general purpose functionality out there? or maybe there is a good collection of global functions out there we could use/extend. We know DOM manipulation is covered by many AJAX libraries including JQuery.
*Mind you, we could alternatively extend ExtJS, JQuery, etc. Is that what you guys are doing?
Google Closure Library
It contains (quoted from link):
a large set of reusable UI widgets and controls, and from lower-level utilities for DOM manipulation, server communication, animation, data structures, unit testing, rich-text editing, and more.
It also contains a nice set of string manipulating methods, in goog.string namespace.
Underscore
Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Prototype.js
Underscore is intended to go along with other library, like jQuery or prototype.
It's not extensible like jQuery or Google Closure, though.
*Mind you, we could alternatively extend ExtJS, JQuery, etc. Is that what you guys are doing?
Yes, I do and I think most are. A lot of what you describe as a "general purpose library" is covered by Frameworks like JQuery, Prototype or Moo. And short of clipping the webmaster's nails, there's a JQuery plugin for everything that's not already in the core.
Still, I'm interested to see whether any other "general purpose" libraries come up here. There are fields - like string manipulation, as stated in one of the comments to another answer, and advanced date operations - where none of these frameworks is the holy grail AFAIK.
I use the jQuery library and a bunch of plugins. jQuery's plugin directory contains a lot of useful tools. There's also jQuery UI, a set of interactive components and effects, which you can use if you don't want to use a more complex library like ExtJS.
Of course every project is different, and you will probably end up writing some helper functions on your own.
I realize that others are going to say the same, but jQuery truly amazes me every time I learn something new about it.
DOM, CSS, and event manipulation along with easy AJAX, extensibility, and the plethora of existing extensions make jQuery a wonderful tool for web development.
jQuery is incredibly useful for UI manipulation. However, being open source, it contains some less than optimal code. If you start running into performance issues, don't be afraid to delve into the source and see what's going on.
I have been using jQuery for some time now and that seems to handle most of the basic operations I need. It has a healthy library of plug-ins and you can always write your own. It is a very good lightweight js library and even if it doesn't do all that you need it to you it is a good starting point.