8

I am creating a MVC 3 application (although just as applicable to other technologies e.g. ASP.NET Forms) and was just wondering if it is feasible (performance wise) to serve images from code rather than using the direct virtual path (like usual).

The idea is that I improve the common method of serving files to:

  1. Apply security checks
  2. Standardised method of serving files based on route values
  3. Returning modified images (if requested) e.g. different dimentions (ok this would only be used sparingly so don't relate this to the performance question above).
  4. Perform business logic before allowing access to the resource

I know HOW to do it but I don't know IF I should do it.

  1. What are the performance issues (if any)
  2. Does something weird happen e.g. images only load sequentially (maybe that's how HTML does it currently i am not sure - exposing my ignorance here).
  3. Anything else you can think of.

Hope this all makes sense!

Thanks, Dan.

UPDATE

OK - lets get specific:

What are the performance implications for using this type of method for serving all images in MVC 3 using a memory stream? Note: the image url would be GenericFetchImage/image1 (and just for simplicity - all my images are jpegs).

public FileStreamResult GenericFetchImage(string RouteValueRefToImage)
{
    // Create a new memory stream object
    MemoryStream ms = new MemoryStream();

    // Go get image from file location
    ms = GetImageAndPutIntoMemoryStream(RouteValueRefToImage);

    // return the output as a file
    return new FileStreamResult(ms, "image/jpeg");
 }

I know that this method works, because I am using it to dynamically generate an image based on a session value for a captcha image. It's pretty neat - but I would like to use this method for all image retrieval.

I guess I am wondering in the above example if this is ok to do or whether it requires more processing to perform and if so, how much? For example, if the number of visitors were to multiply by 1000 for example, would the server be then processingly burdened in the delivery of images..

THANKS!

Dan B
  • 936
  • 2
  • 13
  • 26
  • Performance and "if something weird happens" both entirely depend on how you're building your application... it's pretty subjective. – womp Apr 07 '11 at 22:56
  • Performance depends entirely on your method of delivery. How do you intend to deliver the image to the client. – Biff MaGriff Apr 07 '11 at 22:59
  • Hi Bill and womp - I have updated my question with an example. Performance implications are on my mind. – Dan B Apr 08 '11 at 17:09
  • IIS streams data directly from the file to the client, and therefore uses little RAM even for many connections. If you buffer every file into memory every time, you will run out of RAM very quickly. (Dial-up clients may take minutes to download a small file, think abou tit).. – Lilith River Oct 15 '11 at 22:18
  • Yeah - that's what I am worried about the most. Can you offer an alternative solution maybe a hybrid approach? – Dan B Oct 17 '11 at 10:25
  • @Computer Linguist Dial up connections and minutes to download an image? What century are you living in? – Levitikon Jul 26 '12 at 12:59
  • 1
    @Levitikon A Mobile one. Replace 'Dial-up' with 'EDGE' or 'AT&T 3G'. Long-lasting requests are not an abnormality here, and you need to face the reality of it. You can't pretend only one request is handled at a time. – Lilith River Jul 26 '12 at 16:14
  • @Levitikon It's worth noting that there are many parts of the world where connection speeds are BELOW 56k dial up speeds even on home connections - travelling in Africa (even richer parts of South Africa) was illuminating in this respect. Even if you are only targeting Western users, there are plenty of areas where only GPRS or Edge connections are available for mobile users. – pwdst Jul 10 '13 at 15:42

1 Answers1

8

A similar question was asked before (Can an ASP.Net MVC controller return an Image?) and it appears that the performance implications are very small to serving images out of actions vs directly. As the accepted answer noted, the difference appears to be on the order of a millisecond (in that test case, about 13%). You could re-run the test locally and see what the difference is on your hardware.

The best answer to your question of if you should be using it is from this answer to (another) similar question (emphasis mine):

DO worry about the following: you will need to re-implement a caching strategy on the server, since IIS manages that for static files requested directly. You will also need to make sure you manage your client-side caching with the correct headers included in the response. Ultimately, just ask yourself if re-inventing a method of serving static files from a server is something that serves your application's needs.

To address the specific cases you provided with the question:

  1. Apply security checks

    You can already do this using the IIS 7 integrated pipeline. Relevant bit from documentation:

    Allowing services provided by both native and managed modules to apply to all requests, regardless of handler. For example, managed Forms Authentication can be used for all content, including ASP pages, CGIs, and static files.

  2. Standardised method of serving files based on route values

    If I'm reading the documentation correctly you can insert a module early enough in the pipeline to re-write incoming URLs to point directly to static resources and let IIS handle the request from there. (For the sake of completeness there also this related question regarding mapping routes to mages: How do I route images using ASP.Net MVC routing?)

    Empowering ASP.NET components to provide functionality that was previously unavailable to them due to their placement in the server pipeline. For example, a managed module providing request rewriting functionality can rewrite the request prior to any server processing, including authentication.

    There are also some pretty powerful URL rewrite features that come with IIS more or less out of the box.

  3. Returning modified images (if requested) e.g. different dimentions (ok this would only be used sparingly so don't relate this to the performance question above).

    It looks like a module that does this is already available for IIS. Not sure if that would fall under serving images from code or not though, I guess it might.

  4. Perform business logic before allowing access to the resource

    If you're performing business logic to generate said resources (like a chart) or as you mentioned a captcha image then yeah, you basically have no choice but to do it this way.

Community
  • 1
  • 1
Roman
  • 19,581
  • 6
  • 68
  • 84
  • I have updated my post with a specific example. Like I said it's not the how i am struggling with, it's the IF I am questionning. I don't want to bring my server down just serving images. :) But excellent response. – Dan B Apr 08 '11 at 17:08
  • @Dan B: So I think my answer addresses this but if not I can try to reword it a bit. The very first link basically points to the same question of "Is there a speed difference" and I believe the accepted answer shows that there is but it's small, around 1ms. The other part of the IF is that you can accomplish most of it using IIS which may be more flexible (since changing rules won't require code changes and an app redeply) and it may feel more natural to more people (principle of least surprise). Does that help or not o much? – Roman Apr 08 '11 at 17:21
  • The module you mention above is not free. I have moved away from URL rewriting (since routing is so good). The links you sent were fantasitc. But neither mention the speed of FileStreamResult which is the one stated in my updated question. I will mark as answer in a few days should no one else have a contribution. Thanks for your feedback! – Dan B Apr 08 '11 at 21:13
  • @Dan B: Thanks for the feedback, I rewrote parts of my answer to hopefully better answer your question. Yes, the module I linked to isn't free, but it may be cheaper than your time to develop similar functionality (at least to your employer). I would also go with the "can another tool already accomplish this as well or better" approach. If the answer is yes I would lean towards using the tool rather than rolling your own. That way you get to benefit from any performance improvements in the tool down the line. – Roman Apr 09 '11 at 04:07