Skip to content

Instantly share code, notes, and snippets.

@stramel
Last active February 12, 2019 04:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stramel/482554f1847a60b17a9c57a9abb9712b to your computer and use it in GitHub Desktop.
Save stramel/482554f1847a60b17a9c57a9abb9712b to your computer and use it in GitHub Desktop.
(WIP) Ideal Image (Maybe Video) Component

Ideal Image Component

Features

  • "Modern Browser" compliant (no IE)
  • A11y
  • Lazy-loading
  • Placeholder
    • LQIP (
    • SQIP
  • Responsive
  • "Adaptive"
    • Use progressive image formats (ie. WebP) if available
    • Handle "slow networks"
    • Ability to "cancel" a download
    • Use async decoding (decoding attribute??)
  • SSR/pre-rendering
    • Handle users without javascript
  • Customization
    • Icons
    • Text/i18n/i10n
    • Theme/Styling
  • Additional UX, nice-to-haves
    • Network error
    • 404 error
    • Offline
    • Hooks

Details

Modern Browser Compliant

Requires X feature-set and Y Browser are compliant

The Breakdown

How to keep the component small and progressive

Resources

@stramel
Copy link
Author

stramel commented Feb 12, 2019

Features

Minimal

Based on latest ES2018 standards, Webcomponents (extends HTMLElement), extensible using mixins

Lazy-Loading

<lazy-image lazyload src="my-image.jpg"></lazy-image>

This comes built into Modern Browsers and shipping a separate polyfill will allow us to reduce bloat.

NOTE: Detect if lazyload is supported with 'lazyload' in new Image()
NOTE: If lazyload attribute is not supported, ability to pull in polyfill for it to support it. Extract into a separate file using IntersectionObserver.
NOTE: Requires IntersectionObserver support as well, possibly need to polyfill that prior to the lazyload attribute support polyfill

QUESTION: How can a user manually trigger lazy-loading
QUESTION: Should we create a declarative IntersectionObserver that we can wrap the image in?

Placeholder

<lazy-image src="giant-image.png" placeholder={lqip}></lazy-image>

Removes dead space of loading image. LQIP/SQIP are techniques that work. Any string should be allowed in this field

NOTE: Using lqip, sqip, lqip.macro, or sqip.macro would be able to be passed through the placeholder.

QUESTION: Do I need to pass it through as an object or can I just pass it directly? (Double-check API)
QUESTION: Should we show some kind of loader if no placeholder is passed?

Responsive

<lazy-image>
  <source 
    media="(min-width: 650px)"
    srcset="images/kitten-stretching.png" />
  <source 
    media="(min-width: 465px)"
    srcset="images/kitten-sitting.png" />
</lazy-image>

Allows for source tags to be slotted for responsive support.

NOTE: All qwirks that would apply to the picture and source tags would apply here.

QUESTION: Should we offer a component without this option that is just a basic img tag, instead of the picture tag?
QUESTION: How should we handle the default img tag if no src is supplied?

Adaptive

Progressive Image Format support

<lazy-image>
  <source 
    media="(min-width: 650px)"
    srcset="images/kitten-stretching.webp"
    type="image/webp" />
  <source 
    media="(min-width: 650px)"
    srcset="images/kitten-stretching.png" />
</lazy-image>

Using the native type attribute on source should allow for experimental image types to be used if the UA supports it.

Slow Networks

<lazy-image src="giant-image.png" placeholder="fallback-image.jpg"></lazy-image>

or

<lazy-image src="giant-image.png" placeholder="fallback-image.jpg" threshold="1000"></lazy-image>

Read the navigator.connection.dataSaver, navigator.connection.effectiveType. Default to !== '4g' fallback. Allow manual threshold of a number (ms) or string (effectiveType).

If "slow-network" is detected,

  1. Emit event to prevent other
  2. Cancel the load, if still loading
  3. Show control for manually loading (Click to load)

Allow a slotted "click to load" icon for configurability.

NOTE: Cancelling of the iamge will be handled via the Image variable. Setting Image.src to something different or '' will cancel the previous request.

Offline Network

Should be similar to slow networks and check navigator.onLine.

SSR

<noscript>
  <lazy-image></lazy-image>
</noscript>

QUESTION: How do we handle this? / Should we handle this?
QUESTION: Would it make sense to make this more of a decorator for the picture/img tags to allow better SSR handling?

Configurability

Icons

<lazy-image>
  <iron-icon icon="error" slot="network-error"></iron-icon>
</lazy-image>

Expose configurability of the icons through named slots. "network error", "404", "offline", "click to load" all will have named slots.

i18n

/shrug

QUESTION: Should we expose a getMessages function that gets the state and does something with it?

Themeing

Make use of the ::part / ::theme API

QUESTION: Will this cover everything?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment