optimize image downloading

revision:


Content

key optimization strategies programming strategies lazy-load or eager-load? preload images?

key optimization strategies

Top

Six key strategies that can be used to optimize image files, reduce page load time and improve the user experience:

1. choose the right file format

The most common file types are:

PNG : produces high-quality images, but also increases file size. PNG is lossless, but you can also configure it to enable lossy compression.
JPEG : the quality and file size can be balanced by adjusting the JPEG quality level, between 1-100%.
GIF : supports only 256 colors, and provides lossless compression. Rarely used for static images, but increasingly popular for animations.

Lossy and lossless are considered as compression techniques. Lossy compression is a process that removes some of the image data. While this significantly reduces the file size, it also lowers the image quality. Lossless compression only takes away non-essential metadata. It only slightly reduces the file size, but it preserves the image quality.

2. use progressive JPEG and next-gen file formats

JPEG images have two rendering modes:

Baseline loading : displaying the image with full quality, from top to bottom. This can be problematic for users with slow connections.
Progressive loading: initially showing a low quality image, and then increasing quality gradually as more of the image is loaded.

Using progressive JPEG in a website or app can greatly improve the user experience for users with slow Internet connections.

Next-generation image formats - such as WebP and JPEG-XR - can create large savings in file size with advanced compression, without hurting image quality. They are recommended for use by Google's website optimization guidelines, and are therefore also important for search engine optimization (SEO).

The issue with next-gen formats is that they are not supported by all browsers, and so it is necessary to prepare a fallback image (such as PNG), and display it instead if the user's browser does not support the new format.

3. caching

Caching is a technique employed for the purpose of serving content quickly, by storing the image files in a proxy server or a browser cache. Browser-side caching can help reduce application requests and the download side of each cached page.

Caching image files in a proxy server requires setting up storage for images on several point of presence (PoP) servers, which are distributed throughout the world. Images are then served from the closest server, which significantly speeds up page loading times.
Page load times can also be reduced by using an image caching service, which creates cached tiles for images. To improve performance and loading speed, an image caching service preprocesses an image before it is cached. You can do this for static images like backgrounds and low-performance formats.

4. compression

Compression techniques are employed for the purpose of reducing the size of an image. There are two common compression types:

Lossy compression: reduces file size by removing data redundancies. This type of compression can cut down image file size, but also degrades quality. Once a file is compressed, you cannot recover the eliminated data. To prevent loss of data, you should always keep a master copy with the highest possible quality.
Lossless compression: prioritizes quality over file size. This technique maintains a high quality, which enables you to later restore the file as needed. However, you cannot use this technique to significantly reduce file size.

4. resizing

Size and resolution need to be balanced: the higher the resolution, the larger the file size. On the web, using high-resolution images slows down page load, while access via a mobile phone limits the bandwidth. The best practice is to find a balance between quality and file size. Resize the image to the smallest size that will still provide the required visual effect. Also, if you must display large high resolution images, show a thumbnail and only load the full image when a user requests it.

5. optimizing image delivery

Server speed and network performance are also important factors affecting how fast images load for your users.

Plan for traffic spikes and make sure your image server can handle three to four times normal traffic load. Always provide images with an appropriate cache header so local devices can use a cached version of the image.
Use a content delivery network (CDN) that can deliver your images to users from close proximity to their physical location. The closer the server is, the faster the response time. CDNs are now widely available and easy to implement, and are a great solution for improving image performance.


programming strategies

top

1. general strategies

code splitting: JavaScript, CSS and HTML can be split into smaller chunks. This enables sending the minimal code required to provide value upfront, improving page-load times. The rest can be loaded on demand.

As an application grows in complexity or is maintained, CSS and JavaScripts files or bundles grow in byte size, especially as the number and size of included third-party libraries increases. To prevent the requirement of downloading ginormous files, scripts can be split into multiple smaller files. Then features required at page load can be downloaded immediately with additional scripts being lazy loaded after the page or application is interactive, thus improving performance. While the total amount of code is the same (and perhaps even a few bytes larger), the amount of code needed during initial load can be reduced.

entry point splitting: separates code by entry point(s) in the app.
dynamic splitting: separates code where dynamic import() statements are used.

2. JavaScript strategies

Script type module: any script tag with type="module" is treated as a JavaScript module and is deferred by default.

3. CSS strategies

By default, CSS is treated as a render blocking resource, so the browser won't render any processed content until the CSSOM is constructed. CSS must be thin, delivered as quickly as possible, and the usage media types and queries are advised to unblock rendering.

code:
            <link href="style.css" rel="stylesheet" media="all" />
            <link href="portrait.css" rel="stylesheet" media="(orientation:portrait)" />
            <link href="print.css" rel="stylesheet" media="print" />
        

4. Images and iframes

Webpages may contain many images that contribute to data-usage and how fast a page can load. Most of those images are off-screen (non-critical), requiring a user interaction, like scrolling, in order to view them.

The Loading attributeon an <img> element (or the loading attribute on an <iframe>) can be used to instruct the browser to defer loading of images/iframes that are off-screen until the user scrolls near them.

code:
        <img src="image.jpg" alt="..." loading="lazy" />
        <iframe src="video-player.html" title="..." loading="lazy"></iframe>
    

lazy-load or eager-load?

top

The img loading attribute handles how an image will be loaded on a webpage. It accepts three string values : auto, eager and lazy.

lazy loading attribute: this strategy is used to identify resources as non-critical and the resources will be loaded only when needed. Lazy loading defers the loading of the webpage content as long as if they were not required. This technique helps to optimize the page by allowing images to load later. Usually, the image size is large on the webpage. For this, lazy loading can be useful to defer the offscreen images.

The loading attribute specifies whether a browser should load an image immediately or to defer loading of off-screen images until for example the user scrolls near them. Add loading="lazy" only to images which are positioned below the fold.

Syntax:<img src="url" loading="auto|eager|lazy">

Attribute Values:

auto: default lazy-loading behavior of the browser, in which the browser will determine for the lazy load of contents.
eager: the image that corresponds to it will load without any delay. It will load the resources immediately, regardless of where it's located on the page.
lazy: it delays the loading of the image that corresponds to it until the browser specifies that it is expected to appear shortly. It can help in optimizing the loading time of a webpage, by postponing the loading of images until and unless they are expected to appear, instead of loading them at once.

examples

Lazy Loading Attribute

NY python dbms meh
code:
                <style>
                    .first{display: flex; flex-flow: row nowrap;}
                    img {height: 7vw; width: 7vw; display: block; margin: 1vw;}
                </style>
                <div class=first-spec>
                    <h4>Lazy Loading Attribute</h4>
                    <div class="first spec">
                        <img src="../images/foto-fieldset.jpg" loading="lazy" alt="NY"/>
                        <img src="../images/Python.png" loading="lazy" alt="python"/>
                        <img src="../images/dbms.png"loading="lazy" alt="dbms"/>
                        <img src="../images/meh.png" loading="lazy" alt="meh"/>
                    </div>     
                </div>
            

examples

Lazy Loading Attribute

NY python dbms meh
code:
                <style>
                    .second{display: flex; flex-flow: row nowrap;}
                    img {height: 10vw; width: 10vw; display: block; margin: 1vw;}
                </style>
                <div>
                    <h4>Lazy Loading Attribute</h4>
                    <div class="second spec">
                        <img src="../images/foto-fieldset.jpg" loading="auto" alt="NY"/>
                        <img src="../images/Python.png" loading="auto" alt="python"/>
                        <img src="../images/dbms.png"loading="eager" alt="dbms"/>
                        <img src="../images/meh.png" loading="eager" alt="meh"/>
                    </div>     
                </div>
            


preload images?

top

Preloading images will avoid delays in image loading on hover. Also, some large images might take a while to load. It is therefore better to preload them for a better user experience.

1. preloading images using HTML

The link tag in HTML is usedy to load an external CSS stylesheet but it can also be used to load other type of resources as well. There are two important attributes of the link tag:

The href attribute, which is used to provide the path to the resource that we want to fetch;
The rel attribute, which specifies the relationship of the resource with the containing document. The "rel attribute" can take a lot of valid values. One of them is preload, which can be used to preload images. The preload attribute tells the browser to preemptively fetch and cache the linked resource as it will be needed on the current page.

The as attribute is also needed when the value of the "rel attribute" is set to preload. This will specify the type of content that is being loaded by the link tag. This attribute serves many important purposes such as applying the correct content security policy, prioritization of the request etc. Skipping it could prevent the image from being preloaded.

examples
code:
                <head><link rel="preload" as="image" href="../images/flowers.jpg" /></head>
                <div class="hover-me"></div>
                <style>
                    div.hover-me { width: 30vw; height: 30vw;background: url("../images/vangogh.jpg"); 
                    background-size: cover; cursor: pointer; margin: 0 auto; position: relative;}
                    div.hover-me::before { content: "Van Gogh"; background: black; color: white; 
                    position: absolute; top: 0.75vw; left: 1vw; padding: 0.5vw;  font-size: 1.5vw; 
                    border-radius: 0.5vw;}
                    div.hover-me:hover {background: url("../images/flowers.jpg"); background-size: cover;}
                    div.hover-me:hover::before {content: "Flowers";}
                </style>
            

2. preloading images using CSS

The browser cam also download images by setting the image URL as a value of the content property.

The body element along with the ::before or ::after pseudo-elements can be used for this. The URLs to be downloaded will be set as a value of the content property of any of the pseudo-elements.
It is important to keep in mind that the pseudo-elements need to be pushed far off the screen to prevent their contents from accidentally appearing on the screen. The following CSS takes care of all this:

code:
        <style>
            body::before {content: url("flowers.jpg"); position: absolute; top: -9999vw; left: -9999vw; opacity: 0;}
        </style>
    
examples
code:
                <div class="hover-it"></div>
                <style>
                    body::before {content: url("../images/flowers.jpg"); position: absolute; top: -9999vw; left: -9999vw; opacity: 0;} 
                    div.hover-it{width: 30vw; height: 36vw; background: url("../images/img_pink_flowers.jpg"); background-size: cover; 
                    cursor: pointer; margin: 0 auto; position: relative;}
                    div.hover-it::before {content: "Pink flowers"; background: black; color: white; position: absolute; top: 0.75vw; 
                    left: 1vw; padding: 0.5vw; font-size: 1.5vw; border-radius: 0.5vw;}
                    div.hover-it:hover {background: url("../images/img_orange_flowers.jpg"); background-size: contain;}
                    div.hover-it:hover::before {content: "Orange flowers";}
                </style>
            

3. preloading images using JavaScript

Preloading images using JavaScript is more convenient in situations where you have to load a large number of images. However, it will only work if JavaScript execution isn't disabled in the browser.

The following function can help us preload any image in JavaScript.

code:        
        function preload_image(im_url) {
          let img = new Image();
          img.src = im_url;
        }
    

The function accepts the path to an image that should be preloaded as a parameter. Inside the function, the image constructor is used to create a new instance of HTMLImageElement. After creating the image element instance, the value of its "src property" to path of the image to be preloaded is set. All that's needed now is a call to the preload_image() function: preload_image("flowers.jpg");.

examples
code:
                <div class="hover-this"></div>
                <style>
                    div.hover-this{ width: 30vw; height: 30vw;background: url("../images/vangogh.jpg"); background-size: cover; 
                    cursor: pointer; margin: 0 auto; position: relative;}
                    div.hover-this::before { content: "Van Gogh"; background: black; color: white; position: absolute; top: 0.75vw; left: 1vw; 
                    padding: 0.5vw;  font-size: 1.5vw; border-radius: 0.5vw;}
                    div.hover-this:hover {background: url("../images/flowers.jpg"); background-size: cover;}
                    div.hover-this:hover::before {content: "Flowers";}
                </style>
                <script>
                    function preload_image(im_url) {
                        let img = new Image();
                        img.src = im_url;
                    }
                    preload_image("flowers.jpg");
                </script>