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-163603 benchmark card rendering time in PR #3377

Open
wants to merge 16 commits into
base: stage
Choose a base branch
from
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ npm run test:watch
-----

#### 1. Running Nala Tests
Make sure you ran `npm run install` in the project root.
Make sure you ran `npm install` in the project root.
You might need also to run `npx playwright install`.
Nala tests are run using the `npm run nala <env> [options]` command:

Expand Down
4 changes: 2 additions & 2 deletions libs/deps/mas/commerce.js

Large diffs are not rendered by default.

70 changes: 35 additions & 35 deletions libs/deps/mas/mas.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion libs/deps/mas/merch-card-collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ var N=Object.defineProperty;var y=(s,e,t)=>e in s?N(s,e,{enumerable:!0,configura
justify-content: end;
}
}
`;var u=(s,e)=>s.querySelector(`[slot="${e}"]`).textContent.trim();var D="merch-card-collection",a={alphabetical:"alphabetical",authored:"authored"},v={filters:["noResultText","resultText","resultsText"],mobile:["noSearchResultsMobileText","searchResultMobileText","searchResultsMobileText"],desktop:["noSearchResultsText","searchResultText","searchResultsText"]},P=(s,e={})=>{s.querySelectorAll("span[data-placeholder]").forEach(t=>{let{placeholder:o}=t.dataset;t.innerText=e[o]??""})},B=(s,{filter:e})=>s.filter(t=>t.filters.hasOwnProperty(e)),H=(s,{types:e})=>e?(e=e.split(","),s.filter(t=>e.some(o=>t.types.includes(o)))):s,V=s=>s.sort((e,t)=>(e.title??"").localeCompare(t.title??"","en",{sensitivity:"base"})),I=(s,{filter:e})=>s.sort((t,o)=>o.filters[e]?.order==null||isNaN(o.filters[e]?.order)?-1:t.filters[e]?.order==null||isNaN(t.filters[e]?.order)?1:t.filters[e].order-o.filters[e].order),k=(s,{search:e})=>e?.length?(e=e.toLowerCase(),s.filter(t=>(t.title??"").toLowerCase().includes(e))):s,p=class extends O{constructor(){super();E(this,"mobileAndTablet",new f(this,A));this.filter="all",this.hasMore=!1,this.resultCount=void 0,this.displayResult=!1}render(){return l`${this.header}
`;var u=(s,e)=>s.querySelector(`[slot="${e}"]`)?.textContent?.trim();var D="merch-card-collection",a={alphabetical:"alphabetical",authored:"authored"},v={filters:["noResultText","resultText","resultsText"],mobile:["noSearchResultsMobileText","searchResultMobileText","searchResultsMobileText"],desktop:["noSearchResultsText","searchResultText","searchResultsText"]},P=(s,e={})=>{s.querySelectorAll("span[data-placeholder]").forEach(t=>{let{placeholder:o}=t.dataset;t.innerText=e[o]??""})},B=(s,{filter:e})=>s.filter(t=>t.filters.hasOwnProperty(e)),H=(s,{types:e})=>e?(e=e.split(","),s.filter(t=>e.some(o=>t.types.includes(o)))):s,V=s=>s.sort((e,t)=>(e.title??"").localeCompare(t.title??"","en",{sensitivity:"base"})),I=(s,{filter:e})=>s.sort((t,o)=>o.filters[e]?.order==null||isNaN(o.filters[e]?.order)?-1:t.filters[e]?.order==null||isNaN(t.filters[e]?.order)?1:t.filters[e].order-o.filters[e].order),k=(s,{search:e})=>e?.length?(e=e.toLowerCase(),s.filter(t=>(t.title??"").toLowerCase().includes(e))):s,p=class extends O{constructor(){super();E(this,"mobileAndTablet",new f(this,A));this.filter="all",this.hasMore=!1,this.resultCount=void 0,this.displayResult=!1}render(){return l`${this.header}
<slot></slot>
${this.footer}`}updated(t){if(!this.querySelector("merch-card"))return;let o=window.scrollY||document.documentElement.scrollTop,n=[...this.children].filter(r=>r.tagName==="MERCH-CARD");if(n.length===0)return;t.has("singleApp")&&this.singleApp&&n.forEach(r=>{r.updateFilters(r.name===this.singleApp)});let i=this.sort===a.alphabetical?V:I,h=[B,H,k,i].reduce((r,c)=>c(r,this),n).map((r,c)=>[r,c]);if(this.resultCount=h.length,this.page&&this.limit){let r=this.page*this.limit;this.hasMore=h.length>r,h=h.filter(([,c])=>c<r)}let m=new Map(h);n.forEach(r=>{if(m.has(r)){let c=m.get(r);r.style.order=c,r.setAttribute("tabindex",c+1),r.size=r.filters[this.filter]?.size,r.style.removeProperty("display"),r.requestUpdate()}else r.style.display="none",r.size=void 0,r.style.removeProperty("order")}),window.scrollTo(0,o),this.updateComplete.then(()=>{let r=this.shadowRoot.getElementById("resultText")?.firstElementChild?.assignedElements?.()?.[0];r&&P(r,{resultCount:this.resultCount,searchTerm:this.search,filter:this.sidenav?.filters.selectedText})})}connectedCallback(){super.connectedCallback(),this.filtered?(this.filter=this.filtered,this.page=1):this.startDeeplink(),this.sidenav=document.querySelector("merch-sidenav")}disconnectedCallback(){super.disconnectedCallback(),this.stopDeeplink?.()}get header(){if(!this.filtered)return l`<div id="header">
<sp-theme color="light" scale="medium">
Expand Down
188 changes: 94 additions & 94 deletions libs/deps/mas/merch-card.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion libs/features/mas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ npm run build
#### Build documentation

```sh
node run build:docs
npm run build:docs
```

### Testing
Expand Down
70 changes: 35 additions & 35 deletions libs/features/mas/dist/mas.js

Large diffs are not rendered by default.

125 changes: 125 additions & 0 deletions libs/features/mas/docs/benchmarks.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@

<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>M@S Benchmarks</title>
<script>
performance.mark('benchmark:start')
window.commercePromise = new Promise((resolve) => {
document.addEventListener('wcms:commerce:ready', () => {
//we measure the time it takes to load the commerce bundle and store it in a global variable
window.initTime = performance.measure('initTime', 'benchmark:start', 'mas:ready').duration;
console.log(`Commerce loaded in ${window.initTime}ms`);
resolve();
});
});
</script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Fonts -->
<link rel="stylesheet" href="https://use.typekit.net/hah7vzn.css">
<!-- Include any additional stylesheets -->
<link rel="stylesheet" href="spectrum.css">
<link rel="stylesheet" href="styles.css">
<script type="module">
import { init } from './common.js';
init();
</script>
</head>

<script>
const measureCardPerformances = async (container, fragmentId) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

we should probably incorporate performance api to merch-card and aem-fragment custom elements directly.

and use performance api entries while reporting the measurements.

return new Promise((resolve, reject) => {
const result = {};
const card = document.createElement('merch-card');
const fragment = document.createElement('aem-fragment');
fragment.setAttribute('fragment', fragmentId);
card.appendChild(fragment);
let timeoutId;
const onReady = () => {
clearTimeout(timeoutId);
const mark = (suffix) => `merch-card:${fragmentId}:${suffix}`;
result.duration = performance.measure(fragmentId, mark('start'), mark('ready')).duration;
console.log(`Card ${fragmentId} loaded in ${result.duration}ms`);
resolve(result);
};
card.addEventListener('mas:ready', onReady);
timeoutId = setTimeout(() => {
card.removeEventListener('mas:ready', onReady);
result.timedOut = true;
console.log(`Card ${fragmentId} timed out`);
reject('Timed out');
}, 5000); // Timeout after 5 seconds
container.appendChild(card);
result.card = card;
});
};
const fillContainer = async (container) => {
const fragmentIds = container.getAttribute('data-benchmark').split(',');
let limit = parseFloat(container.getAttribute('data-benchmark-limit'));
const adjust = new URL(window.location.href).searchParams.get('adjust') === 'true';
if (adjust) {
//if adjust is set to true, we adjust the limit based on the stored initTime and
//reference time of 82ms it took on a quick network. This way, we should not be
//affected by network speed when comparing benchmarks to limit.
const referentInitialTime = 82.0;
const previousLimit = limit;
if (referentInitialTime < window.initTime) {
limit = limit * window.initTime / referentInitialTime;
container.setAttribute('data-benchmark-limit', limit);
container.setAttribute('data-benchmark-previous-limit', previousLimit);
console.log(`Adjusted limit ${previousLimit} to ${limit}`);
} else {
console.log('No need to adjust limit');
}
}
const promises = fragmentIds.map((fragmentId) => measureCardPerformances(container, fragmentId));
const results = await Promise.allSettled(promises);
results.forEach((result) => {
const { card, duration } = result.status === 'fulfilled' ? result.value : {};
const mask = document.createElement('div');
mask.style.position = 'absolute';
mask.style.width = card.offsetWidth + 'px';
mask.style.height = card.offsetHeight + 'px';
mask.style.top = card.offsetTop + 'px';
mask.style.left = card.offsetLeft + 'px';
mask.textContent = `⏱️ ${duration}ms`;
mask.classList.add('benchmark-mask');
mask.setAttribute('data-benchmark-time', duration);
mask.classList.add(duration > limit ? 'benchmark-mask-over-limit' : 'benchmark-mask-under-limit');
container.appendChild(mask);
});
}
</script>

<body class="spectrum spectrum--medium spectrum--light">
<aside class="sidenav">
<a href="/libs/features/mas/docs/mas.html">Home</a>
<a href="/libs/features/mas/docs/mas.js.html">mas.js</a>
<a href="/libs/features/mas/docs/checkout-link.html">Checkout Link</a>
<a href="/libs/features/mas/docs/inline-price.html">Inline Price</a>
<a href="/libs/features/mas/docs/merch-card.html">Merch Card</a>
<a href="/libs/features/mas/docs/ccd.html">CCD Gallery</a>
<a href="/libs/features/mas/docs/benchmarks.html">Benchmarks</a>
</aside>
<main>
<div class="gallery-content">
<h1 id="ccd-cards" tabindex="-1">CCD cards benchmark<a class="header-cards" href="#ccd-cards" href="#ccd-cards" title="Permalink to this heading">#</a></h1>
Marked as green if below each container limit, red otherwise. If you are running this page under a slow network, <a href="/libs/features/mas/docs/benchmarks.html?adjust=true">you can adjust the limit by adding <code>?adjust=true</code> to the URL.</a>
<div class="three-merch-cards ccd-slice"
data-benchmark="0ef2a804-e788-4959-abb8-b4d96a18b0ef,58c7906f-70a6-4e2b-bc29-257ff2ade513,51c23f28-504f-450d-9764-0e60f1e279b2,c13897c7-de77-4e45-b23b-eec9fd66cad1,bdf40d06-5914-4f1f-aa10-77c5676fe671,31205553-b453-4c9e-a2ef-7b6aa7bfdc72"
data-benchmark-limit="400">
</div>
</div>
<script>
window.commercePromise.then(() => {
const promises = Array.from(document.querySelectorAll('[data-benchmark]')).map((c) => fillContainer(c));
Promise.allSettled(promises).then((containers) => {
console.log('All containers have been processed');
const event = new Event('benchmark-done');
document.querySelector('body').dispatchEvent(event);
});
});
</script>
</main>
</body>
</html>
14 changes: 11 additions & 3 deletions libs/features/mas/docs/ccd.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,17 @@
document.head.appendChild(masCommerceService);
</script>
</head>

<body class="spectrum spectrum--medium spectrum--light">
<main>
<body class="spectrum spectrum--medium spectrum--light">
<aside class="sidenav">
<a href="/libs/features/mas/docs/mas.html">Home</a>
<a href="/libs/features/mas/docs/mas.js.html">mas.js</a>
<a href="/libs/features/mas/docs/checkout-link.html">Checkout Link</a>
<a href="/libs/features/mas/docs/inline-price.html">Inline Price</a>
<a href="/libs/features/mas/docs/merch-card.html">Merch Card</a>
<a href="/libs/features/mas/docs/ccd.html">CCD Gallery</a>
<a href="/libs/features/mas/docs/benchmarks.html">Benchmarks</a>
</aside>
<main>
<div class="gallery-content">

<h1 id="ccd-gallery" tabindex="-1">CCD Gallery <a class="header-anchor" href="#ccd-gallery" href="#ccd-gallery" title="Permalink to this heading">#</a></h1>
Expand Down
42 changes: 18 additions & 24 deletions libs/features/mas/docs/checkout-link.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,33 @@
<meta charset="UTF-8">
<title>M@S Web Components</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script type="module" src="../../../deps/custom-elements.js"></script>
<link rel="stylesheet" href="spectrum.css">
<link rel="stylesheet" href="../style.css">
<link rel="stylesheet" href="https://use.typekit.net/hah7vzn.css">

<script>
if (/localhost/.test(window.location.host)) {
const meta = document.createElement('meta');
meta.name = 'aem-base-url';
meta.content = 'http://localhost:8080'; // local AEM proxy URL
document.head.appendChild(meta);
}
</script>
<script type="module" src="../dist/mas.js"></script>

<!-- Include your custom element script as an ES6 module -->
<script type="module">
const params = new URLSearchParams(document.location.search);
const masCommerceService = document.createElement('mas-commerce-service');
['locale','language','env','cli'].forEach((attribute) => {
let value = params.get(attribute);
if (value === 'cli') attribute = 'checkout-client-id';
if (value) masCommerceService.setAttribute(attribute, value);
});
document.head.appendChild(masCommerceService);
import { init } from './common.js';
init();
</script>
<!-- Include Highlight.js stylesheet for syntax highlighting -->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css">
<!-- Include any additional stylesheets -->
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main class="spectrum spectrum--medium spectrum--light">
<div class="container">
<h1 id="checkout-link" tabindex="-1">checkout-link <a class="header-anchor" href="#checkout-link" href="#checkout-link" title="Permalink to this heading">#</a></h1>
<body class="spectrum spectrum--medium spectrum--light">
<div class="sidenav">
<a href="/libs/features/mas/docs/mas.html">Home</a>
<a href="/libs/features/mas/docs/mas.js.html">mas.js</a>
<a href="/libs/features/mas/docs/checkout-link.html">Checkout Link</a>
<a href="/libs/features/mas/docs/inline-price.html">Inline Price</a>
<a href="/libs/features/mas/docs/merch-card.html">Merch Card</a>
<a href="/libs/features/mas/docs/ccd.html">CCD Gallery</a>
<a href="/libs/features/mas/docs/benchmarks.html">Benchmarks</a>
</div>
<main>
<sp-theme color="light" scale="medium">
<h1 id="checkout-link" tabindex="-1">checkout-link <a class="header-anchor" href="#checkout-link" href="#checkout-link" title="Permalink to this heading">#</a></h1>
<h2 id="introduction" tabindex="-1">Introduction <a class="header-anchor" href="#introduction" href="#introduction" title="Permalink to this heading">#</a></h2>
<p>This custom element renders a checkout link supporting most of the features documented at <a href="https://wiki.corp.adobe.com/pages/viewpage.action?spaceKey=businessservices&amp;title=UCv3+Link+Creation+Guide.">https://wiki.corp.adobe.com/pages/viewpage.action?spaceKey=businessservices&amp;title=UCv3+Link+Creation+Guide.</a><br>
Sometimes a checkout-link can be also referred as placeholder, as it can be used as an inline link resolving at runtime.<br>
Expand Down Expand Up @@ -349,7 +343,7 @@ <h4 id="logs" tabindex="-1">Logs <a class="header-anchor" href="#logs" href="#lo
<pre><code id="log" class="language-html">
</code></pre>

</div>
</sp-theme>
</main>
<script type="module">
document.querySelectorAll('code.demo').forEach(el => {
Expand Down
36 changes: 36 additions & 0 deletions libs/features/mas/docs/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import '../../../deps/custom-elements.js';
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe its better to place it in src folder
and keep docs folder for html build artifacts

Copy link
Contributor Author

Choose a reason for hiding this comment

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

actually no, src is for doc build, and docs is for built / as is artifacts, so it's at its place

const init = () => {
const ENVS = {
Copy link
Contributor

Choose a reason for hiding this comment

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

kudos on adding this, I would mention it in PR description

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 could yes, i didn't add it to ccd page and i should have, but i'm waiting for @yesil merge on spectrum css before to limit merge work

Copy link
Contributor

@yesil yesil Dec 20, 2024

Choose a reason for hiding this comment

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

Oh, I also have something similar but not common but will replace with this once before merge.

qa: 'qa-odin',
stage: 'stage-odin',
prod: 'odin',
};
const href = window.location.href;
const envOverride = new URL(href).searchParams.get('aem.env');
const env =
envOverride && ENVS[envOverride]
? ENVS[envOverride]
: ENVS.prod;
const meta = document.createElement('meta');
meta.name = 'aem-base-url';
meta.content = `https://${env}.adobe.com`;
document.head.appendChild(meta);
import('../dist/mas.js');
// theme
const params = new URLSearchParams(document.location.search);
const darkTheme = params?.get('theme')?.toLowerCase() === 'dark';
const theme = document.createElement('script');
theme.setAttribute('src', `../../spectrum-web-components/dist/themes/${darkTheme ? 'dark' : 'light'}.js`);
theme.setAttribute('type', `module`);
document.head.appendChild(theme);
// mas-commerce-service
const masCommerceService = document.createElement('mas-commerce-service');
['locale','language','env'].forEach((attribute) => {
const value = params.get(attribute);
if (value) masCommerceService.setAttribute(attribute, value);
});
masCommerceService.setAttribute('host-env', 'prod');
masCommerceService.setAttribute('lana-tags', 'ccd');
document.head.appendChild(masCommerceService);
}
export { init };
42 changes: 18 additions & 24 deletions libs/features/mas/docs/inline-price.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,33 @@
<meta charset="UTF-8">
<title>M@S Web Components</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script type="module" src="../../../deps/custom-elements.js"></script>
<link rel="stylesheet" href="spectrum.css">
<link rel="stylesheet" href="../style.css">
<link rel="stylesheet" href="https://use.typekit.net/hah7vzn.css">

<script>
if (/localhost/.test(window.location.host)) {
const meta = document.createElement('meta');
meta.name = 'aem-base-url';
meta.content = 'http://localhost:8080'; // local AEM proxy URL
document.head.appendChild(meta);
}
</script>
<script type="module" src="../dist/mas.js"></script>

<!-- Include your custom element script as an ES6 module -->
<script type="module">
const params = new URLSearchParams(document.location.search);
const masCommerceService = document.createElement('mas-commerce-service');
['locale','language','env','cli'].forEach((attribute) => {
let value = params.get(attribute);
if (value === 'cli') attribute = 'checkout-client-id';
if (value) masCommerceService.setAttribute(attribute, value);
});
document.head.appendChild(masCommerceService);
import { init } from './common.js';
init();
</script>
<!-- Include Highlight.js stylesheet for syntax highlighting -->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css">
<!-- Include any additional stylesheets -->
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main class="spectrum spectrum--medium spectrum--light">
<div class="container">
<h1 id="inline-price" tabindex="-1">inline-price <a class="header-anchor" href="#inline-price" href="#inline-price" title="Permalink to this heading">#</a></h1>
<body class="spectrum spectrum--medium spectrum--light">
<div class="sidenav">
<a href="/libs/features/mas/docs/mas.html">Home</a>
<a href="/libs/features/mas/docs/mas.js.html">mas.js</a>
<a href="/libs/features/mas/docs/checkout-link.html">Checkout Link</a>
<a href="/libs/features/mas/docs/inline-price.html">Inline Price</a>
<a href="/libs/features/mas/docs/merch-card.html">Merch Card</a>
<a href="/libs/features/mas/docs/ccd.html">CCD Gallery</a>
<a href="/libs/features/mas/docs/benchmarks.html">Benchmarks</a>
</div>
<main>
<sp-theme color="light" scale="medium">
<h1 id="inline-price" tabindex="-1">inline-price <a class="header-anchor" href="#inline-price" href="#inline-price" title="Permalink to this heading">#</a></h1>
<h2 id="introduction" tabindex="-1">Introduction <a class="header-anchor" href="#introduction" href="#introduction" title="Permalink to this heading">#</a></h2>
<p>This custom element renders an inline price supporting various display options and configurations. It retrieves pricing information from WCS based on the provided Offer Selector ID.</p>
<p>See <a href="mas.html#terminology">MAS</a> to learn more.</p>
Expand Down Expand Up @@ -311,7 +305,7 @@ <h4 id="logs" tabindex="-1">Logs <a class="header-anchor" href="#logs" href="#lo
<pre><code id="log" class="language-html">
</code></pre>

</div>
</sp-theme>
</main>
<script type="module">
document.querySelectorAll('code.demo').forEach(el => {
Expand Down
Loading
Loading