服务器端图片调整大小的性能

7
我注意到越来越多的大型网站(如Google、Facebook、Youtube等)正在客户端重新调整图片大小以接近其所需的尺寸,我想知道这是否是人们思考方式的转变还是他们变得懒惰了。
例如,在一组产品(电子商务)中添加一种新的图像尺寸,该产品集合包含数十万、甚至数百万个产品。假设我有一份原始图像的副本,它的尺寸为300x350或其他尺寸,并在客户端将其调整为200x250。我为每个页面上的20个产品都这样做。
那么,为了使客户端受益,值得花费服务器端的工作和解决问题来适应这种新尺寸吗?
如果不是,那么判断何时应预处理某个尺寸会更好呢?
如果是,那么是否存在服务器端处理和缓存可能过度的情况(例如,存储8张110x220、120x230、150x190等尺寸的图像)?

客户端调整大小是救星。当一定数量的人同时上传图片时,我的服务器会崩溃。这是唯一的方法...想象一下,如果大多数用户上传的图片都是原始文件大小的一半或四分之一,你的CPU可以节省多少工作量。这可以通过画布完成,在摄入服务器端之前调整大小并转换为字符串。这对用户体验也有好处,因为它可以加快页面加载时间。这是双赢的局面。 - FredTheWebGuy
2个回答

1
考虑以下问题: 图片调整大小对服务器来说是一个繁重的过程。首先它本身就很昂贵。其次,这是硬盘I/O操作,速度相当慢。所以这完全取决于您的服务器有多忙。
对客户端而言,它影响两个方面:
1) 缩略图文件更小,因此下载速度更快。所以它们会显示得更快。但这完全取决于互联网连接的速度,这一点每天都在增长。您见过大型图像如何加载吗?它们不会一次性全部显示出来,而是逐行显示。
2) 如果尝试将大图像显示为小图像,则图像质量将会大幅降低。这是因为浏览器如何处理它。它们不具备 Photoshop 的功能,无法进行适当的质量调整。
3) 单个页面上有许多大型图像将增加该页面的内存使用率。在一些性能不太强劲的电脑上,这可能导致滚动或打开页面时出现严重卡顿。
做出对此问题的解决方案,我更倾向于采用Drupal模块之一中所见的内容(如果我没记错的话,应该是imagecache)。

它在上传图像时不会创建缩略图。相反,它使用.htaccess和mod_rewrite功能在请求时间创建它们。它检查所请求的文件是否不存在,如果不存在,则将请求重定向到小型且轻量级的PHP脚本,该脚本将创建缩略图,将其写入文件系统,然后输出到客户端。

因此,下一个访问者将已经获得先前创建的缩略图。

因此,您可以实现延迟/懒惰的图像调整大小,这将使负载更加平滑(在时间上拉伸)。


@Sammaye,那我在这里能做什么呢?我给了你基本的原因,但每个人都必须自己决定应该走哪条路。最终我们所做的(因为流量太高)是采用所有可以改进的方式。所以我们假设有一个原始图像800x600。然后在页面上我们使用150x100、200x250、400x300和原始大小。所以我们只需要创建两个缩略图。200x250和400x300,然后将200x250用于150x100。这是一种方法,但如果你仔细思考,还有很多其他方法。 - Alexey Kamenskiy
@Sammaye 不是真正的处理它,而是允许浏览器在<img width="150" height="100">中呈现250x200。 是的,它的质量不会很好。 但它足够小,以至于质量并不那么重要。(当然我指的不是200x250,而是250x200) - Alexey Kamenskiy
嗯,我的意思是你的答案缺少一些细节,就像我知道ff使用opengl进行3d和2d渲染,而Photoshop也大多使用这种技术,因此两者的质量都很好。如上评论所证明的那样,下载大小实在太小了,没什么必要关心,而且我不知道你所说的内存使用情况是什么,因为即使你在服务端缩放图像,当图像渲染时客户端计算机仍然需要将图像保存在内存中(也许你想说的是CPU使用率?)。另外,我认为这个问题没有得到很好的回答。因此,这个答案看起来并不是很权威。 - Sammaye
但是,渲染100px(2)相对于1000px(2)需要多少CPU呢?当然,第一件事是每秒所需的计算量,但是这是我正在寻找的一个要点。我需要有经验的人来通过这种方式进行图像缩放。 - Sammaye
我还是不明白你的第一条评论,我并没有询问页面上大量图像的内存使用情况。就CPU而言,我想知道:对于PC性能来说,100px(2)的后处理缩放图像是否会对其产生如此严重的影响,以至于我不应该这样做?我的意思是,其他大型网站,如FB、Youtube和Google都在这样做。因此,我想知道,将所有图像进行缩放以满足所需大小的服务器端缓存状态是否比保留标准集并在客户端缩放接近测量值的混合解决方案更好。 - Sammaye
显示剩余18条评论

0

我决定先在页面上的单个图像上进行测试,并进行了一些乘法运算来预测多个图像。需要注意的是:

  • 我在这个测试中使用的是png格式,不过png格式似乎相当标准。
  • 我使用了一个特定的函数,该函数可以自适应地调整图像大小,以便宽度高度始终适合我调整大小的原始图像的纵横比。

我得到了一个大约为450x450的图像,并决定将其缩小到200x200(本答案中的所有测量单位均为像素),在客户端进行缩放。尽管缩放超过了图像总大小的一半,但我发现CPU的负载很小。

在所有现代浏览器(Chrome、Opera、Firefox和IE)中,图像的质量也非常好,显示得清晰明了,就像是在Photoshop或GD中完成的一样。

在IE7上,我没有注意到太多的CPU负载,并且只要根据图像大小的限制使用百分比缩放,质量就很好。

总的来说,即使是将这种大小的缓存服务器端进行存储、计算和编码所需的额外工作,似乎也不如可以应用于用户端的功能强大。

话虽如此,如果我要开始做这种类型的多次调整大小(比如我的问题中的20次),我可能会遇到问题。

经过一些调整,我发现如果原始图像的宽度或高度小于1000像素,则在原始图像大小的1/3以下提供的任何内容似乎对CPU和计算机性能都是微不足道的。

使用我正在使用的附加功能,我从客户端调整大小得到了与服务器端相同的良好质量。我使用的特定函数(对于感兴趣的人)是:

function pseudoResize($maxWidth = 0, $maxHeight = 0){

$width = $this->org_width;
$height = $this->org_height;

$maxWidth = intval($maxWidth);
$maxHeight = intval($maxHeight);

$newWidth = $width;
$newHeight = $height;

// Ripped from the phpthumb library in GdThumb.php under the resize() function
if ($maxWidth > 0)
{
    $newWidthPercentage = (100 * $maxWidth) / $width;
    $newHeight          = ($height * $newWidthPercentage) / 100;

    $newWidth = intval($maxWidth);
    $newHeight = intval($newHeight);

    if ($maxHeight > 0 && $newHeight > $maxHeight)
    {
        $newHeightPercentage    = (100 * $maxHeight) / $newHeight;

        $newWidth = intval(($newWidth * $newHeightPercentage) / 100);
        $newHeight = ceil($maxHeight);
    }
}

if ($maxHeight > 0)
{
    $newHeightPercentage    = (100 * $maxHeight) / $height;
    $newWidth               = ($width * $newHeightPercentage) / 100;

    $newWidth = ceil($newWidth);
    $newHeight = ceil($maxHeight);

    if ($maxWidth > 0 && $newWidth > $maxWidth)
    {
        $newWidthPercentage = (100 * $maxWidth) / $newWidth;

        $newHeight = intval(($newHeight * $newWidthPercentage) / 100);
        $newWidth = intval($maxWidth);
    }
}

return array(
    'width' => $newWidth,
    'height' => $newHeight
);
}

从我的测试结果来看,似乎将您要使用的每个图像的每个尺寸都存储起来是有些过度的。正如我在问题中所问:

如果是这样,那么是否会有时候服务器端处理和缓存可能会变得过度(即存储110x220、120x230、150x190等8张图片)?

在现代计算机中,这似乎是过度的,相反,如果您打算使用许多不同大小的图像,则应选择接近的测量值。

然而,我发现,如果您有一组标准尺寸并且它们很小,则实际上优势在于服务器端调整大小和存储所有尺寸,因为强制客户端调整大小将始终使其计算机变慢,但在原始大小的1/3以下进行缩放似乎不会产生太大的影响。

因此,我认为像FB、Google和Youtube这样的网站不太担心存储所有图像的精确尺寸,是因为“接近测量”的缩放可以更加高效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接