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

What is the secret to remaining on the same spot even after the page is reloaded?

How can I maintain the AJAX call data after a page reload? I have attempted to use code that reloads the entire page, but I would like to stay in the same location. Is there a way to achieve this without reloading the entire page? $('#updateAddressPr ...

React event handling

Currently, I am in the process of developing an accordion app using React. The data for this app is fetched from an API, and while I have the basic structure of the app ready, I am facing some difficulties with handling the click event on the accordion. H ...

Create a custom countdown using Jquery and Javascript that integrates with MySQL and PHP to display the datetime in the format Y-m-d

Hey there, I'm looking to create a countdown script using dates in the format (Y-m-d H:m:s). The goal is to retrieve the current_datetime and expire_datetime in this format and incorporate them into some JavaScript or jQuery plugin to display a countd ...

I need to generate table rows using v-for and include a unique value in the 'id' attribute of each row

I am creating table rows dynamically in a view using Flask data. <tr id="<% file.id %>" v-for="file in fileList"> <td><img class="thumbnail_preview" src=""></td> <td><% file.filename %></td> <td> ...

Is there a way to retrieve information from a different object?

Access the code on Plunker I am working with two data structures - ingredients and recipes [{ "id":"1", "name": "Cucumber" }, .. ] and [{ "id":"1", "name": "Salad1", "recipein":[1, 3, 5] }, { ... } ] My goal is to ...

The versatility of reusable Backbone components

As I search for the best way to ensure the reusability of Backbone views, I have come across various solutions but am unsure which one would best meet my needs. My goal is to create multiple widgets populated with real-time data and I require a base compon ...

Clicking does not trigger scrollIntoView to work properly

I'm facing an issue with a button that is supposed to scroll the page down to a specific div when clicked. I implemented a scrollIntoView function in JavaScript and attached it to the button using onClick. Although the onClick event is functioning as ...

How can external webpages be effectively integrated under a banner for a cohesive user experience?

Google Images serves as a prime example. Upon clicking on an image, a persistent frame appears at the top of the page, prompting users to easily navigate back to Google. Is there a specific term for this method and what would be the most effective approach ...

Transforming all numbers to a consistent scale with the help of Numeral JS

Is there a way to customize the output of the numeral.js function so that it always returns numbers in thousands? For example, converting 1000000 to 1000k and 100 to 0.1k. console.log( numeral(1000000).format('0a') ); <script src="https ...

What is the best way to eliminate the unattractive white border surrounding dialog boxes?

Is there a way to remove the unsightly white outline around the UI Dialog? Check out this picture of the dialog I've tried various solutions I found on Google and Stack Overflow, such as: .ui-widget-content { border: none !important; outlin ...

Error encountered when mapping through images in Next.js with TypeScript due to a missing mandatory 'src' property

Issue: I am encountering an issue where the string entries from an array of objects are displayed correctly, but the images in the Image Component do not load dynamically in the src. The images are imported in the constants.js file and exported via the &a ...

Animate the transition effect as soon as the block is displayed

Looking to create a smooth page transition using CSS changes with the help of Javascript (jQuery). Initially, one of the pages is set to display none. page1 = $('.page1'); page2 = $('.page2'); page1.removeClass('animate').cs ...

When the open button is clicked, the Div will toggle between open and closed states

Recently, some of my questions have not been well-received, which makes me feel a bit disheartened. It's important to remember to be kind when providing feedback. I've noticed that some people downvote without offering constructive criticism, whi ...

Beautify JSON data display

My JSON object is displaying differently when I alert it: https://i.stack.imgur.com/lwNIJ.png I would like it to show like this instead: https://i.stack.imgur.com/cVakX.png function getEmployeeNameById(id){ return staffArray.find(item => item. ...

What is the best way to transfer data from one function to another file in React without directly calling the component or using props?

filename - Header.jsx import { useEffect, useState } from 'react' import { getValue } from './Input' import TextField from '@mui/material/TextField'; export const Header = () => { const [search, setSearch] = useState( ...

Inquiry about how TypeScript handles object property references when passed into functions

As a newcomer to TypeScript, I am exploring the creation of a range slider with dual handles using D3.js. I have developed a simple class for managing the slider objects: export class VerticalRangeSlider{ private sliderContainer: d3.Selection<SVGG ...

Is there a way to modify a document without altering its original location?

I attempted to load an entire page using ajax, with the doctype and html tags removed. However, when I tried setting it with the following code: document.documentElement.innerHTML=xmlhttp.responseText; Google Chrome returned an error message: An invalid ...

Is there a way to incorporate the load page plugin specifically for JavaScript while ensuring that my PHP code is still functional?

Is there a way to implement the loading page plugin "PACE" for PHP code execution instead of just JavaScript? I am more comfortable with PHP, CSS, and HTML, but not very experienced in JavaScript/AJAX. The PACE plugin is designed to show a progress bar fo ...

The Google Pie chart is displaying outside of the designated div area when placed inside a dropdown menu

Encountering an issue with my pie chart rendering outside of its parent div when placed within a dropdown menu. The chart successfully loads after the page is loaded, but only displays correctly if I hover over the dropdown and allow it to load. If I do ...

Is it advisable to include cursor:pointer in the pseudo class :hover?

Which option is better to use? .myclass { cursor: pointer; } or .myclass:hover { cursor: pointer; } Is there a notable difference between the two? ...