Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: TIP vs PINRemoteImage #9

Open
oferRounds opened this issue Mar 4, 2017 · 4 comments
Open

Question: TIP vs PINRemoteImage #9

oferRounds opened this issue Mar 4, 2017 · 4 comments
Labels

Comments

@oferRounds
Copy link

oferRounds commented Mar 4, 2017

Thanks for sharing TIP!
Looks very very impressive!

Currently, I use PINRemoteImage in my app (and enjoy it very much!). If I may, I wanted to ask the following:

  1. What were the reasons you felt that PINRemoteImage would not be good for the Twitter iOS app?
  2. What are the key differences to consider when choosing between both?

Thanks again for sharing this library!

@NSProgrammer
Copy link
Collaborator

NSProgrammer commented Mar 4, 2017

Thanks for the message!

PINRemoteImage is an excellent framework with strong implementation, good documentation and is well maintained. TIP doesn't set out to compete with other frameworks that fulfill a developers needs so if you are getting what you need from PINRemoteImage (or anyone else with any other framework), definitely keep using it 😊

As to your specific questions:

  1. why does Twitter not use PINRemoteImage? I'll answer that briefly in a sec.
  2. what are the key differences to consider? I prefer not to pit two open source frameworks against one another and will defer to the README.md list of features for TIP and permit evaluators to draw their own conclusions as to the comparison and contrast with any other frameworks. (I'll paste them at the bottom of this reply too).

Why not PINRemoteImage? There are 2 very specific reasons: 1) is that we have specific requirements that PINRemoteImage does not offer (which is likely for the best for avoiding complexity) - these are visible in the feature set TIP has. 2) (and most obvious) is that TIP was written in January 2015 and integrated in April 2015. PINRemoteImage was published to GitHub in July 2015. So there was no PINRemoteImage for us to consider at the time ¯\_(ツ)_/¯

Features (with some color added)

  • Fetching
    • Progress reporting
      • for progress UI
    • Customizable progressive loading policies
      • supporting progressive loading AND offering control of how to progressively load (greedily, per scan, first & last scan, and more)
    • Preview loading with option to avoid continuing to load
      • not listed, but implied, is multivariant support
      • cached images that are larger than requested variant will be used and scaled rather than hitting network
      • cached images that are smaller than requested are offered as previews while larger version async loads OR can be used as the image and the full load (if delegate determines it is high enough quality) will be cancelled
    • Placeholder support (for non-canonical images that get purged)
      • Not the same as a static placeholder, which any view can have
      • Having a super low fidelity image that could be higher in resolution that canonical variants (say a b/w placeholder) can be useful until a canonical version is loaded and we just purge the placeholder
    • Automatic scaling to target view's size
      • provide the target view sizing to get the resulting image(s) scaled properly without impacting main thread perf
    • Custom caching options
      • customize TTL, whether or not to update LRU position on cache hit
    • Customizable set of loading sources (caches and network)
      • memory cache(s), disk cache, alt cache(s), network & network resumption
  • NSOperation based
    • Cancellable
      • when image is no longer necessary (goes off screen for example) we want to cancel
    • Priority support
      • affects operation priority AND download priority over multiplexed connections
    • Dependency chain support
      • one of the most powerful features of NSOperation is dependency chaining
    • Delegate pattern (for robust support)
    • Block callback pattern (for simple use cases)
  • Storing
    • Manual storage support (UIImage, NSData or file on disk)
      • user uploaded images being cached avoid unnecessary network calls
    • Manual purging support
      • such as when a user deletes an image from their account
    • Dependency chain support (like NSOperation)
      • just like fetches, stores have dependency support
  • Caching
    • Synchronous/fast cache for rendered images
      • immediately load images that are the right size and won't have an impact on the main thread
    • Async memory cache for images
      • fast access to cached images that are async scaled/rendered
    • Async disk cache for images
      • disk cache for long term storage
    • Automatic LRU purging
      • avoid cache bloat
    • Automatic TTL purging
      • purges shorter lived images, avoids perpetual caching
    • Siloed caches (via multiple TIPImagePipeline instances)
      • multiple accounts keep images segregated and can purge all cached images for a removed account
    • Support for loading from additional non-TIP caches (helps with migration)
      • helps migrate from a legacy cache to TIP and avoid unnecessary networking
    • Expose method to copy disk cache images directly
      • safely access on disk cached images without impacting cache integrity/safety
  • Downloads
    • Coalescing image downloads
      • multiple fetches to the same image will only hit the network once and demuxes to each fetch
    • Image download resumption support built in
      • cancelled/failed downloads will persist in cache and be resumed on the next download to save on unnecessary download bytes
      • example: scroll through timeline with images, some image loads 90% of the way then goes off screen and is cancelled. Instead of the next time the image is viewed being a full download, only the last 10% needs to load. When combined with progressive images, there will be no delay in getting whatever progressive content was already loaded.
    • Pluggable networking (use your own network layer)
      • Critical for Twitter since all networking goes over our own network layer for maximum measurements and control
    • Custom hydration (useful for authenticated fetches)
      • fetching an image that needs auth can use hydration, among other use cases for modifying the NSURLRequest that will be downloaded
  • Detailed insights
    • Global pipeline observability
      • see all fetches go by, can be useful for the network activity indicator
    • Individual pipeline observability
      • watch a specific pipeline or pipelines
    • Global problem observability (non-fatal problems for monitoring)
      • get notified on specific problems such as when a fetch's target sizing is wonky
    • Asserts can be enabled/disabled
      • fail fast and hard, we have asserts on except for production builds
    • Pluggable logging
    • Inspectable (can inspect each pipeline's entries)
      • We have dev UI that lets us visually look at every cache image and its metadata to find issues
    • Robust errors
      • being clear about what went wrong helps diagnose and fix
    • Detailed metrics on fetch operation completion
      • things like latencies and timing per load step
      • networking insight too like the NSURLResponse
  • Robust image support
    • Pluggable codecs (can add WebP or other image codecs)
      • we add and remove codecs regularly including custom codecs
    • Can serialize access to CGContext
      • too many images decoding at once can lead to out-of-memory crashes
    • UIImage convenience methods
      • just some convenience stuff, there are convenience functions too
    • Animated image support (GIFs, by default)
      • GIFs, pretty clear
  • UIKit integration
    • Default UIImageView subclass for convenience
      • convenient
    • Fetch helper offers useful fetch behavior encapsulation
      • decouples the Control work from the View
    • Debug overlay feature to see debug details of the image view
      • really nice debug UI to see how images are loading in realtime
  • Configurable
    • caches sizes (both in bytes and image count)
      • avoid cache bloat
    • max cache entry size
      • avoids single images from overwhelming the caches
    • max concurrent downloads
      • avoid network congestion by keeping concurrency limited (default is 4)

@oferRounds
Copy link
Author

@NSProgrammer – thanks a lot for your detailed answer!!
Of course, I wasn’t referring to any competition, I was just curious, programmatic wise 😀

Anyhow, going over the framework and its capabilities now - thanks so much again!!

@NSProgrammer
Copy link
Collaborator

Totally! Just wanted to clarify why I wouldn't be putting a side by side comparison together. Will use this issue as reference in the future for similar questions. I hope you enjoy :)

@oferRounds
Copy link
Author

I will 😀👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants