(Disclaimer: I handle developer relations at imgix, and will be answering this post as it applies to our stack)
You're absolutely correct that for a completely uncached image, there are more "hops" involved to serve an image. For the first user to view an image, this can result in a slightly increased latency. After that, however, the image is cached by both our rendering cluster and global CDN, which makes subsequent requests for any image based off of the original much faster. Either way, the byte savings from serving correctly-sized images to the browser will almost always outweigh any additional latency from initial requests for an image.
Here's a simple diagram that shows the flow when an image has not yet been cached:
┌─────────────────┐ 4. Origin responds
│ Your Origin │ with full-size
│ (S3/web folder) │ `dogs.png` image.
└─────────────────┘
▲ │
│ │
│ │
│ ▼
3. Image is not ┌─────────────────┐ 5. imgix caches the
cached at imgix, send │ imgix │ full-size image, then
request to origin for │ │ resizes it to 300px
`dogs.png` └─────────────────┘ wide and caches that
▲ │ derivative.
│ │
│ ▼
2. Image is not ┌─────────────────┐ 6. The imgix CDN
cached at CDN, │ imgix CDN (edge │ caches the 300px wide
forward to imgix │nodes worldwide) │ variant and serves it
rendering cluster. └─────────────────┘ to the browser.
▲ │
│ │
│ │
│ ▼
1. Browser requests ┌─────────────────┐ 7. The browser
`dogs.png?w=300` │ User's Browser │ receives and renders
│ │ 300px wide `dogs.png`.
└─────────────────┘
Once the image has been cached (after a single user requests it), the loop becomes much tighter:
2. The imgix CDN has ┌─────────────────┐
this variant cached, │ imgix CDN (edge │
and serves it to the │nodes worldwide) │
browser. └─────────────────┘
▲ │
│ │
│ │
│ ▼
1. Browser requests ┌─────────────────┐ 3. The browser
`dogs.png?w=300` │ User's Browser │ receives and renders
│ │ 300px wide `dogs.png`.
└─────────────────┘
After an original image is cached at our rendering cluster, generating derivatives is also much faster (in this case, a 600px wide version), since they don't require an additional trip to your origin server:
3. Full-size image is ┌─────────────────┐ 4. imgix resizes the
already cached at │ imgix │ cached full-size image
imgix, no origin │ │ to 600px wide and
request needed. └─────────────────┘ caches that
▲ │ derivative.
│ │
│ ▼
2. Image is not ┌─────────────────┐ 5. The imgix CDN
cached at CDN, │ imgix CDN (edge │ caches the 600px wide
forward to imgix │nodes worldwide) │ variant and serves it
rendering cluster. └─────────────────┘ to the browser.
▲ │
│ │
│ │
│ ▼
1. Browser requests ┌─────────────────┐ 6. The browser
`dogs.png?w=600` │ User's Browser │ receives and renders
│ │ 600px wide `dogs.png`.
└─────────────────┘