Tuesday, February 26, 2013

Partial page load issue with ASP.NET MVC and head.js

I've been working with a small team over the past year or so on a large-scale web application built in ASP.NET MVC 3. We're using some of the best new client-side technologies with it as well - jQuery, Bootstrap and head.js to name a few. Overall, the project has gone very smoothly, with only a few minor hiccups or delays.

Well, except for one lingering issue.

We began experiencing intermittent partial page loads almost as soon as the first draft of the UI was released to our testing servers. The following behaviors were exhibited:

  • This issue could happen on any page in the application when it loaded.
  • 65-70% of the time a page would load correctly.
  • Pressing F5 (refresh) would reload the page and always fixed the issue.
  • Generally, either part of the main menu bar wouldn't load, or our datagrid wouldn't load. Both controls could have a problem on a given page if you reloaded it multiple times.

Perplexing and frustrating to say the least. First, we thought it was a problem with the tiny VMs we had in our testing environment. Then we guessed it might be a packet delivery issue with the VPN tunnel between the testing network and the office network. Then we supposed maybe our self-hosted CDN wasn't set up correctly, and switched to using Amazon S3 (which we were planning on doing anyway).

Each of these theories (and others) were tested and debunked. No love. There's no way it could be in our code, right??

What ended up working for us was moving our "core" libraries outside of head.js and using their "execute in-order" method for the rest of our libraries. Our _Layout.cshtml page looks like this:

<!doctype html>
<html lang="en">
<head>

(... stylesheets and other head content ...)

<script type="text/javascript" src="http://cdn.company.com/JS/head.min.js" />
<script type="text/javascript" src="http://cdn.company.com/JS/jquery-1.7.1.min.js" />
<script type="text/javascript" src="http://cdn.company.com/JS/jquery-ui-1.8.18.min.js" />
<script type="text/javascript" src="http://cdn.company.com/JS/modernizr-2.5.3.min.js" />
<script type="text/javascript" src="http://cdn.company.com/JS/bootstrap-2.1.0.min.js" />
<script type="text/javascript" src="http://cdn.company.com/JS/flexigrid.pack.js" />

<script type="text/javascript">
    head.js(
        "http://cdn.company.com/JS/jquery.validate.min.js",
        "http://cdn.company.com/JS/another.script.js",
        (... other javascript files ...),
    );
</script>

(... other code / markup ...)

</html>

We implemented this change about a week ago, and have yet to experience the issue once since then. Couple of additional notes / comments to share about the change:

  • This seems to work because generally all of the other javascript files you'll want to load probably depend on one or more of these "core" files to work properly. Letting head.js handle this becomes even more delicate when you consider the fact that ASP.NET is trying to load multiple Partial Views per page, many of which contain controls that need the "core" in place to be built properly. Any interruption of loading a "core" file before a control needs it may break part of the page.
  • While the head.js usage documentation lists what we have here as a correct way of using the library, this is not how their demo is built ('View Source' to check it out).
  • The most similar issue we could find was here on the head.js GitHub project site. This is where we got the idea to try an alternate implementation.
  • Since the purpose of head.js is to improve page load times, you may be wondering if this change hurt our delivery speed. Unfortunately, because pages weren't reliably loading for a number of months, it was hard to measure where we were at before the change, so I'm unable to determine a speed difference.

I decided to document this because we weren't able to find any instances online of someone else having the problem; hoping this post will save a few other teams some time and headaches.

Monday, February 4, 2013

How Would Don Draper Hack?

A few weeks ago, a link was posted on Signal vs. Noise to the following article - "10 Tips on Writing from David Ogilvy". As expected, the "original Mad Man" had some really good tips on writing. What I wasn't expecting was how applicable his advice was to writing good code.

I propose my interpretation (in red) of what the memo might have looked like if he was running a software company today:

People who think well, write well. Woolly minded people write woolly memos functions, woolly letters classes and woolly speeches applications. Good writing is not a natural gift. You have to learn to write well. Here are 10 hints:

  1. Read the Roman-Raphaelson book on writing Code Complete. Read it three times.
  2. Write code the way you talk. Naturally.
  3. Use short words variables, short sentences functions and short paragraphs classes.
  4. Never use jargon words like "reconceptualize", "demassification", "attitudinally", "judgmentally" in output to clients. They are hallmarks of a pretentious ass.
  5. Never write more than two pages on any subject class.
  6. Check your quotations references and open source credits.
  7. Never deploy a change send a letter or a memo on the day you write it. Read it aloud the next morning — and then edit it.
  8. If it is something important, get a colleague to improve it.
  9. Before you send your letter or your memo check in your code, make sure it is crystal clear what you want the recipient next developer to do understand.
  10. If you want ACTION, don’t write standards or documentation. Go and tell the guy person what you want.

Pretty interesting how close it is to the original, but maybe not all that surprising. After all, writing code is the act of explaining to another human, in the simplest way possible, what you are expecting a computer to do. It is the story of your application (for the human), as well as the instructions (for the computer).

Maybe the next time you sit down in front of your favorite editor with a caffeinated drink, you should start by asking yourself: HWDDH (How Would Don Draper Hack)?