最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to load an iframe without blocking onload or waiting for onload - Stack Overflow

programmeradmin2浏览0评论

Suppose I have this page:

<h1>Hello, world!</h1>
<iframe src=".html"></iframe>

And test.html contains this:

<img src="huge.png" />

huge.png is 100mb for some reason.

I have no control over test.html, but I must include the iframe in my page.

Is there a way to load the iframe without

  1. blocking my page's onload event OR
  2. waiting until my page's onload event to set the iframe's src attribute

I want #1 because I don't want JS on my page to have to wait for example's slow image.

I want #2 because I want to start loading example's content ASAP.

There are two similar questions.

  • is there a way to load an iframe asynchronously
  • Javascript preload iframe without blocking the browser

This is why they aren't duplicates:

  1. Neither is clear what it means to "block" loading - I specify the onload event.
  2. Neither specifies that I don't have control over the iframe's contents (which the first answer on #2 assumes).
  3. Neither specifies that setting the src attribute after onload is not an option (which several answers on #1 assume).

While it's possible that answers to those questions could answer this one, neither is worded in such a way that the answer must answer this question.

Suppose I have this page:

<h1>Hello, world!</h1>
<iframe src="https://example.com/test.html"></iframe>

And test.html contains this:

<img src="huge.png" />

huge.png is 100mb for some reason.

I have no control over test.html, but I must include the iframe in my page.

Is there a way to load the iframe without

  1. blocking my page's onload event OR
  2. waiting until my page's onload event to set the iframe's src attribute

I want #1 because I don't want JS on my page to have to wait for example.com's slow image.

I want #2 because I want to start loading example.com's content ASAP.

There are two similar questions.

  • is there a way to load an iframe asynchronously
  • Javascript preload iframe without blocking the browser

This is why they aren't duplicates:

  1. Neither is clear what it means to "block" loading - I specify the onload event.
  2. Neither specifies that I don't have control over the iframe's contents (which the first answer on #2 assumes).
  3. Neither specifies that setting the src attribute after onload is not an option (which several answers on #1 assume).

While it's possible that answers to those questions could answer this one, neither is worded in such a way that the answer must answer this question.

Share Improve this question edited Apr 22, 2020 at 13:09 crenshaw-dev asked Dec 2, 2018 at 17:58 crenshaw-devcrenshaw-dev 8,3546 gold badges48 silver badges88 bronze badges 5
  • I don't want to wait until the load event to start loading their content. – crenshaw-dev Commented Dec 2, 2018 at 18:07
  • Then what is the higher level problem? – charlietfl Commented Dec 2, 2018 at 18:08
  • Their content blocking my page's onload event. – crenshaw-dev Commented Dec 2, 2018 at 18:10
  • 2 No way to do anything with a cross domain iframe. Could try using DomContentLoaded event instead – charlietfl Commented Dec 2, 2018 at 18:13
  • Ooh. Great interaction with existing questions, @MichaelCrenshaw! – Sam Hughes Commented Sep 29, 2021 at 19:07
Add a comment  | 

3 Answers 3

Reset to default 11 +250

You can use Window: DOMContentLoaded event as suggested by charlietfl in the comments; it does not get blocked by resources/assets loading:

The DOMContentLoaded event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.

Here is a demo snippet that loads an external iFrame that has a 2MB JPEG image; when you run it, you'll see that DOMContentLoaded get to trigger before the iFrame fully loads and it runs custom Javascript; then when the iFrame is done loading, the load event on the iFrame is called and we update a status text.

// On DOMContentLoaded set status text and start an ASCII animation
window.addEventListener('DOMContentLoaded', (event) => {
  document.getElementById('js-status').textContent = 'DOM fully loaded and parsed; staring JS code';

  const animation = new animascii({
      src: [
          ["0-----", "-----0"],
          ["-0----", "----0-"],
          ["--0---", "---0--"],
          ["---0--", "--0---"],
          ["----0-", "-0----"],
          ["-----0", "0-----"]
      ],
      display: document.getElementById("ascii-animation"),
      repeat: -1,
      delay: 120,
      font_size: 20
  }, function() {
      alert("Done!");
  });
});

// On iframe load event set status text
document.getElementsByTagName('iframe')[0].addEventListener('load', function() {
  document.getElementById('iframe-status').textContent = 'IFrame fully loaded';
});
iframe { width: 600px; height: 400px; }
h2 span { color: blue; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/rot.js/0.6.0/rot.min.js"></script>
<script src="https://www.cssscript.com/demo/ascii-animation-library-pure-javascript-animascii/animascii.js"></script>

<h2>DOM/JS status: <span id="js-status">(loading...)</span></h2>
<h2>IFrame status: <span id="iframe-status">(loading...)</span></h2>

<h3>Demo JS to check that JS is running after DOMContentLoaded and before iFrame finish loading</h3>
<div id="ascii-animation"></div>

<iframe src="https://zikro.gr/dbg/so/53583045/iframe.php"></iframe>

Of course you can set the iFrame src attribute on load, but that is already covered by the questions you're linking:

window.addEventListener('load', (event) => {
  document.getElementById('js-status').textContent = 'DOM fully loaded and parsed; staring JS code';
  document.getElementById('iframe-status').textContent = '(loading...)';
  document.getElementsByTagName('iframe')[0].setAttribute('src', 'https://zikro.gr/dbg/so/53583045/iframe.php');
});

document.getElementsByTagName('iframe')[0].addEventListener('load', (event) => {
  document.getElementById('iframe-status').textContent = 'IFrame fully loaded';
});
iframe { width: 600px; height: 400px; }
h2 span { color: blue; }
<h2>DOM/JS status: <span id="js-status">(loading...)</span></h2>
<h2>IFrame status: <span id="iframe-status">(not started yet)</span></h2>

<iframe></iframe>

In modern browsers all you need to do is add loading="lazy" to your iframe.

<iframe src="test.html" loading="lazy"></iframe>

This feature is rated "Baseline 2023", meaning it's supported across the latest devices and browser versions as of December 2023. (MDN)

A different and somewhat-easier trick: do the load as usual, but also include

<link rel="prefetch" href="https://example.com/test.html">

in your page's <head>.

The browser will start fetching test.html (or huge.png) for you.

It doesn't even require the iframe to exist, you can put it in any page. If you want, you can have the browser start loading the external resource before it's even on the specific page that needs it.

The detailed time depends on the browser's decision, of course, but at the end of the day that's true for all async requests -- and you can put that prefetch first thing after the doctype stuff.

发布评论

评论列表(0)

  1. 暂无评论