【问题标题】:Carrierwave - Multiple images upload too slow when adding or removing imagesCarrierwave - 添加或删除图像时多张图像上传速度太慢
【发布时间】:2017-03-22 03:37:15
【问题描述】:

我正在关注 CarrierWave Wiki https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Add-more-files-and-remove-single-file-when-using-default-multiple-file-uploads-feature 中的这篇文章,以使用 CarrierWave 多次上传功能为我的系统中的模型添加更多图像和删除图像。

那篇文章的主要代码是

def add_more_images(new_images)
  images = @gallery.images 
  images += new_images
  @gallery.images = images
end

def remove_image_at_index(index)
  remain_images = @gallery.images # copy the array
  deleted_image = remain_images.delete_at(index) # delete the target image
  deleted_image.try(:remove!) # delete image from S3
  @gallery.images = remain_images # re-assign back
end

它有效。 不过,太慢了。我看过日志,整体处理时间如下:

  1. 上传 1 张图片:例如需要 5000 毫秒
  2. 再添加 1 张图片:需要 8500 毫秒(2 张图片)
  3. 再添加 1 张图片:需要 12000 毫秒(3 张图片)
  4. 删除 1 张图片:需要 8400 毫秒(返回 2 张图片)

我在本地机器上测试了作者编写的这个解决方案的示例应用程序,速度也很慢。

即使我们只添加或删除 1 张图片,CarrierWave 似乎也会重新上传和重新处理所有图片。我想是因为我们将新的图像数组重新分配给@gallery,以便它将旧图像视为新图像。

这里还有一个相关的问题https://github.com/carrierwaveuploader/carrierwave/issues/1704#issuecomment-259106600

有没有人有更好的解决方案来使用 CarrierWave 多次上传功能添加和删除图像?

谢谢。

【问题讨论】:

    标签: ruby-on-rails ruby carrierwave image-uploading


    【解决方案1】:

    当您拨打model.images = remain_images 时,carrierwave 将上传所有图片。因此,您在列中存储的图像越多,所需的时间就越长。 见:mount.rb#L300mounter.rb#L40

    我之前也遇到过这个问题,下面是我的代码:

    new_images = self.logo_images.clone
    4.times do |t|
      next if !(image = params[:"logo_image#{t + 1}"])
      new_images[t] = image
      changed = true
    end
    self.logo_images = new_images if changed
    ...
    self.save if changed
    

    这就是黑客...

    (适用于 carrierwave 1.0.0carrierwave-aws 1.1.0

    mounter = self.send(:_mounter, :logo_images)
    4.times do |t|
      next if !(image = params[:"logo_image#{t + 1}"])
      uploader = mounter.blank_uploader
      uploader.cache!(image)
      mounter.uploaders[t] = uploader
      changed = true
    end
    mounter.uploaders.each{|s| s.send(:original_filename=, s.file.filename) if !s.filename} if changed 
    ...
    self.save if changed
    

    【讨论】:

    • 我在遵循您的代码时遇到了问题。看起来对于提供的每个logo_image[x] 参数,它都会缓存图像并将其添加到新的blank_uploader,然后迭代所有新的上传器并分配original_filename。所以让我们之前有 4 张图片,现在用户操作只在参数中发送 3 张(代表已删除的图片)......这如何防止重新上传原始 3 张图片?
    • 代码只能添加或替换图片。让logo_images 成为[nil, image1, image2] 并且用户上传一个新图像params[:logo_image3]。如果您使用add_more_images([params[:logo_image3]]),carrierwave 将上传image1image2params[:logo_image3]。但是如果你使用我的代码,它只会上传params[:logo_image3]
    • 我不知道如何删除图像。您可以尝试mounter.uploaders[t]&.remove! 删除图像。 mounter.uploaders.delete_at(t) 删除上传者。然后迭代所有的上传者并分配 original_filename。
    猜你喜欢
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多