How To Serve An Image From An Action And Otherwise Be An MVC Swashbuckler

There comes a time in every pasty young developer’s life when they realize that they must build an application that stores images in a database, and then serves them up via an ASP.NET MVC Action.

Soon after this realization, they have another realization that, unlike with many other shortcuts to brilliance that MVC readily provides, the purveyors of the Web Stack of Love did not serve this one up on a silver platter carried by a pirate riding a unicorn. What they did do (which is twice as pirate, upon reflection) is make their little framework as extensible as the sea is salty. So basically, unless your liver is gilded with lilies, you can sail forth and build your own ruddy ImageResult.

I have one here.

public class ImageResult : ActionResult 
{         
    public Stream ImageStream { get; private set; }         
    public string Extension { get; private set; }         

    public ImageResult(Stream imageStream, string extension)         
    {         
        this.ImageStream = imageStream;         
        this.Extension = extension;         
    }         
        
    public override void ExecuteResult(ControllerContext context)         
    {         
        var response = context.HttpContext.Response;         

        // set the content type based on the extension 
        response.ContentType = string.Format("image/{0}", this.Extension);         

        // copy the image stream to the response output stream 
        this.ImageStream.CopyTo(response.OutputStream);         

        response.End();         
    }         
}

Here’s the consuming code that shows the ImageResult in action:

public ActionResult UserImage(int id)
{
    using (var db = new ApplicationEntities())
    {
        var user = db.Users.Single(p => p.ID == id);
        // read bytes from database into a stream
        var imageStream = new MemoryStream(user.Image);

        // create an image result using the stream
        return new ImageResult(imageStream, "jpeg");
    }
}

See what I did there? In action.

Moving On.

The quick-of-brain among our readership will extrapolate from this that any type of binary file can be served from an Action in this way, with only minor modification to our custom type.

The not-quite-as-quick-of-brain will then reason that this is wicked awesome and that every file should be served this way. To them I will say two things: No, and really this approach should only be used if you need to obtain or manipulate the file in code before serving it. For example, if you need to resize the image, or if access to it is secured in a programmatic way.

So, you know.

Hoist the colors, me hearties.

Advertisements

Slow jQuery And The Thing About Duct Tape

So, here’s the thing about duct tape.

 

Ducttape_thumb

It is super useful. But if you’re working quickly, and with enough of it, your grip will inevitably fail and you’ll be left helpless except to watch as its sticky side makes irrevocable contact with itself. And if your forearm hair was involved in the exchange, well. There goes your will to carry on.

What I mean to get at with all the jabber about our ubiquitous silvery adhesive friend is this: jQuery is arguably the duct tape of WebForms development, and its quick-fix powers over rendered markup are seemingly without limit. Use enough of it at once, though, and it will find ways of getting stuck to itself, or indeed to the hirsute wrist of your DOM. As your page’s once-blinding responsiveness disappears over the usability horizon, you shed a single caffeinated tear, and it dawns on you that getting this untangled could be a slow and painful affair. Perhaps involving plenty of unintentional hair loss.

Now, let me brush away that tear—in a totally non-creepy, platonic sort of way—as I submit for you today some tricks to get your jQuery just about as unstuck and performant as an abstraction over an interpreted language could ever hope to be.

Step Zero

In any performance tuning venture, step zero is to measure the problem. This kills two sluggish birds with one stone. First, it calls your attention to the sucking chest wound in your code, so that you don’t waste time kissing the boo-boo on its wittle finger. Second, it gives you a baseline to compare against your theoretically optimized code later.

Internet Explorer 9 comes standard with a perfectly decent performance profiler, so I’ll be rocking that for our purposes here. If, however, you scribble your hopes and dreams in a Field Notes and you’re allergic to IE, feel free to follow along using similar tooling for Chrome, Lynx, or whatever you prefer to check your mess in.

Setting the user-agent zealot-bait aside, let’s browse to the page in question. Then press F12 to open the Developer Tools window, and switch to the Profiler tab. Click the Start Profiling button, and reload the page.

start-profiling

At this point, if it’s only page load time you are concerned with, click Stop Profiling. Otherwise, do the thing on the page that seems to be angering the JavaScript gods, then click Stop Profiling. In a few seconds, a report will be generated showing which functions have flitted in and out of existence, and which ones should maybe think about taking the stairs every once in while.

A closer inspection of the Current View dropdown reveals that we get two ways to see this information: as a straight list of functions, or those same functions arranged on a call tree. Since what we seek is the path of greatest sadness through our code, we’ll select the Call Tree option, and then sort the Inclusive Time column, descending.

Once our perf data is presented this way, we simply start at the top, popping open functions on the tree. When we find a node corresponding to code over which we have any control (as opposed to jQuery itself, a 3rd-party plugin, or other framework code), we can finally let the healing begin.

call-tree

Get Better Selectors

After identifying our less-than-spritely blocks of code, the first thing we should examine is how its selectors are sculpted. If a selector is defined too broadly, without scope, it can bring your page to a grinding halt as the entire document (or way too much of it) is scanned for matches. For instance, a selector comprised of a single class:

// boo 
$(".row-status").removeClass("error");

To remedy this, narrow the breadth of the query using the id or (better yet) the path of ids that zeroes in on the relevant part of the page:

// yay
$("#content #grid .row-status").removeClass("error");

Alternatively, you could use the jQuery function’s second parameter to specify a context object:

// yay for me too
$(".row-status", $("#content #grid")).removeClass("error");

Remember to measure again after this tweak (and any of the others below) to track your progress. When code changes and functionality doesn’t, people on the team who are not you may get twitchy if you don’t have numbers ready to back it up.

More twitchy than usual, I mean.

j-Jà Vu

Another common selector faux pas to scan for is a situation where you are defining a selector inside of a loop, or the same selector is created multiple times. This leads to more cycles wasted on scanning the DOM for elements that were already reaped in a previous iteration.

// copy the important info to the parents of a lot of things

$('.a-lot-of-things').each(function () {

  $(this).parent().val( $('input.important-info').val() );

});

The fix for this is to consolidate—in the case of the loop, define the selector before the loop begins, so its work is done only once. For merely redundant selectors, stash the resulting object in a variable and use it inside the loop.

// copy the important info to the parents of a lot of things
// faster, more intense
var $info = $('input.important-info');
$('.a-lot-of-things').each(function () {
    $(this).parent().val( $info.val() );
});

Look For Each Each And Forgo It For A For

Another perf gain opportunity is any usage of jQuery’s each function. Sure, it’s an elegant alternative to a for loop, but depending on its contents, it may cost you. I have seen on the order of ten-fold speed gains just from converting each loops back to slightly less fancy for blocks:

// each
$('.a-lot-of-things').each(function (e) {
    $(this).val( $info.val() );
});
  
// for
var $things = $('.a-lot-of-things');
for(var i = 0; i < $things.length; i++)
{
  $($things[i]).val( $info.val() );
}

This one is a fine example of the tradeoff we sometimes find between beautiful and fast code. While the previous two fixes are merely implementing jQuery selector best practices, this one should only be implemented on an as-needed basis. A for loop is less readable and has more moving parts than an each call, making it harder to maintain.

Less delicately? I might as well beat my app with an ugly stick if I’m going to prematurely optimize my code.

With Great Abstraction Comes Great Responsibility

We’ve measured the damage, made our selectors more selective, stopped repeating ourselves, and applied precision hideousness to take the slack out of our ponderous page renders.

With frameworks like jQuery doing much of the heavy lifting for us, it sure is a snap to write client-side code quickly these days. But too often, when we write code fast, we don’t write fast code. Rapid development with jQuery is super useful—if you make the time to unstick what becomes stuck before you call it done.