img-min

Responsive and lazy image web-component

This is a demo page for <img-min> web-component. It is a vanilla web-component / custom element with no dependencies.

Check it out on GitHub.

The hero image above varies between 17kb (iPhone 5/SE size) to 222kb (1400px MacBook Pro) to have a "good" visual impression.

<img-min> is intended to be a replacement for the <img> tag to automatically request images with optimal size/quality ratio in respect to every client. This can save clients easily hundreds or thousands of KB.

<img-min> plays best with a CDN backed image resize/reformat microservice. It comes with a freely hosted implementation for demos.

Features

Usage

<script
  src="https://unpkg.com/@lipp/img-min@0.0.6/dist/index.min.js"
  >
</script>

<img-min
  src="https://images.unsplash.com/..."
  alt="Hero"
  style="--aspect-ratio: 15/10"
  >
</img-min>

It is used very similar to the good old <img> tag.

A src attribute to the "big" original image must be specified.

The CSS variable (custom property) --aspect-ratio is recommended to prevent page layout jumping and to leverage visibility checking and thus lazy loading. Every other means to make the image have a certain height is also ok.

You can play with a dup of this page on codepen.io.

Image CDNs

To use <img-min> a CDN backed image resize/reformat microservice is required. There are many of these services out there and all of them should be compatible. Their job is to deliver resized / reformated images as fast as possible to the client.

To name a few:

When an image (placeholder) gets visible, a hook is called with detailed information supposed to return a URL for this image.

window.ImgMin.getCDNUrl = ({
  url, // original image url (high res)
  width, // width on screen 
  height, // height on screen
  quality, // quality [0..100]
  format // jpeg|webp
    }) => {
  // return url to microservice / image CDN
}

cloudimg.io offers a free plan, which is awesome! WebP is not supported so the hook looks like this:

window.ImgMin.getCDNUrl = ({url, width, quality}) => {
  return `https://atzvkhhlen.cloudimg.io/width/${Math.floor(60/quality * width)}/n/${url}`
}

This is all code you need to use your custom CDN. This is also the spot where you can implement image quality strategies. One can even think about guessing connection speed and reduce image quality under certain conditions.

To build this demo, I created my own CDN backed image microservice, img-scale. With the help of Zeit's now in less than 5o lines of code. It is the default method and free to use until I get chopped by Zeit.co ;) .

Feedback welcomed

This implementation is still very basic and I guess people would like to have more customization options and other features or changes in API. Your precious feedback is very welcomed, just create an issue.

Why

Page size is important for many respects and will probably stay important forever. Images often times make up the biggest part of a website's data delivered to the client. This article focuses on methods to deliver images in sizes and formats which are best for each client based on its viewport (screensize).

Delivering minimal images isn't trivial. This usually involves uploading and serving them in different sizes over a CDN and writing media queries for certain breakpoints. As developer and/or content contributor it can be easy to forget to do all the steps required.

Further, different clients might support different images formats. WebP for instance offers "better" compression but is not supported by all browsers. This can multiply the effort.

Things get more complicated when RWD layouts causes images to get displayed larger on smaller devices. The images below get stacked on smaller devices and might actually require a bigger image to look crisp. Handling this with media queries can get messy.

Browser Support

The basic requirement for <img-min> is support for web-components aka custom elements. Checkout support on caniuse.com. At the time of this writing the working major browsers are:

The only big missing is Edge.

Some more images

Scroll and watch images get lazy loaded.

Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.

There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.

Me

Follow me :)