-
Notifications
You must be signed in to change notification settings - Fork 169
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
base: stage
Are you sure you want to change the base?
Conversation
… and the manifest
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
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. |
There was a problem hiding this 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)) |
There was a problem hiding this comment.
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));
There was a problem hiding this comment.
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.
@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 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:
Note that the timeout duration in martech.js is exactly 4000ms.
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. |
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. |
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. |
There was a problem hiding this 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.
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. |
} | ||
|
||
if (promoEnabled) { | ||
const { default: getPromoManifests } = await import('./promo-utils.js'); | ||
const { default: getPromoManifests } = await promoUtilsPromise; |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
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. |
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. |
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. I'll attach the trace here: |
const normalizedURL = normalizePath(manifestPath); | ||
return fetch(normalizedURL, { mode: 'same-origin' }); |
There was a problem hiding this comment.
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' }); |
There was a problem hiding this comment.
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?
This optimization won't immediately bear fruit since it reveals a different bottleneck
Before:
After:
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.
Resolves: MWPW-159113
Test URLs:
https://main--cc--adobecom.hlx.page/products/photoshop?milolibs=par-pers--milo--sharmrj