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

MWPW-159113 [Personalization] Parallelize personalization network requests to be as efficient as possible #2970

Open
wants to merge 15 commits into
base: stage
Choose a base branch
from

Conversation

sharmrj
Copy link
Contributor

@sharmrj sharmrj commented Sep 27, 2024

  • Network requests, entitlements.js, promo-utils.js (if needed), and the manifest files are now made concurrently.

This optimization won't immediately bear fruit since it reveals a different bottleneck
Before:
image

After:
image

Once entitlements.js, promo-utils.js, and the manifests load concurrently, we find that launch becomes our bottleneck, so thi optimization needs to be combined with two subsequent optimizations in order to bear fruit. Note that photoshop.json takes less time to load in prod environments, so launch is more likely to be bottleneck in prod.

  1. Launch.js needs to be split up/optimized. Related tickets: https://jira.corp.adobe.com/browse/MWPW-158739, https://jira.corp.adobe.com/browse/MWPW-158749
  2. The request for the manifest files may need to be made earlier (this depends on how long it takes to load in prod with the prior optimizations, since manifest files take less time to laod on prod.). We'll have to wait for prior optimizations to be done to decide the next step.

Resolves: MWPW-159113

Test URLs:

https://main--cc--adobecom.hlx.page/products/photoshop?milolibs=par-pers--milo--sharmrj

@sharmrj sharmrj requested a review from a team as a code owner September 27, 2024 06:57
Copy link
Contributor

aem-code-sync bot commented Sep 27, 2024

Page Scores Audits Google
📱 /?martech=off PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI
🖥️ /?martech=off PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI

Copy link

codecov bot commented Sep 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.80%. Comparing base (f950ca5) to head (3180394).

Additional details and impacted files
@@            Coverage Diff             @@
##            stage    #2970      +/-   ##
==========================================
+ Coverage   95.92%   98.80%   +2.87%     
==========================================
  Files         175       70     -105     
  Lines       47971     8449   -39522     
==========================================
- Hits        46016     8348   -37668     
+ Misses       1955      101    -1854     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@spadmasa spadmasa self-assigned this Sep 27, 2024
Copy link
Contributor

@mokimo mokimo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool to see this being tackled, with MEP/Personalization we should have room for improvements in terms of performance.

}

manifests = await Promise.all((await Promise.all(manifestPromises))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the double Promise.all there for any specific reason, or is that an omission?

// Untested demo code
manifests = await Promise.all(
  manifestPromises.map(async (promise) => {
    try {
      const resp = await promise;
      if (!resp.ok) {
        if (resp.status === 404) {
          throw new Error('File not found');
        }
        throw new Error(`Invalid response: ${resp.status} ${resp.statusText}`);
      }
      const manifestData = await resp.json();
      return { manifestData, manifestPath: resp.url };
    } catch (e) {
      console.log(`Error loading content: ${resp.url}`, e.message || e);
      return null;
    }
  })
).then(results => results.filter(Boolean));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the double Promise.all needs to be refactored. I've done something similar to what you've suggested.

@sharmrj
Copy link
Contributor Author

sharmrj commented Sep 27, 2024

@mokimo pointed out an issue where we're waiting a long time in between the interact call and loading the blocks.

Turns out, if launch finishes loading before the ims token network request completes, the page stalls for 4 extra seconds while we wait for the alloy event (even though the interact call goes through just fine). I've confirmed this by making measurements of getTargetPersonalization like so:

    performance.mark('targetstart');
    const { targetManifests, targetPropositions } = await getTargetPersonalization();
    performance.mark('targetend');
    console.log(performance.measure('target', 'targetstart', 'targetend'));

If launch loads before the ims token comes back we always get a 4second timing on this function:

PerformanceMeasure {detail: null, name: 'target', entryType: 'measure', startTime: 5821.900000095367, duration: 4000.899999976158}

Note that the timeout duration in martech.js is exactly 4000ms.
If the ims token comes back before launch we get something more along the lines of:

PerformanceMeasure {detail: null, name: 'target', entryType: 'measure', startTime: 8346.5, duration: 596.2999999523163}

This is possibly why some Nala tests are timing out.

AFAICT this sometimes happens out in the wild, it's just that the optimization in this pr makes it more likely to happen. I'll continue to investigate the root cause.

Copy link
Contributor

This pull request is not passing all required checks. Please see this discussion for information on how to get all checks passing. Inconsistent checks can be manually retried. If a test absolutely can not pass for a good reason, please add a comment with an explanation to the PR.

Copy link
Contributor

github-actions bot commented Oct 6, 2024

This PR has not been updated recently and will be closed in 7 days if no action is taken. Please ensure all checks are passing, https://github.com/orgs/adobecom/discussions/997 provides instructions. If the PR is ready to be merged, please mark it with the "Ready for Stage" label.

Copy link
Contributor

@vgoodric vgoodric left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please let me know when this is finalized so we can thoroughly QA it. SOT approval often does not check for MEP.

@github-actions github-actions bot removed the Stale label Oct 9, 2024
Copy link
Contributor

This PR has not been updated recently and will be closed in 7 days if no action is taken. Please ensure all checks are passing, https://github.com/orgs/adobecom/discussions/997 provides instructions. If the PR is ready to be merged, please mark it with the "Ready for Stage" label.

@github-actions github-actions bot added Stale and removed Stale labels Oct 16, 2024
}

if (promoEnabled) {
const { default: getPromoManifests } = await import('./promo-utils.js');
const { default: getPromoManifests } = await promoUtilsPromise;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could also move code from promo-utils.js directly here, i think it was not a good decision in the first place to have a separate file.
promo-utils.js contents seem small enough

@@ -1037,15 +1047,22 @@ export const combineMepSources = async (persEnabled, promoEnabled, mepParam) =>
}
});
}
return persManifests;
return initialPersManifestsPromises.concat(persManifests
.filter((m) => !('disabled' in m) || !m.disabled)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if i remember correct, we shouldn't filter out disabled manifests.
those are 'promotions' manifests that are schedule is in the future/past, but Content Authors need to see them in the Page mep preview interface. However we don't load the .json itself (at least this is how it used to work) unless the manifest is active.

if you are still able to see a disabled manifest in the page then we are good

Copy link
Contributor

This PR has not been updated recently and will be closed in 7 days if no action is taken. Please ensure all checks are passing, https://github.com/orgs/adobecom/discussions/997 provides instructions. If the PR is ready to be merged, please mark it with the "Ready for Stage" label.

@github-actions github-actions bot added Stale and removed Stale labels Oct 25, 2024
Copy link
Contributor

github-actions bot commented Nov 2, 2024

This PR has not been updated recently and will be closed in 7 days if no action is taken. Please ensure all checks are passing, https://github.com/orgs/adobecom/discussions/997 provides instructions. If the PR is ready to be merged, please mark it with the "Ready for Stage" label.

@github-actions github-actions bot added the Stale label Nov 2, 2024
@sharmrj sharmrj removed the Stale label Nov 7, 2024
@sharmrj
Copy link
Contributor Author

sharmrj commented Nov 7, 2024

For whatever reason I'm seeing the timeout issue again after merging the stage branch into my branch and fixing the merge conflicts. I was also unable to reproduce the issue earlier which is why I thought it had been resolved.
It seems IMS loaded after launch and that's what triggered the issue again:
image
image

I'll attach the trace here:
Trace-20241107T131821.json.zip

Comment on lines +1085 to +1086
const normalizedURL = normalizePath(manifestPath);
return fetch(normalizedURL, { mode: 'same-origin' });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: inline normalizePath

/* c8 ignore next 3 */
console.log(`Error loading content: ${resp.url}`, e.message || e);
}
if (pzn) loadLink(getXLGListURL(config), { as: 'fetch', crossorigin: 'anonymous', rel: 'preload' });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this line still need to run even when the manifest loading is successful?

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

Successfully merging this pull request may close these issues.

6 participants