BarneyK
BarneyK

Reputation: 399

Resizing iframe from JavaScript results high CLS

I have an iframe on my site that displays a list. At the bottom of the list there is a "See more" button, once the user presses it, the list will expand. The iframed site uses parent.postMessage to notify my site of the height changes:

parent.postMessage({"height": height}, targetOrigin);

On my site, I listen to this message and update the iframe's height by code:

window.addEventListener("message", function (event) {
  if (event.data.height) {
    const iframe = document.getElementById("iframe");
    iframe.height = event.data.height;
  }
});

However clicking inside the iframe does not count as user interaction on the site, so by expanding the iframe from JavaScript it results as "unexpected layout shift" once the content below the iframe is pushed down.

I tried to delay the height change with setTimeout, and also added transition css rule to the iframe's height, but still getting high CLS numbers. I also tried to add a button on the site and once the message arrives, I trigger a click event on it, and handle the resize from that, but it didn't help at all.

I can ask the iframed site to modify their code, if necessary. Also the new height is dynamic, so I won't know it until the message arrives.

How to solve the CLS issue, while having the resize in place?

Edit: Answering KIKO Software for clarification.

The site's CLS score for real user data is around 0.7-0.9. I get this number from PageSpeed Insights and from a Chrome extension. I suspect the "See more" button, because nothing else on the site moves or loads. Also I installed a Chrome extension (CLS visualizer) that shows the shifts upon interaction.

Since the CLS is part of the Web Vitals, my page is getting worse ranking by search engines if it's high, that is why I'm concerned.

Upvotes: 0

Views: 75

Answers (1)

David Bradshaw
David Bradshaw

Reputation: 13087

Coming to this as the author of iframe-resizer.

You can reduce visible layout shifts on page load, by setting the initial height of the iframe to 100vh. That way once the content loads, it will either shrink into view, which stops the jarring effect, or it will expand below the fold, where again it will have no jarring effect on the user.

Updating the iframe via postMessage after the page in the iframe loads more content you will have to accept this is never going to have the browser think it was the result of user interaction. If this is important to you then you need to run the iframe on the same-origin as the parent page, so you can communicate directly via JS, without using message passing.

A better question is how is the content being added to the iframe. I would look to see if there is a lot of content shifting going on when that happens. Ideally you should render all the added content in one go with all page elements correctly sized and then send a single postMessage to the parent page.

Upvotes: 0

Related Questions