最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to speed up image loads from AngularMvc.net - Stack Overflow

programmeradmin2浏览0评论

I have an MVC website which serves images based on this old article:

.aspx

My c# controller code looks like this:

public ActionResult GetThumbnail(string code)
{
    byte[] image = _dataProvider.GetThumbnailImage(code);
    return this.Image(image, "image/jpeg");
}

On the client side I have an AngularJS controller which loads up a search result set from the server. The result set includes a number of image URLs like this:

    <tr ng-repeat="item in data.items | filter:filter" class="fixed-height-80">
        <td>
            <a href="{{ item.viewDetailUrl }}"><img ng-src="{{item.thumbnailUrl}}"/></a>
        </td>
    </tr>

The thumbnailUrl points to the GetThumbnail action on my MVC controller and is constructed server side in a model factory and returned to the Angular ready for use.

The problem is that the images load very slowly even thought they are only about 3kb per image. After the async search return is pleted in the javascript the images appear one at a time, about one per second, until they are all loaded.

I put a Stopwatch in the C# on the controller and the loading of the image data from the dataProvider on the server side takes about 0.9ms But even with just ten images to serve it takes about six seconds before all the images are loaded in the page. The JS renders the links almost immedialtly, it's just the images that are slow.

How can I speed up image loading in this context?

Update

If I move the images into ~/images/image.jpg and route the url to point directly at the folder using Url.Content it doesn't seem to have the same issue. therefore the problem seems to be with the way the controller is serving the images - sometimes if can take < 10ms and other times over 2000ms for the same image, but it's unclear why.

I have an MVC website which serves images based on this old article:

http://blogs.msdn./b/miah/archive/2008/11/13/extending-mvc-returning-an-image-from-a-controller-action.aspx

My c# controller code looks like this:

public ActionResult GetThumbnail(string code)
{
    byte[] image = _dataProvider.GetThumbnailImage(code);
    return this.Image(image, "image/jpeg");
}

On the client side I have an AngularJS controller which loads up a search result set from the server. The result set includes a number of image URLs like this:

    <tr ng-repeat="item in data.items | filter:filter" class="fixed-height-80">
        <td>
            <a href="{{ item.viewDetailUrl }}"><img ng-src="{{item.thumbnailUrl}}"/></a>
        </td>
    </tr>

The thumbnailUrl points to the GetThumbnail action on my MVC controller and is constructed server side in a model factory and returned to the Angular ready for use.

The problem is that the images load very slowly even thought they are only about 3kb per image. After the async search return is pleted in the javascript the images appear one at a time, about one per second, until they are all loaded.

I put a Stopwatch in the C# on the controller and the loading of the image data from the dataProvider on the server side takes about 0.9ms But even with just ten images to serve it takes about six seconds before all the images are loaded in the page. The JS renders the links almost immedialtly, it's just the images that are slow.

How can I speed up image loading in this context?

Update

If I move the images into ~/images/image.jpg and route the url to point directly at the folder using Url.Content it doesn't seem to have the same issue. therefore the problem seems to be with the way the controller is serving the images - sometimes if can take < 10ms and other times over 2000ms for the same image, but it's unclear why.

Share Improve this question edited Nov 24, 2014 at 14:37 Kaine asked Nov 24, 2014 at 9:45 KaineKaine 1,2872 gold badges16 silver badges30 bronze badges 7
  • How large are the image files? – DGibbs Commented Nov 24, 2014 at 9:48
  • Are the images generated, altered or just fetched? In the last scenario, the whole thing can possibly be split into using backend code for getting file names, and browser loading images from a static directory. – Gerino Commented Nov 24, 2014 at 9:52
  • The images files are approx 3kb and if loaded direct on the page they load almost at once. – Kaine Commented Nov 24, 2014 at 10:06
  • 1 Can you use Profiler, like Miniprofiler to check where's the bottleneck? – Max Brodin Commented Nov 24, 2014 at 11:20
  • @MaxBrodin - interesting results - there are multiple calls to /GetThumbnail (one for each image as you'd expect) - about half are processing in ~10ms (6.2 -> 13.8) which is what I'd want, but others are taking over two seconds (2047.7 -> 2564.2) - the images are similar sizes and going through the same route. – Kaine Commented Nov 24, 2014 at 11:43
 |  Show 2 more ments

4 Answers 4

Reset to default 3

Several options are available:

  1. Caching the images in the browser/client-side by adding cache-control HTTP to the response headers.
  2. Caching the images in the server-side (in-memory) instead of carrying-out an I/O operation to the file-system (IIS will cache frequently used images and serving them from memory).
  3. Compression of HTTP response's resources using GZIP, for example (you should do it in your Web-Server).
  4. Reduce images size/quality in the server (maybe while uploading them).
  5. Use CSS image sprite technique: An image sprite is a collection of images put into a single image and by that, reducing the number of images that the browser need to load.
  6. Use a dedicated CDN for serving your images faster and in turn, reduce the load-time on the server.

You should decide what's the best choice in your case.

UPDATE:

Another 2 options:

  1. With ng-repeat, in each iteration of your results you're effectively accessing the server instead of accessing the browser cache - there could be hundreds of records. It would be better to send your images with cache-control HTTP response headers (A Beginner's Guide to HTTP Cache Headers) in order to prevent accessing the server again and again for fetching the images and reducing the repeated round-trips.

  2. Pre-load your images into the browser cache: http://perishablepress./3-ways-preload-images-css-javascript-ajax/

Consider option to resize images once they loaded on the server and store thumbnails images on the server or CDN as well as orignal version. This will reduce server load and make image load as fast as getting image without any processing every time image requested.

Use a proper CDN or just serve it directly from virtual directories. Your current implementation is IIS is good and fast as a web server, .Net framework is good as a server-side technology.

A properly configured IIS will help you save bandwidth and file system I/O, if you need resizing capabilities, check out Image Resizer

It turns out that it's the MVC SessionState that causes this issue - although it's not entirely clear why at thgis stage.

Adding a new controller just for images and decorating it as below will disable the default session state behaviour and prevent the images getting stuck 'waiting' for ages.

    [SessionState(System.Web.SessionState.SessionStateBehavior.Disabled)]
    public class ImageController : Controller
    {
      public ActionResult GetThumbnail(string code)
      {
          byte[] image = _dataProvider.GetThumbnailImage(code);
          return this.Image(image, "image/jpeg");
      }
    }
发布评论

评论列表(0)

  1. 暂无评论