Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FCP on iOS WebView is 3x higher than Android WebView #570

Open
guoyunhe opened this issue Nov 18, 2024 · 5 comments
Open

FCP on iOS WebView is 3x higher than Android WebView #570

guoyunhe opened this issue Nov 18, 2024 · 5 comments

Comments

@guoyunhe
Copy link

guoyunhe commented Nov 18, 2024

We have a mobile app with WebView. Web pages loaded in Android app has a very low FCP, which is great. However, web pages loaded in iOS app has 3x higher FCP than Android.

And you can also see, LCP of iOS and Android are almost the same.

image

@tunetheweb
Copy link
Member

Interesting. I have heard about FCP on Safari being reported much earlier but not later!

I'm also curious as to how you're seeing LCP on iOS as it does not support that?

What this library does in terms of FCP is relatively simple and pretty much just reports what the web timing APIs give for it:

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
    console.log('FCP candidate:', entry.startTime, entry);
  }
}).observe({type: 'paint', buffered: true});

To rule out this library it would be good to run the above JavaScript and confirm what it shows? And that it matches when the contentful paint shows (i.e. is the first contentful paint at 0.455ms or at 1492ms when looking at what's rendered).

Then you'll likely need to raise an issue an issue at https://bugs.webkit.org/ for Safari to look into.

@guoyunhe
Copy link
Author

guoyunhe commented Nov 18, 2024

I'm also curious as to how you're seeing LCP on iOS as it does not support that?

We have a manual implementation of LCP on Safari, not perfect but it works 😺

What this library does in terms of FCP is relatively simple and pretty much just reports what the web timing APIs give for it:

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
    console.log('FCP candidate:', entry.startTime, entry);
  }
}).observe({type: 'paint', buffered: true});

To rule out this library it would be good to run the above JavaScript and confirm what it shows? And that it matches when the contentful paint shows (i.e. is the first contentful paint at 0.455ms or at 1492ms when looking at what's rendered).

We also have another app that shows different result: iOS FCP is a little smaller than Android but they are close enough. This makes me rethink what made the difference. I will try to get more data with your method.

Thanks for the explanation!

@tunetheweb
Copy link
Member

tunetheweb commented Nov 18, 2024

We also have another app that shows different result: iOS FCP is a little smaller than Android but they are close enough. This makes me rethink what made the difference.

That would make sense to me based on the post linked above, as IIRC their presentation time for FCP is basically when it leaves WebKit and is sent to the OS to render. Which is early than Chrome which handles more of the rendering in browser land.

Being so much larger does not make sense to me. So super curious if you figure this out!

@guoyunhe
Copy link
Author

guoyunhe commented Nov 21, 2024

I guess it is because our web page has a loading screen:

image

This loading screen is pure div + CSS. Here is no texts or images. However, we do inserted some zero-width space to trick browsers and improve FCP 🙈. It tricked Chrome but not Safari. Safari is smart enough to ignore all kinds of spaces and non-sense characters.

In short, if anyone want to trick iOS Safari/WebView on FCP, simply add the following code into your HTML:

<span style="color:transparent">...</span>

@tunetheweb
Copy link
Member

That's interesting. I'd be curious to see the code for that loading screen. FCP should only trigger if it's a URL background images (including data). So it's possible that that a data-encoded URL of "grey" is enough to trigger FCP for content on chrome if that's what you're using. If there is no background-image and it's just a background-color I would not expect it to trigger FCP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants