Skip to content

Commit

Permalink
MWPW-163603 benchmark card rendering time in PR (#3377)
Browse files Browse the repository at this point in the history
* MWPW-163602 draft

* some fixes

* add benchmark test to Nala

* fix adjust

* bring adjusted limit to nala too

* MWPW-163603 review comments

* forgot to rebuild docs

* review comments

* latest

* make sidenav smaller :)

* yet a bit smaller :)

* fix benchmark selector

* use aside

* desperate try to fool cov

---------

Co-authored-by: cod23684 <cod23684@adobe.com>
  • Loading branch information
npeltier and afmicka authored Jan 13, 2025
1 parent c582faa commit b6e2bcd
Show file tree
Hide file tree
Showing 27 changed files with 623 additions and 326 deletions.
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) => {
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';
const init = () => {
const ENVS = {
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

0 comments on commit b6e2bcd

Please sign in to comment.