This past Friday I gave my first Google Tech Talk on Building a JavaScript Library. I was invited to speak by Jon Wiley and had a chance to speak with a bunch of people on the User Experience team at Google (and, of course, try the always-popular food).
Building a JavaScript Library [Video]
Building a JavaScript Library [Slides]
Based upon some of the questions that I got, it definitely seems like there’s a market for a jQuery presentation, at Google. Maybe I’ll be able to give another talk there someday – time will tell!
I’m glad that I’ve been able to start codifying my thoughts surrounding JavaScript Library design and implementation. We’ll have to see where it leads (if it does lead anywhere besides a presentation) – maybe it’ll end up in the form of a book or set of articles.
Please let me know if this talk interested you as I’m trying to gauge what interests other web developers – because all of this stuff fascinates me (JavaScript programming, open source projects, etc.).
Ryan (August 22, 2007 at 1:27 am)
Cool, this definitely interests me. I don’t think I’m going to create my own Javascript library anytime soon, but the more I learn, the better!
I think you should teach some Javascript classes, considering the incredible power you’ve put into jQuery with such a small amount of code. There’s a hell of a lot of bad Javascript out there, and I think it’s partly due to a misunderstanding of Javascript.
Alex Egg (August 22, 2007 at 2:09 am)
What is a “pre_commit hook in svn”?
John Resig (August 22, 2007 at 2:43 am)
@Ryan – Good idea, maybe I’ll arrange something.
@Alex – In Subversion (SVN) you can make it such that before a user commits changes to the repository that additional checks are done. For example, in jQuery we could make it such that it wouldn’t let you commit code that breaks the test suite. Unfortunately, even though Google Code has SVN support, it doesn’t have support for these hooks, which means that we lose out on this incredibly-handy functionality.
pd (August 22, 2007 at 6:24 am)
Why, so long after absorbing YouTube, does Google Video still absolutely suck?
Could you possibly provide this talk in bog standard XviD John? If there’s licensing reasons for why it’s buried in Google Video, I understand. Or indeed if it’s too much trouble to recode, fair enough.
AxsDeny (August 22, 2007 at 9:55 am)
Good talk. I enjoyed it.
John Resig (August 22, 2007 at 10:41 am)
@pd: Unfortunately, I think it is stuck on Google Video, for copyright reasons. Kind of a bummer. I’m not sure what platform you’re on, but if you’re on Windows or OSX you can try the Google Video Player. (But I somehow suspect that you’re on Linux, so I’m not sure.)
Peter Michaux (August 22, 2007 at 11:20 am)
Hi John, I only got though part of the video and then it crapped out, unfortunately. You were using the word “orthogonal” regarding APIs quite a bit and your use doesn’t line up with my definition of orthogonal at all. You seem to mean “parallel and complete” APIs. To me an orthogonal API is one where each action can only be performed one way. For example if I provide an API that has forward(), right() functions then I’ve made an orthogonal API. It isn’t complete because up() could be added. However if I add diagonal() the API is no longer orthogonal.
John Resig (August 22, 2007 at 11:25 am)
@Peter: “To me an orthogonal API is one where each action can only be performed one way.” That’s quite true, there were two points that I was making on that slide: First, that if you have a method that performs one action, you should have another that performs an equal and opposite action. Secondly, that there should be one equal way to perform an action against all objects (.add(), .remove(), .all are all the same on all the objects in FUEL).
I hope you’re able to watch the rest of the video, I’d love to hear your feedback (considering that you only made it to the fist content slide, heh).
Peter Michaux (August 22, 2007 at 5:20 pm)
John, if you are inviting feedback….
I think it was an excellent talk. I think any sane library developer would agree with just about everything you said.
It was good to hear the well reasoned criticism of the Prototype library. Many of the pages on the web that do criticize it are out of date. The dangers you list do to the practice of augmenting built-in prototypes shows they can’t fix the problems without stopping that practice.
The navigator.userAgent issue was really the only area where I disagree with you. I believe it is the same kind of fundamental disagreement between the folks that augment verses those that won’t augment. I doubt I’ll make an argument against navigator.userAgent as well as you argued against augmenting but to me they have the equally intense odors.
A script that uses navigator.userAgent will almost surely require maintenance with future browser releases. This is something we want to avoid. I want to avoid it at almost all costs. Code built on feature detection is far less likely to require maintenance.
Your primary example that navigator.userAgent is unavoidable when determining rendering capabilities. Here are some examples…
I don’t know of a check for opacity functionality other than an element that says “click me” with an translucent overlay where users in browser just wouldn’t see the message and wouldn’t know to click. Because of this detection problem, I just never build anything that will be broken in browsers where opacity doesn’t work. It turns out this isn’t very limiting. The good news is that checking rendering capabilities isn’t usually as difficult as checking opacity.
Take position:fixed, for example. Unless I’ve missed something, you can’t check for a browser feature’s existence to know if this will work. But you can place a test element on the page with position:fixed and calculate it’s rendered position. If it is where you expect a position:fixed element to appear then you know the browser has this capability. If we just checked navigator.userAgent for /MSIE/ then when IE7 was released those users wouldn’t see the better UI that uses position:fixed until we adjust our sniff.
Another rendering example is borders on <input type=”text”> borders. In Safari, text input borders are not shown. Suppose we were going to depend on that for error indicators. In Safari we would need to take some other action to indicate the error like adding a background colour. To test for border rendering support we try adding a border to an element and it’s offsetHeight will increase when borders are supported. If we just check navigator.userAgent for /Safari/ then when, say, Safari does start to support input borders but not background colours then we will have no error indicator shown and our UI is broken.
So for the rendering issues you are worried about often the “try it” approach is the only way to see if the feature is supported. In fact, this “try it” approach is better than just seeing if a feature exists. Just because a feature exists, it doesn’t mean it works. Only trying it will test that it really works. You could do this with every feature you use but this is overkill if a problem has never been noticed with a particular feature in a particular browser. In your talk you mention this “try it” approach for testing getComputedStyle with colour in Safari. I think you can leverage this technique more than you may think and avoid navigator.userAgent in many more places.
In places where you just can’t find any possible way to feature detect by feature presence or actually trying the feature, navigator.userAgent still isn’t necessary. You can use multiple object inference. If a browser has ActiveXObject and no XHMLHttpRequest and has document.all and doesn’t support position:fixed (through a test) and has conditional compilation that works for IE6 and 10 more things, then you can be pretty sure it is IE6. The need for this would sort of test would be extremely rare but would be more robust then checking the navigator.userAgent to see if it claims to be IE 6. If I needed a test like this I would simply say the UI design is not suited to today’s web reality and let’s come up with something different.
If low maintenance is important at all, it is better to imagine navigator.userAgent doesn’t exist. If it didn’t exist could you still solve the problem of building web pages?
You stated a library with an API that doesn’t work on all browsers should not be released as a library. I believe the same with navigator.userAgent and that it has no place in a library.
Like I said at the top, I think it was an excellent talk.
Dan Evans (August 23, 2007 at 12:18 am)
I enjoyed the talk very much. Thank you for presenting it. When you were listing how the variety of us jQuery users approach the language I began thinking about how I approach it. I actually don’t have a formal Computer Science background as I switch my focus in school. I think that I come at jQuery (and programming in general) from a mathematics perspective. To me writing a function is like writing a proof. In fact, recently I was amused to write a function that took an argument as a real number, x, and in one line of arithmetic returned an f(x) for a parabola that I was using to create an easing effect. That’s in some code that I want to turn into a plugin for jQuery too.
Just wanted to give my input on all the different types who are drawn to jQuery.
Oh, and as for a benevolent dictator, sometimes I just imagine that the j in jQuery stands for john. :)
John Resig (August 24, 2007 at 11:38 am)
@Peter: I’m working on a blog post response to your excellent comments. Thanks for taking the time to write them up. I feel like I didn’t frame my proposition very well in the presentation, so I would like to do so better (since recommending the user of userAgent is rather blasphemous).
@Dan: I’m glad you’re enjoying it – I’m glad that it’s able to bring in everyone on the technical spectrum.
Brian Slesinsky (August 25, 2007 at 7:55 pm)
I haven’t done much JavaScript yet, but maybe the disagreement on userAgent comes from the difference in perspective between writing an application and writing a library. A webapp developer mostly worries about browser compatibility, but coexistence with libraries is less of a concern because you choose the libraries you want to use and disregard the rest. A popular library runs in a much wider range of environments and has much greater compatibility hassles.
Maybe the biggest lesson is that you need to set different standards according to the environment you’re working in.
Kip Lawrence (August 25, 2007 at 10:20 pm)
I would love to watch this video. Is it still working? I’ve tried for a couple of days and haven’t been able to see or download the video.
Matjaž (August 26, 2007 at 6:24 am)
Very nice presentation John, sadly you ran out of time for the last (also interesting) slides.
I have a question regarding error messages on slide 22 – “Perform type checking”.
You said error messages should be moved to debugging extension.
How do you then trigger this error ? with some internal method “error()” which is empty by default and extension overrides it ?
Can you please provide some examples ?
In the next slide, what did you mean with “ignore the templation to try{}catch(e){}” ?
Not to use exceptions ?
Thank you for your answers !
Diego F. Goberna (August 27, 2007 at 8:01 pm)
Greetings John,
I’ve just watched your presentation 5 minutes ago, I’ve enjoyed all of it a lot as much as knowing the face and the voice of the creator of my beloved jQuery, I’ve been using it since April and haven’t stop yet.
Thank you, take care!
PD: how about always-popular google’s food? :D
$(“#me”).hide(‘slow’);
sirdarckcat (September 5, 2007 at 1:01 am)
Hi
Well, your talk is the first “Google tech talk” that I see from begining to end, it was quite interesting, the only thing that “sHocked” me was your recomendation of the avoidance of try&catch.. any way, if that’s for allowing the user to “debug” the error, you can always do this..
setTimeout(function(){/*code here*/},0);
so the error get’s reported to the debugger, and the library (jQuery) is able to continue without any errors, that can destroy everything (I mean, everything), because the users of the class (like me) are not going to be the only ones to see the error, actual users of the application that uses jQuery are going to be affected as well.
Any way, congrats again for the awezome talk, and I’m looking forward to test FUEL & javascript2.0 & firefox 3 :P
Burcu (September 6, 2007 at 7:17 pm)
Very incredible presentation.
The model and your advices has inspired me a lot although I’m not about to write a JS library. While watching the video I felt the same Peter did about the “orthogonal API” but John’s comment cleared that up.
I’m really curious about firefox 3 and FUEL.
Lindsey Simon (September 14, 2007 at 11:59 am)
Heya John, just wanted to say thanks again for coming to Google and giving the presentation. It was well presented, thoughtful, and a great brain-dump of the things you’ve assimilated via jQuery etc. The web developer community is lucky to have such an ambassador.
Liqbpyig (October 13, 2007 at 1:37 am)
charity in job uk flute magic review calling canada card in machine show trade vending allure day spa drilling natural gas well center chevrolet youngstown western coral snake dragonlance generation second cat cat himalayan kitties kitty persian 20 greatest hit monkees