homesharepublicmail
arrow_upward
{{platform}}
jam-platform.devsymbiotejs.org
mail[email protected]send@rnd_pro_chat
RND-PRO.com

Web Images: Problems and Solutions

CIT (Cloud Images Toolkit) dashboard screenshot

Not as Easy as It Seems

So, images on the internet: what could be simpler? We see them every day, download them, upload them, share them with friends... We have become so accustomed to images being an integral part of the web that the very act of them appearing on our screens seems exceedingly simple, requiring neither special knowledge nor complex technology. But is that really the case? Let's delve into it.

Imagine we’ve taken a picture of our beloved cat using a smartphone camera and we want to post it on our webpage. To insert the image into a web document, we use the HTML <img> tag. This tag has a src attribute, where we specify the address of our photo. In its simplest form, this would be some relative path, and we would upload the image to our server along with the webpage file itself. Our HTML code might look something like this:

<img src="./images/cat.jpg">

Elementary! And it works. So what’s so difficult about this?

Let’s start by acknowledging that our image is of enormous size because we shot it with a modern camera boasting many megapixels. If such things don’t concern you, you may stop reading here, as practically all that follows will focus on optimization and adaptivity.

Why Optimization Is Necessary

We are compelled to consider optimization for three main reasons: 

  • Optimization affects your website's ranking in search engines.
  • Optimization, particularly loading speed, directly impacts user experience and the likelihood of a user leaving your page and whether they will return.
  • Costs associated with traffic, of course.

Resizing

If an image is large, it needs to be reduced. To what size? This depends on your page’s design. And if the design is responsive? Then, in a simple case, you would need to prepare two sizes: for mobile and desktop versions. We grab an image editor and create two smaller versions from one large image. It’s already not as simple as at the beginning, but still fairly straightforward. We rub our hands together and prepare to publish... Or not? Actually, our adventures are just beginning.

DPI

There are screens with varying pixel densities. Oh, the wonders of technology! Additionally, there are browsers that render "virtual pixels" to determine the sizes of elements. If the pixel dimensions of your image simply match the size of the container in these "virtual" pixels, then on a high-density screen, your image will appear "blurry," and this is evident to the naked eye. This means we need to prepare different versions of our cat photo for screens with various DPI. Ugh... This is already becoming tedious. Back to the editor... Are we really going to have to repeat all of this every time?

Format

Besides the image size, the format is also important. There are the good old compression formats like JPEG, as well as more modern ones that allow efficient compression with minimal quality loss, such as WEBPAVIF, or HEIC. Different browsers and operating systems may support different formats. Various codecs may use different resources for decompression. Which format should you choose? How do you find out which formats are supported by others' browsers? How do you determine what format is best suited for your original data? By this point, an unprepared person may start feeling overwhelmed.

CDN

And here it is, the first ray of light in this dark tunnel: specialized CDN services exist that can take a significant portion of the aforementioned problems off your hands! Moreover, they can cache your resources for more efficient access across different regions of the globe and can nearly completely relieve your server from managing this type of traffic. They also handle automatic resizing and format support detection. Dynamic transformation of images from the original can even occur for each individual request (with this, you should be cautious as each request with new parameters may incur costs). There are many such services, and I will not elaborate on their enumeration and description in this article.

What are the downsides? 

  • You will need to add another dependency, another paid service to your ecosystem.
  • Images must be loaded through a separate process, either via an external UI or through an API that needs to be studied and integrated.
  • Furthermore, you will have to set up custom URLs for your images, to ensure that the request addresses do not lead somewhere external to outside observers (this may incur additional charges).
  • Your image collection will be under the control of an external service.
  • Before inserting an image into your markup, you’ll need to upload it and obtain a unique identifier, only then can you publish it on your page.
  • Most commonly, the address of such images will be generic, containing an ID and basic parameters, but not the filename or any other element from which one could infer what exactly the image is.
  • More often than not, it will be difficult for you to sort and organize images into groups. You will have to find some way to save additional metadata using the CDN service or on your own.
  • For collaboration, you will need to share access and cope with the restrictions imposed by such services (some of them allow this only for an additional fee).

However, in my opinion, the advantages still outweigh the downsides.

Embedding Code

So, we have uploaded the photo to the CDN; it's time to sort out the embedding code. As you might have guessed, the code I presented at the start of the article is completely unsuitable because it does not take into account all the nuances regarding formats, sizes, and DPI.

Modern web standards present us with two main options for embedding that can satisfy our requirements:

  • The <img> tag with its attributes: srcset and sizes
  • The <picture> and <source> tags

Examples:

<img
  srcset="cat.jpg 480w, cat-800.jpg 800w"
  sizes="(max-width: 600px) 480px, 800px"
  src="cat-800.jpg"
  alt="My cat" />
<picture>
  <source media="(max-width: 799px)" srcset="cat-480.jpg" />
  <source media="(min-width: 800px)" srcset="cat-800.jpg" />
  <img src="cat-800.jpg" alt="My cat" />
</picture>

For more details on how this works, you can read on MDN.

I would like to point out another complexity: writing such code manually each time is quite the chore (and we are still looking at a significantly simplified example). Ideally, you should generate it automatically, for example, during the server-side build of your page. And here’s yet another task to add to your list.

Lazy Loading

Lazy loading images is another way to optimize the time required for the initial rendering of your page. With this approach, images start loading as needed, only when the user scrolls to the relevant part of the page. Fortunately, this can be easily accomplished using the loading attribute: 

<img loading="lazy" src="cat.jpg" alt="..." />

Another reference to MDN for details.

There’s also the decoding attribute: it instructs the browser that it can defer the decoding process of an already loaded image, prioritizing work with other elements on the page:

<img decoding="async" src="cat.jpg" alt="..." />

Git

Let me briefly outline my near-ideal setup for working with articles, documentation, and other similar web materials.

I write articles in the most suitable format for this purpose—Markdown. Additionally, I use custom tags to insert various widgets and dynamic, interactive elements anywhere within the page body. This is conveniently done directly in Markdown. The assembly of static assets and the publication of the results occur according to a configured GitHub Action when the main branch of the repository is updated. This is a fairly standard workflow nowadays: much more convenient and flexible than using any CMS. One of the important advantages is undoubtedly the ability to collaborate with colleagues and co-authors through Git.

However, it should be understood that storing and tracking image sources through Git is far from the best idea. For the purpose of synchronizing collections of images among collaborators, something like Dropbox comes to mind. However, Dropbox is not ideal, as it can fill your local disk with copies of many hundreds of megabytes without your active desire and necessity. Moreover, it doesn’t solve the issue of storing metadata—Git is quite effective for that.

Here are some ongoing questions:

  • How do we organize collaborative work with images?
  • How do we retrieve and store metadata?
  • How do we automatically generate embedding code based on data from uploaded images?
  • How do we synchronize the local folder structure within the file system with the flat data storage structure in the CDN?

Problem Solution

Our developer-friendly solution emerged while working on our internal infrastructure projects, and now, I would like to share it with the broader public.

Cloud Images Toolkit

CIT is a developer's workspace tool designed for managing graphic assets, which can be tied to a specific web project or operate independently. CIT requires Node.js to function. According to the settings, it monitors a specified local folder and automatically uploads images from it to the CDN. At the same time, data about the uploaded files and directory structure is saved in a local JSON file, which becomes available for automatic processing and collaborative work through Git.

CIT has its own UI for managing remote and local files and directories:

CIT (Cloud Images Toolkit) image files view screenshot

It supports folders even if your cloud storage don't:

CIT (Cloud Images Toolkit) folder view screenshot

CIT features a built-in editor for interactive widgets that utilize images:

CIT (Cloud Images Toolkit) IMS Editor screenshot

CIT is very easy to set up and use. The current version was developed for integration with Cloudflare Images, but, theoretically, it can be used with any other specialized CDN. In the future we will add support and presets for other services.

We plan to actively develop this project: adding features, improving documentation, and creating useful integrations.

CIT is released under the MIT license. You are free to use the project code as you wish, copy and adapt it for your needs, or contribute alongside us.

We would appreciate any feedback and stars on GitHub.

Project repository: https://github.com/rnd-pro/cloud-images-toolkit

17.12.2024

Interactive Media Spots

The set of interactive widgets to demonstrate almost everything
ecg_heart