Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to fix chrome flicker on iframe page reload

Chrome flickers when reloading content in iframes. Can this be avoided in any way, thinking of:

  • Wrapping a-links with js that does some magic.
  • Meta-tags in content-html. (I have source control over the html in the iframes)

Please note that the content-type in the iframe may vary (pdfs, html, images) so if ajax is the only way out here, does it reflect the http-content-type back to the iframe?

Please visit the demo at http://jsfiddle.net/2tEVr/

Excerpt of fiddle:

 <iframe name="if" width="800" height="600"></iframe>

UPDATE

The solution that worked best for me was to replace regular href's with ajax-requests, repopulating the body-area, (solution 4 below) Flickering is gone but comes at a price of akward debugging since sync between content and "view-source" is lost on ajax-request.

Also, since the content-type in my case may change, the method for performing the ajax-request had to have some brains and possibly fall back to regular location request.

regards,

like image 921
Teson Avatar asked Oct 09 '13 08:10

Teson


3 Answers

@user247245: From your question, its not entirely clear how you (want to) use the iframe. Does it reload periodically, or once when the whole webpage loads?

Solution 1: Different background color

In case you just want to avoid the ugly white, and avoid over-complication. Set a different background color in your HTML header of the framecontents.html file, like so:

<!DOCTYPE html>
<html style="background-color: #F48;">

This way, while the CSS file loads,parses, and gets applied, the background is not #fff.

Solution 2: Transparent iframe

While there is no content, the iframe should simply not be visible. Solution:

<iframe src="/framecontents.html" allowTransparency="true" background="transparent"></iframe>

Ofcourse dont use this in combination with solution 1, you'll shoot yourself in the foot.

Solution 3: Preload iframe page

In case you are loading the iframe later (such as user clicking a link), consider preloading its contents. Hide this in near the top of your (parent) page:

<iframe src="/framecontents.html" style="position: absolute; width: 0px; height: 0px"></iframe>

But i'd advise using solution 2 instead.

Solution 4: If doing a mobile web interface:

See how jQuery Mobile did it. We built a web interface that had to feel like a native app, so without reload flashes. jQM fixed that. Basically does a background ajax call to retrieve the full HTML contents, then extracts the body (the "page" div to be more precise) and then replaces the contents (with a transition if you like). All the while a reload spinner is shown.

All in all this feels like more like a mobile application: no reload flashes. Other solutions would be:

Solution 5: Use JS to inject CSS:

See answer by jmva, or http://css-tricks.com/prevent-white-flash-iframe/ .

Solution 6: use JS to inject CSS (simple version)

<script type="text/javascript">
  parent.document.getElementById("theframe").style.visibility = "hidden";
</script>
<iframe id="theframe" src="/framecontents.html"  onload="this.style.visibility='visible';"></iframe>

You could ofcourse leave out the <script> part and add style="visibility:hidden;" to the iframe, but the above would make sure that the frame is visible for visitors with JS disabled. Actually, i'd advise to do that because 99% of visitors has it enabled anyway, and its simpler and more effective.

like image 54
Barry Staes Avatar answered Oct 21 '22 05:10

Barry Staes


A common trick is to display the iframe just when it's full loaded but it's better to not rely on that.

<iframe src="..." style="visibility:hidden;" 
  onload="this.style.visibility='visible';"></iframe>

The same trick a bit optimized using JS.

// Prevent variables from being global      
(function () {

/*
      1. Inject CSS which makes iframe invisible
*/
var div = document.createElement('div'),
    ref = document.getElementsByTagName('base')[0] || 
          document.getElementsByTagName('script')[0];

div.innerHTML = '&shy;<style> iframe { visibility: hidden; } </style>';

ref.parentNode.insertBefore(div, ref);


/*
    2. When window loads, remove that CSS, 
       making iframe visible again
*/
window.onload = function() {
    div.parentNode.removeChild(div);
}

})();

Extracted from css-trick

If you have to switch between different sites and that trick of onload isn't working the only viable solution would be destroy and create the iframe programatically.

like image 2
jmventar Avatar answered Oct 21 '22 05:10

jmventar


Try adding transform: translate3d(0, 0, 0); on a parent element.

I had an issue where the iframe was taller than its parent (parent has overflow: hidden). The iframe's overflown portion was flickering on each video loop on Chrome (YouTube iframe API).

Forcing hardware acceleration this way was the only thing that worked for me.

like image 2
gedijedi Avatar answered Oct 21 '22 06:10

gedijedi