OriginProtocol / origin

Monorepo for our developer tools and decentralized marketplace application
https://www.originprotocol.com/developers
MIT License
652 stars 196 forks source link

Image Optimization #947

Closed nick closed 5 years ago

nick commented 5 years ago

Some listings have very large (> 1Mb) images which are downloaded in full even when we only need to show a thumbnail.

A few possible solutions:

  1. Use an image resize proxy service. This allows you to resize images on the fly automatically. Eg https://images.weserv.nl or cloudimage.io
  2. Host our own image proxy/cache eg https://github.com/weserv/images or https://willnorris.com/go/imageproxy
  3. Resize images in the browser at upload time and push multiple sizes to IPFS
  4. Provide a service that resizes uploaded images and pushes to IPFS, returning the hashes back to the client for inclusion in the listing IPFS blob

An example optimization using weserv:

Original hat - 1.3Mb Optimized hat (300px wide) - 31kb

DanielVF commented 5 years ago

I think handling image resizing would be a great value-added service - just like the discovery server currently adds much faster reads of listing and offer state.

Another option would be to consider rolling this into the discovery server. When it get's a new listing, it can fetch the images associated with it, resize to some prearranged sizes, place these back on IPFS, and hand out these thumbnail hashes available over IPFS.

We don't really want to be at the mercy of a third party for image services. Hosting a service that arbitrarily fetches and processes images can be DDOSed for free, and may be abused for bad non-Origin content.

Trusting the client to upload correctly sized thumbnails is certainly far better than what we are doing now, but there's still no guarantee listings will be created with our software or non-maliciously. We could have the discovery server check a listings thumbnails, and not index the listing if the thumbnail sizes are bad.....

tomlinton commented 5 years ago

Another option here is ipfs-proxy which is running alongside our IPFS node. It knows if something is an image so we could add some image processing based on a query string check with something like sharp and cache the processed image. I think it could be quite clean because the URLs would just change from something like https://ipfs.originprotocol.com/ipfs/<hash> to https://ipfs.originprotocol.com/ipfs/<hash>?w=300.

joshfraser commented 5 years ago

I'm a bit dismayed by the growing number of centralized services we're now relying on. Since we can get everything we need in the browser without adding another centralized dependency, that would be my vote.

The problem w/ using ipfs-proxy is that other gateways won't support that & eventually we're going to want people to be able to choose whichever gateway they want.

nick commented 5 years ago

Agree we should cut down on centralized services, however Tom's solution is just an optimization... you can still use any IPFS server to get the raw image, we're just optimizing it for file size with the extra URL param

joshfraser commented 5 years ago

It's a bit weird to me that we'd be returning content that no longer matches the hash of the file. Feels like that could break things down the line as we/others do integrity checks.

tomlinton commented 5 years ago

It is a bit weird, but we can also make it clear from the URL that the hashed content is being modified, e.g. /ipfs/<hash>?modify-width=300. The original content is not modified, it is just a convenience method for returning specific sized images. You can run an integrity check or retrieve the original content like normal. This would also degrade gracefully, you can use a standard IPFS node and it'd just ignore the query string and retrieve the content.

The big downside I can see is that DApp developers would tend to use IPFS nodes that supported this on-the-fly resizing because it'd result in snappier DApps. This would lead to a non uniform distribution of Origin content on IPFS nodes.

I think the decentralisation friendly approach is 3. as you noted Josh. It's got its downsides too though: we have to decide on some standard sizes which will be fixed, it results in storing a lot more data, and as Daniel mentioned its a client side solution.

Food for thought!

franckc commented 5 years ago

Good discussion ! Agreed that solution 3. is best from a decentralized standpoint. A few thoughts:

DanielVF commented 5 years ago

Yeah, I think we should go with client side resizing to thumbnails, and if needed at some far future date, the discovery server can check that the uploaded images are honest and ding the listing if they aren't.

tomlinton commented 5 years ago

Closed in favour of #2187.