如何加速Angular / Mvc.net的图像加载

时间:2014-11-24 09:45:29

标签: javascript c# asp.net-mvc angularjs

我有一个MVC.net网站,根据这篇旧文章提供图像:

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

我的c#控制器代码如下所示:

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

在客户端,我有一个AngularJS控制器,它从服务器加载搜索结果集。结果集包含许多图像URL,如下所示:

    <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>

thumbnailUrl指向我的MVC控制器上的GetThumbnail操作,并在模型工厂中构建服务器端并返回到Angular准备使用。

问题是图像加载速度非常慢,即使每张图像只有3kb左右。在javascript中完成异步搜索返回后,图像一次出现一个,大约每秒一个,直到它们都被加载。

我在.net控制器的C#上放了一个秒表,从服务器端的dataProvider加载图像数据需要大约0.9ms但是即使只有10张图像可供使用,也需要大约6秒才能显示所有图像在页面中加载。 JS几乎可以立即呈现链接,只是图像很慢。

如何在此上下文中加快图像加载?

更新

如果我将图像移动到〜/ images / image.jpg并使用Url.Content将网址直接指向该文件夹,它似乎没有相同的问题。因此,问题似乎在于控制器为图像提供服务的方式 - 有时候如果可以采取&lt;对于同一图像,10ms和其他时间超过2000ms,但目前还不清楚为什么。

4 个答案:

答案 0 :(得分:3)

有多种选择:

  1. 通过向响应标头添加缓存控制HTTP,在浏览器/客户端缓​​存图像。
  2. 在服务器端(内存中)缓存图像,而不是对文件系统执行I / O操作(IIS将缓存常用图像并从内存中提供它们)。
  3. 使用GZIP压缩HTTP响应的资源(例如,您应该在Web服务器中执行此操作)。
  4. 降低服务器中的图像大小/质量(可能在上传时)。
  5. 使用CSS图像精灵技术:图像精灵是放在单个图像中的图像集合,由此减少了浏览器需要加载的图像数量。
  6. 使用专用CDN更快地为您的图像提供服务,从而减少服务器上的加载时间。
  7. 您应该决定什么是您的最佳选择。

    <强>更新

    另外两个选项:

    1. 使用ng-repeat,在结果的每次迭代中,您都可以有效地访问服务器而不是访问浏览器缓存 - 可能 数百 记录。最好使用cache-control HTTP响应标头(A Beginner's Guide to HTTP Cache Headers)发送图像,以防止一次又一次地访问服务器 以获取图像并减少重复轮次-trips。

    2. 将图片预加载到浏览器缓存中:http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

答案 1 :(得分:0)

考虑在服务器上加载图像后调整图像大小的选项,并在服务器或CDN上存储缩略图图像以及原始版本。这将减少服务器负载并使图像加载与获取图像一样快,而不是每次请求图像时都进行任何处理。

答案 2 :(得分:0)

使用正确的CDN或直接从虚拟目录提供。您当前的实现是IIS作为Web服务器是好的和快速的.Net框架作为服务器端技术是好的。

正确配置的IIS将帮助您节省带宽和文件系统I / O,如果您需要调整功能,请查看Image Resizer

答案 3 :(得分:0)

事实证明,MVC会话状态导致了这个问题 - 虽然它并不完全清楚为什么会在这个阶段。

仅为图像添加新控制器并按如下方式对其进行装饰将禁用默认会话状态行为并防止图像卡住并等待#39;多年。

    [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");
      }
    }