<aside> 🧑‍🎓 This guide uses the Performance Insights feature of Google Chrome development tools. Refer to this guide to learn how to use it!

How to get FCP and LCP readings?

</aside>

Untitled

By default, the network requests on a timeline are grouped by hostname. To explore each separate request expand the Network tab.

Start by locating the request resulting in LCP element rendering on the timeline. We suggest putting the handle onto the LCP event and scrolling down, until you see media (green) request ending right before it. Likely, this is the LCP element!

Now, backtrace the request chain up, looking for a request, which end matches the start of a current request (i.e. LCP media request).

Jan-06-2023 13-50-08.gif

Jan-06-2023 13-36-45.gif

<aside> 🧠 Sometimes, requests may not align correctly, for example, if some heavy logic had to be executed beforehand.

To trace such cases, enable the screenshot preview (in the bottom left corner). You can now expand the preview window and use slider (or handle) to traverse the timeline and see screenshots of website loading.

</aside>

As seen in our case, the end of blocking request might not match the start of the blocked request exactly. This is because the JavaScript needs some time to parse and execute downloaded code (in our case GraphQl response needs to parsed and rendered).

As seen in the example, the request blocking main banner image is the GraphQl request of homepage CMS content.

Jan-06-2023 15-30-00.gif

Jan-06-2023 16-55-42.gif

As seen in the example, the request blocking GraphQl request of homepage CMS content, is some request with hash starting with 392....

<aside> 🧠 Use Network tab to learn what payload did response return. Search by known request hash.

</aside>

In our case, this request turns out to be the config request!

But, the GraphQl request could not have been made on its own, it should have been fired by some JavaScript (from some chunk).

<aside> 🧠 Use Network tab to learn who was the initiator of the request. Be careful, direct initiators of the request are common to be parts of dispatchers or main chunk, look for something else, closer to current request.

</aside>

In our case, the request was made from chunk 69, not cms as might have thought. Why?

Jan-06-2023 15-49-14.gif

Jan-06-2023 16-16-39.gif

Switch to development mode to find out! From ScandiPWA root, run:

yarn start # using Yarn
npm run start # using NPM

Using trace of GraphQl request, we learn that it is made from CmsPage.container.js, which as seen from source-maps is a part of vendors~cms chunk.

<aside> 🧠 We see extra chunk, because Webpack automatically splits them if they exceeding a certain size. In this case cms chunk is split into multiple chunks, one of them being vendors~cms also known to us, as the chunk 69.

The weird chunk name 69 (instead of vendors~cms) comes from the Webpack obfuscating chunk names by default in production mode.

</aside>

Untitled

Jan-06-2023 16-28-52.gif

Now, we have two leads: chunk 69 (aka. vendors~cms), and config GraphQl request.

Let’s follow each:

Final stretch! We have two leads, following each:

Let’s now review the final request chain we got for our Homepage:

Jan-06-2023 16-30-56.gif

Untitled

<aside> 🎉 We learned how to identify the critical requests chain!

</aside>

Common critical chains

Homepage (before optimization)

Untitled

Homepage (after optimization)

Untitled

PLP / Product Listing Page (before optimization)

Untitled

PLP / Product Listing Page (after optimization)

Untitled

PDP / Product Description Page (before optimization)

Untitled

PDP / Product Description Page (after optimization)

Untitled