Carrierwave or Dragonfly

2020-02-17 05:04发布

问题:

I have been looking into rails file upload tools and the ones that seemed the most appealing and interesting to me were carrierwave and dragonfly.

From looking around it seems like carrierwave takes the more traditional style where you can process the file on save whereas dragonfly is middleware so it allows you to process on the fly.

I was wondering if people had any references to performance test or any test that compare the two.

Also, just curious on what people's opinions are about both and which they prefer and of course why they prefer it.

回答1:

Depending on the setup. As Senthil writes, as long as you have a cache-proxy in front, it's fine with Dragonfly.

But if you are using the built-in rails caching, Carrierwave will perform better, as the files can be loaded without any processing. If you don't do any processing, it doesn't matter.

Here's how I summarized when considering both for Images on a project with Mongomapper:

Carrierwave:

  • Pros
    • Generates thumbs on upload (saves CPU time)
    • Can use files directly from a static/cached document
    • Doesn't need any cache-front
    • Supports various storage backends (S3, Cloudfiles, GridFS, normal files) easy to extend to new storage types if needed.
  • Cons
    • Generates thumbs on upload (diffucult to generate new thumbsizes)
    • Doesn't natively support mongomapper
    • Uses storagespace for every file/thumb generated. If you use normal file storage, you might run out of inodes!

Dragonfly:

  • Pros
    • Should work with mongomapper, as it only extends ActiveModel
    • Generates thumbs on the fly (easier to create new layouts/thumbsizes)
    • Only one file stored! Saves space :)
  • Cons
    • Eats CPU on every request if you don't have a cache-proxy, rack::cache or similar.
    • No way to access thumbs as files if needed.

I ended up using both in the end.

A future wish is for carrierwave to suppert MongoMapper again. After using both in various situations, I've found that the features in MongoMapper (rails3 branch) always works, and are easy to extend using plugins. Cannot say the same for Mongoid as of now, but that might change.



回答2:

I use dragonfly simply because carrierwave dropped support for mongomapper and paperclip doesn't work mongomapper without some hacks.

Dragonfly does processing on the fly, i.e.

is meant to be used behind a cache-proxy such as Varnish, Squid or Rack::Cache, so that while the first request may take some time, subsequent requests should be super-quick!



回答3:

Paperclip

Paperclip is intended as an easy file attachment library for Active Record. The intent behind it was to keep setup as easy as possible and to treat files as much like other attributes as possible. This means they aren't saved to their final locations on disk, nor are they deleted if set to nil, until ActiveRecord::Base#save is called. It manages validations based on size and presence, if required. It can transform its assigned image into thumbnails if needed, and the prerequisites are as simple as installing ImageMagick (which, for most modern Unix-based systems, is as easy as installing the right packages). Attached files are saved to the filesystem and referenced in the browser by an easily understandable specification, which has sensible and useful defaults.

Advantages

  1. validations, Paperclip introduces several validators to validate your attachment: AttachmentContentTypeValidator AttachmentPresenceValidator AttachmentSizeValidator
  2. Deleting an Attachment Set the attribute to nil and save. @user.avatar = nil @user.save
  3. Paperclip is better for an organic Rails environment using activerecord and not all the other alternatives. Paperclip is much easier to handle for beginning rails developers and it also has advanced capabilities for the advanced developer.
  4. A huge fan of Paperclip because it doesn't require RMagick, it's very easy to set it up to post through to Amazon S3 and declaring everything in the models (validations, etc) keeps things clean.
  5. With respect to multiple file uploads and progress feedback, both are possible with both Paperclip and Attachment_fu, but both typically require some elbow grease with iframes and Apache to get working.

CarrierWave

This gem provides a simple and extremely flexible way to upload files from Ruby applications. It works well with Rack based web applications, such as Ruby on Rails.

Advantages

  1. Simple Model entity integration. Adding a single string image attribute for referencing the uploaded image.
  2. "Magic" model methods for uploading and remotely fetching images.
  3. HTML file upload integration using a standard file tag and another hidden tag for maintaining the already uploaded "cached" version.
  4. Straight-forward interface for creating derived image versions with different dimensions and formats. Image processing tools are nicely hidden behind the scenes.
  5. Model methods for getting the public URLs of the images and their resized versions for HTML embedding.
  6. if built-in rails caching, Carrierwave will perform better, as the files can be loaded without any processing. If you don't do any processing, it doesn't matter.
  7. Generates thumbs on upload (saves CPU time)
  8. Can use files directly from a static/cached document
  9. Doesn't need any cache-front
  10. Supports various storage backends (S3, Cloudfiles, GridFS, normal files) easy to extend to new storage types if needed. One of the fact that it doesn't clutter your models with configuration. You can define uploader classes instead. It allows you to easily reuse, extend etc your upload configuration. What we liked most is the fact the CarrierWave is very modular. You can easily switch your storage engine between a local file system, Cloud-based AWS S3, and more. You can switch the image processing module between RMagick, MiniMagick and other tools. You can also use local file system in your dev env and switch to S3 storage in the production system. Carrierwave has good support for exterior things such as DataMapper, Mongoid, Sequel and even can be used with a 3rd party image managment such as cloudinary The solution seems most complete with support coverage for about anything, but the solution is also much messier (for me at least) since there is a lot more code that you need to handle. Need to appreciate the modular approach that CarrierWave takes. It’s agnostic as to which of the popular S3 clients you use, supporting both aws/s3 and right_aws. It’s also ORM agnostic and not tightly coupled to Active Record. The tight coupling of Paperclip has caused us some grief at work.

Disadvantages

  1. You can't validate file size. There is a wiki article that explains how to do it, but it does not work.
  2. Integrity validations do not work when using MiniMagick (very convenient if you are concerned about RAM usage). You can upload a corrupted image file and CarrierWave will throw an error at first, but the next time will swallow it.
  3. You can't delete the original file. You can instead resize it, compress, etc. There is a wiki article explaining how to do it, but again it does not work.
  4. It depends on external libraries such as RMagick or MiniMagick. Paperclip works directly with the convert command line (ImageMagick). So, if you have problems with Minimagick (I had), you will lose hours diving in Google searches. Both RMagick and Minimagick are abandoned at the time of this writing (I contacted the author of Minimagic, no response).
  5. It needs some configuration files. This is seen as an advantage, but I don't like having single configuration files around my project just for one gem. Configuration in the model seems more natural to me. This is a matter of personal taste anyway.
  6. If you find some bug and report it, the dev team is really absent and busy. They will tell you to fix bugs yourself. It seems like a personal project that is improved in spare time. For me it's not valid for a professional project with deadlines.
  7. Doesn't natively support mongomapper
  8. Uses storagespace for every file/thumb generated. If you use normal file storage, you might run out of inodes!

Dragonfly

  1. The impressive thing about Dragonfly, the thing that separates it from most other image processing plugins, is that it allows on-the-fly resizing from the view.
  2. Not needing to configure thumbnail sizing or other actions in a separate file is a huge time and frustration saver. It makes Rails view code like image_tag @product.image.thumb('150x150#') possible.
  3. The magic is all made possible by caching. Instead of building the processed version on upload and then linking to individual versions of the image, the plugin generates images as they are requested. While this is a problem for the first load, the newly created image is http cached for all subsequent loads, by default using Rack::Cache, though other more robust solutions are available should scaling become an issue.

Advantages

  1. Will I be changing image size often? Example: if you want to let your users change the size of their pictures (or your need flexibility in size for some other reason), or really fast development. Yes: Dragonfly No: either Carrierwave or Paperclip
  2. Can be used with mongomapper with no trouble
  3. Performance should be fine as long as you use a caching proxy
  4. Should work with mongomapper (it only extends ActiveModel)
  5. Generates thumbs on the fly (easier to create new layouts/thumbsizes)
  6. Only one file stored! Saves space
  7. Processing done on the fly (is meant to be used behind a cache-proxy such as Varnish, Squid or Rack::Cache, so that while the first request may take some time, subsequent requests should be super-quick)

Disadvantages

  1. Eats CPU on every request if you don't have a cache-proxy, rack::cache or similar.
  2. No way to access thumbs as files if needed.

References

  • Ruby on Rails Image Uploads with CarrierWave and Cloudinary
  • Rails 3 paperclip vs carrierwave vs dragonfly vs attachment_fu


回答4:

Other people wrote pretty good summaries, I just would like to say that from our experience Dragonfly setup needed more maintenance, and because of negligence of some developer(s) along the way we were also stuck with plenty of orphan images which lingered after the original was removed. This wouldn't have happened with a vanilla carrierwave. P.S. We migrated to cloudinary (and use carrierwave with it) and are happy with it.