Tips for avoiding flickering in a background image when it is being changed

Utilizing JavaScript, I am setting a repeated background image from a canvas to a div in the following way:

var img_canvas = document.createElement('canvas');

img_canvas.width = 16;

img_canvas.height = 16;

img_canvas.getContext('2d').drawImage(canvas, 0, 0, 16, 16);

var img = img_canvas.toDataURL("image/png");

document.querySelector('#div').style.backgroundImage = 'url(' + img + ')';

I need to update this frequently. Unfortunately, there is an issue with flickering when it changes; while Chrome doesn't show this problem, Firefox and Safari do. Despite using data URL, it still seems to happen.

Possible Solution:

// create a new Image object
var img_tag = new Image();

// apply the image to the div after preloading is complete
img_tag.onload = function() {

    document.querySelector('#div').style.backgroundImage = 'url(' + img + ')';
}

// starting preload by setting 'src'
img_tag.src = img;

Answer №1

To optimize the loading of images on your device, consider preloading the image resource into the device's storage by incorporating the image in the DOM as shown in the sample HTML code below. The error you are experiencing might be due to the time it takes for the image resource to load, causing flickering.

<img src="imageToPreload.png" style="display:none;" alt="" />

Another technique you can use is sprites-images. By utilizing sprites, your application will make fewer HTTP-Requests to load all resources onto the page. Additionally, include the following CSS styles when using css animations to prevent background flickering on mobile devices:

-webkit-backface-visibility: hidden;
-moz-backface-visibility:    hidden;
-ms-backface-visibility:     hidden;

Answer №2

Optimize your image loading process by using this method, eliminating the use of an <img> tag with display: none

<link rel="preload" href="/images/background.jpg" as="image">

Answer №3

Consider including the following CSS in your background component:

-webkit-backface-visibility: visible;
-moz-backface-visibility:    visible;
-ms-backface-visibility:     visible;

This adjustment may help alleviate any flickering issues.

To enhance hardware acceleration, you can implement the following code in your background component:

-webkit-transform: translate3d(0, 0, 0);

Alternatively, you could opt for using an image instead of a DIV and simply modify the image URL.

Answer №4

It took me some time to figure it out, experimenting with preloading and appending the image to the document.

Ultimately, I solved the issue by re-saving the JPEG without enabling the "Progressive" option.

After making this change, the rolling flicker when swapping the img src was completely resolved.

Answer №5

For me, I found success by switching from using height: 1080px; (for the background height) to height: fit-content;

Answer №6

It is crucial to preload all images in every situation. I have observed that different browsers behave differently when dynamically changing background images. For example, Firefox may flicker with frequent changes, while Chrome and Safari do not.

My current best solution involves drawing the image within a child canvas that fills the entire parent div.

In any scenario, optimizing the images used is important for optimal rendering performance.

Answer №7

Here is my functioning JavaScript code:

const imageOne = new Image();
const imageTwo = new Image();

imageOne.src = "../img/animation.gif";
imageTwo.src = "../img/still.png";

Even though I don't directly use this code in my query, I utilize the following:

document.querySelector(".btn_animation").addEventListener("mouseover", function() {
  myElement.style.backgroundImage = "url('../img/animation.gif')";

This implementation works well for me. If I try to replace the URL with a variable like `imageOne`, it doesn't behave as expected. Also, initializing and declaring the image objects at the same time helps prevent flickering.

Answer №8

Although not addressing all the specific details mentioned by the original poster, the following method may prove beneficial to others. This technique has been tested successfully in Chrome 97, Firefox 96, Android 11, and iOS 15.

The setup involves a div with certain CSS properties...

#div_image {
    background-image: url( [Path to low-res image] );
    background-size: cover;
}

In addition, there is a corresponding class defined as follows...

.div_image_highres {
    background-image: none !important;
}

This class includes a pseudo-element specified as such:

.div_image_highres::before {
    position: absolute;
    left: 0;
    top: 0;
    
    width: 100%;
    height: 100%;
    
    content: " ";
    
    background-image: url( [Path to highres image] );
    background-repeat: no-repeat;
    background-position: 50% 0;
    background-size: cover;
    
    opacity: 1;
    display: block;
}

Furthermore, an img element is utilized to reference the high-resolution image...

<img id="img_highres_preload" src=" [Path to high-res image ] ">

A corresponding styling for the img element allows it to be loaded (to ensure file loading) without being visible...

#img_highres_preload {
    width: 1px;
    height: 1px;
}

Two notes to consider: (1) Various methods exist for pre-loading images, but this particular approach is preferred. (2) Refer to the addendum regarding the reliability of the load event.

Lastly, a jQuery script handles the addition of the "high-res" class to the "div_image" once the high-resolution file is fully loaded...

$(document).ready(function() {
    $("#img_highres_preload").off().on("load", function() {
        $("#div_image").addClass("div_image_highres");
    });
});

While vanilla JavaScript can accomplish the same task, using jQuery ensures consistency across the codebase.


Summary of the Process:

  1. The low-resolution image loads first and serves as the initial background for the div. Even if this step doesn't happen, the procedure remains effective (i.e., showcasing the high-resolution image).
  2. Upon successful loading of the high-resolution image in the img element, triggering the addition of the "div_image_highres" class to "div_image".
  3. As a result, the transition to the high-resolution image occurs smoothly without any flashing effects. Occasionally, a slight shift might occur, but it's usually unnoticeable or non-disruptive.
  4. The primary reason behind adopting this method is for seamless transitions between multiple panels in the application, preventing flickering when hiding and displaying divs containing images.

Insights on the Load Event:

Relying solely on the load event can be problematic, especially in scenarios where images are cached by the browser. To address this issue, a modification is made to the document.ready event to incorporate additional checks:

$(document).ready(function() {
    positionOnPage(true);
    
    $("#img_highres_preload").off().on("load", function() {
        checkImage();
    });
});

checkImage = function() {
    var image = $("#img_highres_preload")[0];
    
    if (!image.complete || (typeof image.naturalWidth != "undefined" && image.naturalWidth == 0)) {
        console.log("Waiting for high-res image.");
    }
    else if (!$("#div_home").hasClass("div_home_highres")) {
        $("#div_home").addClass("div_home_highres");
        $("#img_highres_preload").remove();
    }
}

By implementing the checkImage function, the script verifies the image status before applying changes. While this particular example might seem redundant given the initial image loading confirmation, it ensures robust handling of potential loading irregularities.

For more dynamic scenarios, checkImage could be invoked based on different triggers within the codebase, allowing for comprehensive image validation prior to display.

Keep in mind that this simplified version suits basic needs like transitioning from low-res to high-res images, while a more advanced implementation would cater to multi-image loading requirements at the outset.

Answer №9

Hello everyone! I understand that this question may have been asked before, but if you are still experiencing flickering on your website, a quick solution is to place the final version behind your background div. This will eliminate any flickering seen through the current image, providing a smoother display.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to modify the colors of a box and text when hovering over it?

I am currently working on a styled subscribe button and have encountered an issue. I want the background color of the entire box to change, along with the text color, when hovering anywhere on the box. However, my current code only changes the text color w ...

What steps are involved in a server utilizing Next.js to create a complete document for transmission to the client?

Understanding Next.js has been quite challenging for me. I am struggling to grasp how it operates on the server and how the server is able to implement server side rendering with the files generated by Next.js during the build process. I have a good under ...

JavaScript file creation and opening issue in Firefox

Check out my code snippet below: var blob = new Blob([data], { type: 'text/plain' }); var downloadLink = angular.element('<a></a>'); downloadLink.attr('href', window.URL.createObjectURL(blob)); downloadLink.attr ...

Numerous Axios GET calls made by various components

I am facing an issue where I have two different components rendering on the main screen. Both of them make multiple axios.get requests to fetch data. However, upon initial page load, only the last component successfully retrieves the data while the first c ...

Is utilizing React's useEffect hook along with creating your own asynchronous function to fetch data the best approach

After attempting to craft a function for retrieving data from the server, I successfully made it work. However, I am uncertain if this is the correct approach. I utilized a function component to fetch data, incorporating useState, useEffect, and Async/Awa ...

Ways to delete a class if it currently exists?

Is there a way to manage multiple toggle classes within a single div? It can be frustrating when clicking the maximize or close button triggers the minimize function as well. How can this situation be addressed? Is there a way to manage multiple toggle cl ...

The attempted JavaScript socket emissions from the server to the client for listening are currently experiencing difficulties and

I have encountered a peculiar issue with my code. It involves emitting from the server side and listening on the client side. The connection seems to persist indefinitely, even when the client refreshes or exits the page. However, the code on the client si ...

Performing a MongoDB query in a controller using the MEAN stack with Node.js

My goal with this controller is to retrieve all the results of a collection. Despite having one item in the prop collection, I am encountering an undefined error. Error: Cannot call method 'find' of undefined This snippet shows my server.js fil ...

Combine and blur multiple background images using CSS blending techniques

I am currently working on a website, which is just a demo built in ReactJS: The issue I'm facing is related to the background. The idea behind the app is simple - it consists of 4 parts, with the top part displaying weather information without a bac ...

Calculate the duration in seconds using the console

Is it possible to display the time of an action in seconds instead of milliseconds using console.time? Below is my code: console.log('start load cache'); console.time('cache load ok executed in') // loading from mongo console.timeEnd( ...

Updating controller variables when the route changes in AngularJS

I'm new to the AngularJS scene and I've encountered a challenge. My goal is to have the selected tab change dynamically based on the URL changes. Here's my JavaScript code: app.config(function($routeProvider, $locationProvider){ $rou ...

Utilizing async/await in React Redux for geolocation functionality

While attempting to retrieve the lng and lat by using geolocation with async and await, I encountered a situation where the promise was not awaited before it was passed to the reducer. Instead, another promise was returned. I had hoped that by using await ...

What is the best way to display two radio buttons side by side in HTML?

Looking at my HTML form in this JSFiddle link, you'll see that when the PROCESS button is clicked, a form with two radio buttons appears. Currently, they are displayed vertically, with the female radio button appearing below the male radio button. I& ...

Problem Installing Express Sharp using Docker

When deploying via Docker, I encountered an error with sharp, even though it works fine on my workspace. I followed all the steps but still faced issues. Error: 'linux-x64' binaries cannot be used on the 'linuxmusl-x64' platform. P ...

Error encountered: X.setValue is not a valid function and cannot be used to set the value. However, manually inputting the value as a

When I try to use the line sseTopicString.setValue(sseValueNumber), a Type error is thrown: Uncaught TypeError: sseTopicString.setValue is not a function. Interestingly, if I output the value (string) of sseTopicString before the dot, everything works fin ...

Sending variable boolean values to a VueJS component

How can I assign dynamic properties to a VueJS Component using VuetifyJS? Below is an example of VuetifyJS code that constructs a select field element: <div id="app"> <v-app id="inspire" style="padding: 10px; "> ...

Initiate the Bull Queue Process upon launching the Application

As I develop my API, I am setting up a queue and adding jobs to it. Additionally, I have configured the API to start processing these jobs as soon as they are added. const newQueue = createQueue(queueName, opts); newQueue.add('JokesJob', data, o ...

Converting a JS string into HTML markup

I recently developed a basic web application to manage telnet connections with routers using Node.js, Express, and WebSockets. After establishing a connection, the terminal stream is transmitted through a websocket as UTF-8 strings. However, my current is ...

jquery plugin causing issues with bootstrap button functionality

Currently, I am utilizing the jQuery form plug-in to post my form in an Ajax way. The post function is functioning perfectly with the default button. However, it seems to encounter issues when I try to use a custom Bootstrap button as shown below. Could so ...

Retrieving an Instance of Google Maps Object with the Help of JQuery

I'm currently working on a script that, when executed, will retrieve an instance of a Google Maps object from the webpage using JQuery. For example, if there is a map present on the page, it will be structured like this: <div class="map">....& ...