Skip to content

Commit

Permalink
fix(storefront): Setup $firstInteraction and $delayedAsyncScripts
Browse files Browse the repository at this point in the history
… on head scripts

Moving from client:sf directive source to base head, client:sf may be not used for some pages (SPA, blog...)
  • Loading branch information
leomp12 committed May 8, 2024
1 parent 5d85e60 commit b48a741
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 66 deletions.
2 changes: 1 addition & 1 deletion packages/storefront/client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ interface Window {
modulesInfoPreset?: Partial<typeof import('./src/lib/state/modules-info').default>,
};
$delayedAsyncScripts?: string[];
$firstInteraction?: Promise<void>;
$firstInteraction?: Promise<any>;
$prefetch?: typeof import('astro:prefetch').prefetch;
$isCmsPreview?: boolean;
}
Expand Down
57 changes: 3 additions & 54 deletions packages/storefront/config/astro/client-sf-directive.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,59 +14,6 @@ const waitIntersection = (el) => new Promise((resolve) => {
}
});

const firstInteraction = new Promise((resolve) => {
const controller = new AbortController();
[
'keydown',
'mousemove',
'pointerdown',
'touchstart',
'scroll',
].forEach((evName) => {
document.addEventListener(
evName,
() => {
resolve();
controller.abort();
window.dispatchEvent(new Event('firstInteraction'));
},
{ once: true, passive: true, signal: controller.signal },
);
});
});
window.$firstInteraction = firstInteraction;

if (!window.$delayedAsyncScripts) {
window.$delayedAsyncScripts = [];
const raceAndLoadScripts = () => Promise.race([
firstInteraction,
new Promise((resolve) => { setTimeout(resolve, 2000); }),
]).then(() => {
const loadDelayedScripts = () => {
window.$delayedAsyncScripts.forEach((src) => {
const script = document.createElement('script');
script.async = true;
script.src = src;
document.body.appendChild(script);
});
};
setTimeout(() => {
if (typeof window.requestIdleCallback === 'function') {
window.requestIdleCallback(loadDelayedScripts);
return;
}
loadDelayedScripts();
}, 200);
});
if (document.readyState !== 'loading') {
raceAndLoadScripts();
} else {
document.addEventListener('DOMContentLoaded', () => {
setTimeout(raceAndLoadScripts, 50);
});
}
}

/**
* Hydrate on context script executed (`$storefront.apiContext` ready)
* Check event emits at BaseHead.astro and use-shared-data.ts
Expand All @@ -85,7 +32,9 @@ export default (load, opts, el) => {
const isLazy = !arrOpts.length || arrOpts.includes('lazy');
const isEager = !isLazy && arrOpts.includes('eager');
const hy = async () => {
if (arrOpts.includes('interaction')) await firstInteraction;
if (arrOpts.includes('interaction') && window.$firstInteraction) {
await window.$firstInteraction;
}
const hydrate = await load();
await hydrate();
};
Expand Down
77 changes: 66 additions & 11 deletions packages/storefront/src/lib/layouts/BaseHead.astro
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,6 @@ if (!ogImage) {
}
let inlineClientJS = `
window._emitApiContext = (id = null) => {
$storefront.url = new URL(window.location.toString());
$storefront.getSession = (/* sid */) => ({
url: $storefront.url,
apiContext: $storefront.apiContext,
});
console.debug('[ctx] emit ' + id);
window.dispatchEvent(new Event('storefront:apiContext'));
window._emitedContextId = id;
window.__sfIds = {};
};
window.ECOM_STORE_ID = ${storeId};
window.ECOM_LANG = '${lang}';
window.ECOM_CURRENCY = '${currency}';
Expand Down Expand Up @@ -208,6 +197,72 @@ const generator = `e-com.plus @cloudcommerce/storefront, ${Astro.generator}`;
&& <link rel="manifest" href="/manifest.webmanifest" />}
</>}

<script is:inline>
const firstInteraction = new Promise((resolve) => {
const controller = new AbortController();
[
'keydown',
'mousemove',
'pointerdown',
'touchstart',
'scroll',
].forEach((evName) => {
document.addEventListener(
evName,
() => {
resolve();
controller.abort();
window.dispatchEvent(new Event('firstInteraction'));
},
{ once: true, passive: true, signal: controller.signal },
);
});
});
window.$firstInteraction = firstInteraction;
if (!window.$delayedAsyncScripts) {
window.$delayedAsyncScripts = [];
const raceAndLoadScripts = () => Promise.race([
firstInteraction,
new Promise((resolve) => { setTimeout(resolve, 3000); }),
]).then(() => {
const loadDelayedScripts = () => {
window.$delayedAsyncScripts.forEach((src) => {
const script = document.createElement('script');
script.async = true;
script.src = src;
document.body.appendChild(script);
});
};
setTimeout(() => {
if (typeof window.requestIdleCallback === 'function') {
window.requestIdleCallback(loadDelayedScripts);
return;
}
loadDelayedScripts();
}, 200);
});
if (document.readyState !== 'loading') {
raceAndLoadScripts();
} else {
document.addEventListener('DOMContentLoaded', () => {
setTimeout(raceAndLoadScripts, 50);
});
}
}
window._emitApiContext = (id = null) => {
const { $storefront } = window;
$storefront.url = new URL(window.location.toString());
$storefront.getSession = (/* sid */) => ({
url: $storefront.url,
apiContext: $storefront.apiContext,
});
console.debug('[ctx] emit ' + id);
window.dispatchEvent(new Event('storefront:apiContext'));
window._emitedContextId = id;
window.__sfIds = {};
};
</script>

<script is:inline set:html={inlineClientJS} />
<script is:inline type="application/ld+json" set:html={inlineJSONLd} />

Expand Down

0 comments on commit b48a741

Please sign in to comment.