Laravel 图像缓存比源文件慢

5
我正在使用 Intervention/imagecache 缓存我的图像。然而,缓存的图像加载比源图像文件慢。在 Chrome 检查元素网络中测试,延迟时间增加了额外的 60-70ms。
这是我在 Route.php 中加载图像的代码。
    Route::get('images/cars/{src}', function ($src){    
        $cacheimage = Image::cache(function($image) use($src){
            return $image->make("images/products/".$src);
        },1440);

        return Response::make($cacheimage,200, array('Content-Type'=>'image/jpg'));
    });

在Blade中:
<img src="{{ URL::asset('/images/cars/theimage.jpg' }}" alt="">

有没有更好的方法来存储图片缓存?

这是一个关于github的问题,链接为https://github.com/Intervention/imagecache/issues/38。 - Netorica
我也在那里发表了一条评论。 - Eric
2个回答

9

我从未使用过laravel,但这是一个普遍的问题。

如果您让Web服务器处理向客户端传递图像,PHP解释器将不会启动。

如果您通过PHP传递某些内容(我假设如此,因为您提到了缓存的图像),则需要使用PHP解释器。那么您需要执行脚本和其中所有的逻辑,而在脚本语言中,这总是比原生语言慢。

您的最佳选择是将图像保存在文件系统中并链接到它,而不是使用PHP脚本。

例如:

在您的应用程序中的某个点,您创建了原始图像。现在考虑您需要哪些版本。调整大小、裁剪、编辑它,直到满足需要为止。将每个所需版本保存在文件系统中。这样,您就拥有了一个image-200x200-cropped-with-branding.jpg而不是image.jpg。此时,性能可能并不那么重要(该图像将被查看数千次,但仅创建一次)。

您需要:

<img src="/path/to/image-200x200-cropped-with-branding.jpg">;

替代

<img src="/image.php?param1=1&param2=2">;

3
PHP解释器是一回事,引导整个框架使问题变得更糟。 - lukasgeiter
你说的有点道理,似乎我得采用不同的方法。 - Eric
1
我遇到了同样的问题。感谢@Christian提供的方法,解决了我的问题。给你点赞。 - Emeka Mbah

2

基于Christian Gollhardt的回答,以下是一些额外的想法。

他说得很对,这是一个普遍的问题。但我不喜欢他创建或上传原始图像时所需的所有版本的方法。因为有一个大问题,如果在将来某个时间点,你决定缩略图应该是250x250而不是200x200(或任何其他尺寸),那怎么办呢?所以基本上我想要ImageCache包提供的灵活性,但没有性能下降。

我实际上还没有实现这个,但我的方法是使用某种“中间”辅助函数来包含所有视图中的图像。实质上,辅助函数将模拟图像缓存的功能,但它不会在实际图像请求上处理所有逻辑,而是在页面请求期间处理。因此,在实际图像从用户浏览器请求时,每个图像版本已经在服务器上创建,并且链接将指向文件系统上的实际图像。一些伪代码可以更好地解释它...

例如,在show_profile.blade视图中:

<h1>{{ $profile->name }}</h1>
<img src="{{ image_helper($profile->image->filename, 'small') }}">

helpers.php

function image_helper($filename, $version) {
    if (!file_exists($version . '_' . $filename)) {
        // some other helper function ...
        create_image_version($filename, $version);
    }

    return "my/images/" . $version . '_' . $filename;
}

function create_image_version($filename, $version) {
    // if you want to go that route, you would need some kind of mapping
    // that maps the $version (string) to a codeblock that actually knows
    // what to do if that version is requested.
    // E.g. if the version 'small' is requested, 
    // create an image with a dimension of 100x100
}

这真的很好,如果你需要动态地完成它。另一方面,为什么不简单地编写一个只运行一次的更新脚本呢?(当然,在这种情况下,原始图像也会被保存) - Christian Gollhardt
一个更新脚本也是一种可能性。我认为这取决于个人偏好或项目环境。或者你能更快地实现的方式。但需要记住的是,如果你选择使用更新脚本,你必须始终预先生成所有图像的新版本。而采用动态方法时,只会生成用户实际请求的图像。所以如果你有很多很多的图像,我更倾向于采用动态方式,因为可以节省一些磁盘空间。 - mwallisch

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