Replies: 5 comments 13 replies
-
I believe we should avoid adding GNAV-specific logic to I tested the changes locally and noticed flickering while loading GNAV, though I’m not sure if it’s just on my end. We also need to align with the business to ensure the right loading experience for the dropdown and UNAV container, as these components are delayed. |
Beta Was this translation helpful? Give feedback.
-
@vhargrave We are thinking of pulling in global navigation before geo routing or making it async so that the global navigation loads faster. This is for improving the global navigation experience. Do you see any risk in this approach? |
Beta Was this translation helpful? Give feedback.
-
I wanted to provide more context on the focus on loading the global navigation earlier:
![]() Reference: Qualitative Research Findings
|
Beta Was this translation helpful? Give feedback.
-
One more note/FYI/consideration... We have multiple possible LCP elements, so it can also be that the same page has an LCP in the first, second and third section. So if the second and third section compete against loading all the post LCP code (gnav, privacy, etcetc), you might hurt the overall LCP. |
Beta Was this translation helpful? Give feedback.
-
There's another thing to consider here, which is INP. Since we're showing everything early, and dropdowns are even less likely to arrive by the time the user can click a dropdown, we are liable to have a high INP. This is solved also by the introduction of a loading state. |
Beta Was this translation helpful? Give feedback.
-
Recently the feds team began to look at optimizing the load of the Global Navigation block. It's certainly possible for the block to become visible sooner than it currently does. This post describes the methodology, the code changes, and the tradeoffs to be made so that the community can comment on them before we go ahead with the changes.
A note on methodology
We throttle our network connection to "Slow 4G" provided on Chrome, and do singular runs to measure the performance using
performance.mark
andperformance.measure
. We do not throttle the CPU. While doing singular runs is not sufficient for predicting the real world performance, it is sufficient to confirm whether a specific change improved or worsened the performance. We also use content overrides to override the Response objects in Chrome DevTools. This allowed us to test on prod with the load times prod provides.Baseline performance
Before making any changes we must establish a baseline. Gnav is loaded quite simply:
The LCP can be inferred by adding the start time and the duration of 'FirstSectionLoaded'. We can see that the LCP is ~5.5 seconds, the gnav starts loading in around 6 seconds in and takes another ~5.5 seconds. Further we see that, since the subsequent sections are blocked by the gnav, the second section only finishes loading ~12.5 seconds in, with the rest completing ~20 seconds in. This is undesirable since the user is unable to scroll or see any further content until further sections load.
Make the Gnav non-blocking
Our first change is to make gnav non blocking; simply remove the await. This makes it more likely that subsequent sections interfere with the load of the gnav, but the page overall feels faster since the amount of time the user waits for the second section is dramatically reduced.
We can see the LCP and the total amount of time the gnav takes is unchanged, but the second section loads ~5 seconds faster.
Parallelize requests for required assets
The next step is a little more involved. The gnav does an initial load of its main content, and loads the rest (dropdown content, unav, etc.) For the initial load, we require a few files:
The code change to do all this is a little more involved. It requires us to move logic into utils.js (see tradeoffs section below)
We also need to modify the gnav init function and the fetchAndProcessPlainHTML function to accept promises instead of making the network calls themselves.
We see some improvement: gnav now loads in ~3.8 seconds.
Show the Gnav Earlier
Finally we see that the gnav can only become visible after the following code finishes executing:
The problem is that this.ims will load the universal nav, and we won't be able to show anything until the promise for the unav js and css resolves (though we don't wait for them to be executed). The solution, then, is
Upon measurement:

We see the gnav takes only ~650ms to become visible. If we move the gnav load before georouting (or make that async as well), we could pull back the gnav to load another ~600ms earlier. We can't move the gnav load any earlier without affecting the LCP (since the gnav is unlikely to be the LCP unless the user interacts with the page).
Tradeoffs
There are a couple of tradeoffs we make for this optimization
In exchange we get
Are these tradeoffs worth it? It's possible to pick and choose which optimizations we want.
You can see all the changes here: https://github.com/adobecom/milo/compare/gnav-performance?expand=1
cc: @salonijain3 @skambi @bandana147
Beta Was this translation helpful? Give feedback.
All reactions