7

我有一个主要的性能问题。问题出在我的一个网站上,有一个滑块可以调用大约 180 张图像。这 180 张图片中的每一张都是由客户端浏览器通过单独的 url 下载的。它们是 gif 和 jpg 的混合体,我想将它们组合成一个图像;最好是 jpg,因为透明度不是问题。图像存储在 SQL 数据库中,并通过 MVC 控制器显示。我想这个精灵也可以通过 MVC 控制器创建,而不是更传统的通用 ashx 处理程序。

我做了一些谷歌搜索,发现了Scott Hanselman 的一篇博文。该帖子解释了如何组合检查图像并通常做我想做的事情。它是在 2005 年写的,所以我很好奇是否有更好的方法。我一直在另一个项目上使用 ImageResizer。我听了Hanselman 先生的播客,该播客与该项目的创始人谈论使用 IIS 和 .NET 调整图像大小。我从那个播客和我的经验中收集到,.NET 和 IIS 中的图像处理可能会变得很奇怪。

以这种方式调整图像大小并将图像合并到精灵中仍然是一个好主意吗?我不想要精灵生成器,我想要一种有效的方法将 .gif 和 jpg 组合成一个可以用作精灵的图像。

4

1 回答 1

7

我不建议将所有内容组合成一个图像,因为您将延迟任何图像的“初始外观”,直到整个文件下载。最好让可见的东西尽快加载并优化其余部分以提高整体吞吐量。

例如,如果图像每个小于 50KB,将它们组合为精灵图像可能是有意义的,但我建议一次组合 10 个。如果图像很小,比如每个 5KB,一次 30 个是合理的。

您需要担心一系列瓶颈

  1. HTTP 开销和并发连接限制(精灵图像对此有帮助)
  2. 服务器吞吐量开销(可通过正确的磁盘缓存和边缘缓存解决)
  3. 浏览器渲染开销(精灵最适合图标和小缩略图;它们不应该很大,尽量保持在 1 兆像素以下)。

将现有图像连接在一起并以 jpeg 形式重新压缩有时可以提高压缩率,有时会引入伪影。例如,混合线条艺术和照片是一个坏主意。Jpeg擅长线条艺术。如果需要,可以使用 PNG,甚至是 PNG-8。有时您会发现 100% 质量的 JPEG 最终小于 GIF 或 PNG 版本,但大多数时候,线条艺术最好以 PNG 格式存储。

如果您有这些照片的 ID,并计划使用磁盘缓存进行动态路由,它确实可以显着简化您的任务。

ImageResizer库可让您轻松“插入”其动态管道和磁盘缓存系统。

在这种情况下,您将实现IVirtualImageProviderand IVirtualBitmapFile。有关生成位图并让管道处理其余部分的简单示例,请参阅渐变插件

您必须定义您的 url 语法并在 FileExists 和 GetFile 方法中查找它。/combine-images.ashx?idlist=34,56,79,23&dir=horizo​​ntal&width=50&height=50 之类的东西。

然后,您必须加载每个图像,使用托管 API将其大小调整为位图实例,然后将其绘制在您分配的画布上。

您的大部分瓶颈可能在于从 SQL 中提取图像。如果服务器上的 RAM 有限,串行方法可能比并行方法更安全(即,一次从 SQL 获取一个图像,调整大小并绘制它,处理数据,然后继续)。如果您的源图像开始时很小,则多线程方法可能没问题。请记住,即使它被磁盘缓存,您也需要使其快速,因为请求默认在 30 秒后超时。正确完成后,您应该能够在 2 秒内使用空磁盘缓存提供 10 个图像精灵,缓存后为 20 毫秒。

如果这看起来有点压倒性,我确实提供自定义插件开发,但有一个队列。

每个请求 1 个文件的方法有很多优点,在加入 Sprite 潮流之前,可能值得尝试 ImageResizer 的磁盘缓存和 SqlReader 插件。并不是说这是错误的方法,但未缓存的 MVC+SQL 可能会增加很多开销。

于 2012-04-24T18:34:10.020 回答