Thursday, July 11, 2013

Live Blog: Web Performance SF Meetup: Enough w/ The JavaScript Already!

Ahhh, the sweet feeling of freedom. Today is my first day back at work (in person) in three weeks, and to celebrate, I'm going to a meet up tonight in Los Altos. Hey, you celebrate your way, I'll celebrate mine :).

Seriously, though, I'm excited about tonight's topic, and specifically from a testing perspective.

NOte: this entry is shifting into "Live Blog" mode now. That means please feel free to refresh if you want to get updates of what's going on. If you see "End of Session", you'll know I'm done ;).

San Francisco & Silicon Valley Web performance Group
Enough With The JavaScript Already! w/ Nicholas Zakas (@slicknet)

Web applications have reached the point now that, unless you have a are bones or super simple static site, it is very likely that you are probably working on a site or service that has a copious amount of JavaScript driving the experience.

Nicholas started out the session with a parable of Dark Chocolate Almonds. Almonds have protein, and Dark Chocolate is much healthier than Milk Chocolate, so almonds + Dark Chocolate == Awesome. With this idea, he put a bunch in a bowl on his coffee table. Over time, he grazed on all of the dark chocolate covered almonds, and ended up with a stomachache from eating tot much. He likens this story to the fact that JavaScript can be good, but too much of a good thing can be very uncomfortable.

Nicholas highlighted the experience of JavaScript about 9 years ago, and how badly JavaScript sucked back then. Then, around 2005, something interesting came into play... AJAX came on the scene. Hmmm, JavaScript became somewhat cool, because it made AJAX happen. 2006 brought jQuery. Now, people who were not necessarily programmers could start making JavaScript than previously. From there, in 2007 Atwood's Law was declared... "any application that can be written in JavaScript, means it ultimately will be written in JavaScript. Now JavaScript is all over the place, and performance is taking a hit because sites are often a victim of JavaScript's success.

Overblown JavaScript

Think of the Web App being a multi level system where each area has well defined responsibilities. On the server, render HTML, calculate dependencies, redirects, etc. HTML gives structure, CSS gives form and style, and JavaScript should be the area to take care of the "others" that aren't handled in the other main areas. Over time, many of these functions have moved from their traditional sphere, and up into the JavaScript space.  GZip also tends to hide the real size of the JavaScript being used. We think only of the payload, not of the footprint once the code is decompressed. In short... to borrow the DOS XX meme, I don't always use JavaScript, but when I do, I use it for everything!"

JavaScript can do everything now... but really, is that a good thing? Think of Facebook and how it typically loads, and how often you see an empty white screen. If JavaScript is disabled, some sites will not render at all! Twitter also did a lot of client side rendering, and ultimately they pulled away from that, so that rendering has been moved back to the server, resulting in page load times of 20% of what they were previously.

Large sites have made the decision to move their rendering back to their servers, and it not only has increased performance, but it's also given better SEO and indexing to the sites as well. Progressive enhancement made sense once upon a time, and more and more people are coming back to that same idea.

Unused JavaScript

How much of the JavaScript that is loaded into your web app actually gets used. JavaScript gets loaded in four places:

In Head
Before Body
After Page Load
On Demand

Depending on how the app is used, we can make better choices about when to load which JavaScript. Analytics can help determine tendencies. Tendencies can tell you a lot about what libraries really matter, and which ones get the biggest workout. Those vital elements should be in the head (generally speaking). Critical stuff, but not to much stuff. If there is JavaScript that needs to be used fairly quickly, but not immediately, then we can put the JavaScript before the closing body tag.  How about stuff that is run after a page load (expanding summaries, accordion controls, secondary search, etc.)? they may not be needed immediately on page load, but pretty soon thereafter. the last option is based on user interaction (clicking the "read more" link, etc.)

What's the point with all this? By learning what the customers most frequently do, you can determine when JavaScript should or should not be loaded. Why load a button for view if the chance of clicking or using that button is rare or even negligible. the idea is "load what you need when you need it, and no sooner."

JavaScript Libraries

jQuery 1 is about 90K unzipped. jQuery2 is roughly the same, YUI, and Dojo are similarly sized. Loading the libraries takes upa a lot of space. There are economies of scale that can be leveraged, but over time, the library code that is used vs what's actually loaded becomes a very large delta. Over time, the Library grows. Component code that is performant and responsive, but expensive to develop, drops when the options are encapsulated in a library. The danger is that the Library coe, over time, become more prevalent, and loads up and takes up memory when most of the code will never be used. Think of tabs. What do you spend every time you load and navigate a site with dynamic tabs? The answer is "quite a lot, if left to its own devices", specifically 120K for each page. Just to have the tabs present. Think there might be room for improvement? If Nicholas is to be believed (and I do), then the library dependency can be reduced by up to 95%. How can we do that?

Store UI state on the DOM. make it part of the Object Model. Add some javascript where needed, preferably sparing, so that it calls just what is needed. Heck, to make it faster, and more responsive, think bout where you may just need some quick and raw HTML. By being more sparing in the amount of JavaScript that is loaded, and focusing on the areas where the loads are actually needed and when/where.

The Big Question

How much value am I getting for the number of bytes loaded. High value and low bytes, good. High value and high bytes, may be good, but verify. High bytes but low value. Definitely not the right way to go. Think about how the app is used, and pay close attention to when and how users actually interact with the site. Leverage your most critical areas and your most bang for the buck in the right places... and don't treat JavaScript like dark chocolate covered almonds. they're good, but too many will give you a belly ache :).


Q&A

Servers are good at cobbling together pages. Let the server do it. Let the server do redirection. Don't have the browser do that when you can avoid it. Browser interactions are sweet and juicy, but they re also very slow by comparison.

Create script nodes for the areas where you really need to call up special actions. look to make them happen when key events trigger them. Don't just load everything by default (again, analytics can tell you a lot :) ).

As always, there are tradeoffs to the choices we make. Recalculating things on the page are pricey, and if you need to do a lot of that, then having the JavaScript loaded completely and early may be worth it.

Impressions:

My developer colleague was a little surprised when I told him I was coming tonight. He thought it might prove to be a bit of a dry topic for a software tester, but "au contraire", I found this talk very valuable. I found the 4 modes concept to be very interesting, and something I will consider as I review the applications I test. what's more, it gives me some ideas to see what I actually interact with and what I don't. It might be interesting to see how an app that has been profiled to my actual usage patterns would perform compared to an app that just loads everything on loading a page. One thing's for sure, JavaScript is going to be increasing, not decreasing as sites and apps try to do everything for everyone and do so prettier and more efficiently (efficient for the coder, not necessarily for the end user or operations). Now, I have some ideas to suggest rather than just say "aww, this site is slow". Instead, I can start asking "How can I make thee more efficient, JavaScript? Let us count the ways!"

End of Session.

No comments: