49

The problem is, on most sites on the web, there are background images. They take time to load. Ordinarily, it wouldn't be a problem if the images were optimized, and small enough. However, on some of my sites, the javascript files find their way to load before anything else on the page, even though they're in the footer! This creates a white "flash" before the background image loads. Why is my javascript loading first before anything else? I'm having this problem on many sites, and I see it everywhere. Here's the site I'm currently working on:

http://www.bridgecitymedical.com/wordpress/

Thanks!

tl;dr How can I defer loading of javascript on my websites so that the background image loads before anything else, thus preventing that white "flash" before the browser finishes downloading the image.

alt
  • 13,357
  • 19
  • 80
  • 120
  • This is an excellent question lacking a good answer. Why? Because it's a bug. Somewhere between the design of CSS and browsers, someone dropped the ball. It seems impossible to display or refresh a page in Firefox or Chrome without showing the background color as an erroneous background of each div having a background image until the background image has completely loaded. If it's a photo, that loading could easily take 90 msec or more. – David Spector Apr 16 '21 at 20:07

7 Answers7

59

Don't delay loading parts of your site - what if the background image were to have an error in transmission and never arrive? Your scripts would never load.

Instead, if you really dislike the "white" flash, set the background color of the document to a more pleasing color, more in line with your background image. You can do so in the same css style:

body {
    background: #EDEBED url(myGrayBackgroundImage.jpg);
}

It's simple, has virtually no cost, won't break, and won't delay things from downloading unnecessarily. It looks like you're already doing something like this - I wouldn't change it. I don't think anybody has the expectation that your site look a certain way before it loads.

Surreal Dreams
  • 26,055
  • 3
  • 46
  • 61
  • 3
    Thanks! I guess I don't really want a solution to my problem do I. – alt Sep 14 '11 at 07:01
  • 1
    I have the expectation that nothing on the screen should change once page loading starts. Sometime no solid color is similar to an image. There must be a way to preload background images perfectly, but hours of searching have not revealed it. This answer does not work for me in 2021, leaving a long flash of the specified color. Did it work for you in 2014? – David Spector Apr 16 '21 at 20:09
  • 1
    Page is already set to black, but reload still flashes white. – WilliamK Jul 04 '22 at 05:05
22

You may use something like this:

HTML

<!-- Add a class to flag when the page is fully loaded -->
<body onload="document.body.classList.add('loaded')">

CSS

/* Hide slider image until page is fully loaded*/
body:not(.loaded) #slider img {
  display:none;
}
Community
  • 1
  • 1
cvsguimaraes
  • 12,910
  • 9
  • 49
  • 73
  • 2
    Clever! Minor improvement: add a space in the appended className attribute. e.g. `document.body.className += ' load';` – jimbo Sep 14 '11 at 05:24
  • 1
    @jimbo why exactly? – Kris10an Apr 24 '19 at 16:59
  • 2
    @Kris10an Originally the my answer used `document.body.className += 'load';`, so if the body tag already had a `class="body-class"` the class would become "body-classload". Currently the more appropriate way to manipulate class names is through the [`classList`](https://developer.mozilla.org/en-US/docs/Web/API/Element/classList) token list. – cvsguimaraes Apr 25 '19 at 01:55
  • 1
    This kind of lunacy is one of the reasons why even many news websites and other content-focused websites, which should work fine without client-side scripting, no longer work without JS enabled. – jbg Nov 26 '19 at 19:38
4

I was having the same issue and found it pretty strange that this isn't talked about more. I still haven't found any documentation on this, but please comment if you find anything regarding RFC's for css background image loading priorities, etc.

Anyways, the only thing I found is that <img> load immediately while background-image() seems to load on dom ready.

So my solution was to place a <img> with display:none just before the <div> with the background image. This will load the image immediately and then it gets used immediately for the background-image.

<img src="my-image.jpg" style="display: none;" />
<div style="background-image: url('my-image.jpg');"></div>
  • One thing to note is that you could still get flickering on images that are not optimized. So for jpg's make sure to compress them and set the "progressive" attribute when creating them.
ggedde
  • 582
  • 5
  • 12
  • I don''t know when images are loaded. All I know is that this answer did not work for me. Here is my exact Bootstrap 5 code:
    – David Spector Apr 16 '21 at 19:59
1

I wanted to add something, in case of having a black background image set for the body. I was experimenting with transitions in between pages in the same site. I finally used this (neatly loads black-background from black, avoiding the flash yeah!):

html{
    background-color: black;
}

body{
    -webkit-animation: fadein 1.5s; //I use chrome
    background: linear-gradient( rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75) ), url('wall_pattern.jpg');
    color: white;
}
adr1Script
  • 109
  • 5
  • 3
    It doesn't matter what "you use". When doing web development, you should make it as cross browser compatible as possible. – carefulnow1 Mar 18 '17 at 20:24
0

So, while changing the background color does help it's important to note that the reason the page is not loading quickly is likely due to javascript being in the header. You can remedy this by putting your javascript tags

<script type="text/javascript" src="/path/to/js/javascript.js"></script>

in the footer of your pages so that it loads after the browser has already read the css and displayed most of the page. I realize this is an old post, but I happened upon it while thinking about this problem myself and realized (through remembering conversations and posts I'd seen before) that I had the js in my header.

Robert McMahan
  • 531
  • 5
  • 6
-1

If you change the render time it should stop people from getting flash banged by your page loading white.

Relykx
  • 1
-2

I would use a query string "?201611" on the image URL in css. This tells the browser which version of the image to load. So instead of checking for new version every time, it will load the version kept in cache. The flash effect will happens only the first time the website is visited.

ex. http://domain.com/100x100.jpg?201611

SequenceDigitale.com
  • 4,038
  • 1
  • 24
  • 23