PHP动态调整图像大小与存储已调整大小的图像比较

30

我正在建立一个图片分享网站,想要了解使用PHP实时调整图片大小并存储调整后的图像的优缺点。

哪种方法更快?

哪种方法更可靠?

这两种方法在速度和性能方面的差距有多大?

请注意,无论哪种方式,图片都会通过PHP脚本进行统计(如浏览次数或是否允许热链接等),因此,如果我选择存储调整的图像,这不会像直接链接图片一样。

希望您能提供评论或任何有关该主题的有用链接。


好问题,我们可以考虑不存储图像缩略图,因为它会创建重复的图像,并且在备份网站时也是无用的数据。 - baptx
4个回答

32

这绝对是不可比较的事情。

实时调整图像大小就像在自己的服务器上运行DoS攻击一样。 调整一个普通图像的大小需要比为php脚本提供一个普通请求更多的CPU和RAM。 这已经对性能产生了巨大影响。 然而,通常会显示不止一个缩略图,而是以多个数量呈现。 因此,在仅显示一个图库页面时,您正在创建数十个繁重的负载过程,并将服务器负载增加了十倍或更多。

简单粗暴的测试来证明我的话: 让我们尝试调整相对较小的1.3百万像素图像。

$ /usr/bin/time --format="%MK mem %Es CPU time" /usr/bin/convert angry_birds_1280x800.jpg -resize 100x100 thumb.jpg
10324K mem 0:00.10s CPU time

这将花费我们0.1秒的时间,因此显示10个图像预览将占用您CPU时间的整整一秒钟。而正确编写的PHP图库页面大约需要0.01秒的时间。所以,通过在运行时调整大小,您将增加服务器负载100倍。

内存方面也是如此。每个缩放过程将消耗不少于10兆的内存(用于调整大小为100k的图像文件!),总和达到100兆。而PHP脚本的通常内存限制仅为8M,很少会达到。

这些都是真实的数字。

与这个问题相关的有趣事情:
完全相同的PHP用户在抛弃1000000个CPU周期的同时,对节省1或2个周期感到非常忌妒!这不是个说法,这是我所讲的问题的一个例子:
某人提出了类似的问题,他非常关心的事情与常量、变量或变量数组之间的速度差异相比微不足道。最近他遇到了内存不足问题,好像这样的灾难还不够。

这个网站上有大量的问题和答案,讨论各种操作的纳秒速度差异,以令人信服的尊严进行回答,运行数百万次迭代测试,以显示每个几个CPU周期的单次操作之间绝对微不足道的差异。

同时也有像这样的问题——关于两种方法在性能方面的巨大、不可比较的差异,在作者看来仅仅是相等的。

这就是PHP普通用户和这个网站的问题。
前者无法区分真实事物和微小的事物。
而后者没有对问题进行理智检查的机制——即使两个问题相互矛盾(并且都与常识相悖),所有问题都得到同等热情的回答。


OP的问题本身只是询问哪种方法更好,当然,预先调整图像大小并将其存储为调整大小后的图像可以大大提高性能,这是无可比拟的。不包括使用即时方法时,至少要调整同一图像两次的事实是最糟糕的性能。但是,如果在即时图像调整服务前面使用了一些CDN,以便每个图像都被缓存,那么它可能是一个非常好的选择。实际上,我可以说这是将调整大小后的图像存储到磁盘的懒惰版本。 - eAbi

24

根据图像的初始大小,动态调整大小可能是一项耗时的过程。在生产系统中我做过这样的操作,但如果可以选择,我强烈倾向于将内容缓存到磁盘中,毕竟磁盘空间很便宜,而在Web上加载时间非常重要。即使您只是以特定大小缓存缩略图并在其他所有地方进行动态调整大小,也可以大大减少画廊式图像列表的加载时间。


你说得对,我的实时主机上有400GB可用空间。我想我会把所有调整大小后的图像都存储起来。谢谢分享。 - Pablo

18

这听起来像是过早地进行优化。您知道您的站点将有多少用户/服务器有多少计算机功率吗?选择最简单的(在维护方面),即按需调整大小,直到性能成为问题,然后从那里找出解决方案。

如果您的重新缩放图像可能会被重复访问,实施某种类型的服务器端缓存可能是个好主意,但我认为这不需要扩展到显式的预渲染。


谢谢您的建议。目前我正在缓存所有缩略图,因为页面上会有很多,而动态调整大小则留给图片页面和下载选项。 - Pablo
你可以轻松地构建自己的调整大小应用程序,查看此存储库:https://github.com/sadok-f/flyimg - sadok-f
我还要补充一点,最好将缩略图缓存到一个单独的缓存目录中。这样你就不会将缩略图与原始图像混在一起,而且你可以轻松确定你想要在缓存上花费多少磁盘空间。因此,有限的缓存下的即时调整大小将允许你动态地调整系统负载和磁盘空间之间的权衡。此外,该实现非常模块化。 - Yeti

18

我强烈建议您缓存图片,而不是即时调整大小。

调整图像大小对服务器来说非常消耗CPU资源和内存空间。

如果您有一个图像库需要即时调整大小,该页会加载得很慢,大约需要3-10秒的时间,这取决于原始文件大小。

每调整一次大小,它将占用大约3字节的内存空间。因此,如果您要调整一个1000x1000的图像大小,它将占用大约3MB的内存空间。如果你的网页上有许多这样的即时调整大小的图像,比如20个,它将占用大约60MB的服务器内存空间。尽管多数客户端一次只请求4张图片,但12MB对于页面加载来说仍然是很多的。我只会在源图像小于100x100像素时才进行即时调整大小。

TIP:一个很棒的图片缩放和保存缩略图的库是PhpThumb


感谢您的输入,我一定会将图像存储在文件系统中。 - Pablo

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