Skip to content

Commit fa3a372

Browse files
committed
Optimize LCP loading times
1 parent accd362 commit fa3a372

File tree

1 file changed

+47
-36
lines changed

1 file changed

+47
-36
lines changed

libs/utils/utils.js

+47-36
Original file line numberDiff line numberDiff line change
@@ -446,27 +446,27 @@ export async function loadTemplate() {
446446
await Promise.all([styleLoaded, scriptLoaded]);
447447
}
448448

449-
export async function loadBlock(block) {
450-
if (block.classList.contains('hide-block')) {
451-
block.remove();
452-
return null;
453-
}
454-
449+
function getBlockData(block) {
455450
const name = block.classList[0];
456-
const hasStyles = AUTO_BLOCKS.find((ab) => Object.keys(ab).includes(name))?.styles ?? true;
457451
const { miloLibs, codeRoot, mep } = getConfig();
458-
459452
const base = miloLibs && MILO_BLOCKS.includes(name) ? miloLibs : codeRoot;
460453
let path = `${base}/blocks/${name}`;
461-
462454
if (mep?.blocks?.[name]) path = mep.blocks[name];
463-
464455
const blockPath = `${path}/${name}`;
456+
const hasStyles = AUTO_BLOCKS.find((ab) => Object.keys(ab).includes(name))?.styles ?? true;
457+
458+
return { blockPath, name, hasStyles };
459+
}
465460

461+
export async function loadBlock(block) {
462+
if (block.classList.contains('hide-block')) {
463+
block.remove();
464+
return null;
465+
}
466+
const { name, blockPath, hasStyles } = getBlockData(block);
466467
const styleLoaded = hasStyles && new Promise((resolve) => {
467468
loadStyle(`${blockPath}.css`, resolve);
468469
});
469-
470470
const scriptLoaded = new Promise((resolve) => {
471471
(async () => {
472472
try {
@@ -731,6 +731,8 @@ function decorateDefaults(el) {
731731
}
732732

733733
function decorateHeader() {
734+
const breadcrumbs = document.querySelector('.breadcrumbs');
735+
breadcrumbs?.remove();
734736
const header = document.querySelector('header');
735737
if (!header) return;
736738
const headerMeta = getMetadata('header');
@@ -744,7 +746,7 @@ function decorateHeader() {
744746
|| getConfig().breadcrumbs;
745747
if (metadataConfig === 'off') return;
746748
const baseBreadcrumbs = getMetadata('breadcrumbs-base')?.length;
747-
const breadcrumbs = document.querySelector('.breadcrumbs');
749+
748750
const autoBreadcrumbs = getMetadata('breadcrumbs-from-url') === 'on';
749751
const dynamicNavActive = getMetadata('dynamic-nav') === 'on'
750752
&& window.sessionStorage.getItem('gnavSource') !== null;
@@ -1221,41 +1223,50 @@ export function partition(arr, fn) {
12211223
);
12221224
}
12231225

1224-
async function processSection(section, config, isDoc) {
1225-
const inlineFrags = [...section.el.querySelectorAll('a[href*="#_inline"]')];
1226-
if (inlineFrags.length) {
1227-
const { default: loadInlineFrags } = await import('../blocks/fragment/fragment.js');
1228-
const fragPromises = inlineFrags.map((link) => loadInlineFrags(link));
1229-
await Promise.all(fragPromises);
1230-
const newlyDecoratedSection = decorateSection(section.el, section.idx);
1231-
section.blocks = newlyDecoratedSection.blocks;
1232-
section.preloadLinks = newlyDecoratedSection.preloadLinks;
1226+
const preloadBlocks = (section) => section?.blocks.map((block) => {
1227+
if (block.classList.contains('hide-block')) return null;
1228+
const { blockPath, hasStyles, name } = getBlockData(block);
1229+
if (name === 'marquee' || name === 'hero-marquee') {
1230+
loadLink(`${getConfig().base}/utils/decorate.js`, { rel: 'preload', as: 'script', crossorigin: 'anonymous' });
12331231
}
1234-
await decoratePlaceholders(section.el, config);
1232+
loadLink(`${blockPath}.js`, { rel: 'preload', as: 'script', crossorigin: 'anonymous' });
1233+
return hasStyles ? new Promise((resolve) => { loadStyle(`${blockPath}.css`, resolve); }) : null;
1234+
}).filter(Boolean);
1235+
1236+
async function resolveInlineFrags(section) {
1237+
const inlineFrags = [...section.el.querySelectorAll('a[href*="#_inline"]')];
1238+
if (!inlineFrags.length) return;
1239+
const { default: loadInlineFrags } = await import('../blocks/fragment/fragment.js');
1240+
const fragPromises = inlineFrags.map((link) => loadInlineFrags(link));
1241+
await Promise.all(fragPromises);
1242+
const newlyDecoratedSection = decorateSection(section.el, section.idx);
1243+
section.blocks = newlyDecoratedSection.blocks;
1244+
section.preloadLinks = newlyDecoratedSection.preloadLinks;
1245+
}
12351246

1247+
async function processSection(section, config, isDoc) {
1248+
await resolveInlineFrags(section);
1249+
const firstSection = section.el.dataset.idx === '0';
1250+
const stylePromises = firstSection ? preloadBlocks(section) : [];
1251+
await Promise.all([
1252+
decoratePlaceholders(section.el, config),
1253+
decorateIcons(section.el, config),
1254+
]);
1255+
const loadBlocks = [...stylePromises];
12361256
if (section.preloadLinks.length) {
1237-
const [modals, nonModals] = partition(section.preloadLinks, (block) => block.classList.contains('modal'));
1238-
const preloads = nonModals.map((block) => loadBlock(block));
1239-
await Promise.all(preloads);
1257+
const [modals, blockPreloads] = partition(section.preloadLinks, (block) => block.classList.contains('modal'));
1258+
blockPreloads.forEach((block) => loadBlocks.push(loadBlock(block)));
12401259
modals.forEach((block) => loadBlock(block));
12411260
}
12421261

1243-
const loaded = section.blocks.map((block) => loadBlock(block));
1244-
1245-
await decorateIcons(section.el, config);
1262+
section.blocks.forEach((block) => loadBlocks.push(loadBlock(block)));
12461263

12471264
// Only move on to the next section when all blocks are loaded.
1248-
await Promise.all(loaded);
1265+
await Promise.all(loadBlocks);
12491266

1250-
// Show the section when all blocks inside are done.
12511267
delete section.el.dataset.status;
1252-
1253-
if (isDoc && section.el.dataset.idx === '0') {
1254-
await loadPostLCP(config);
1255-
}
1256-
1268+
if (isDoc && firstSection) await loadPostLCP(config);
12571269
delete section.el.dataset.idx;
1258-
12591270
return section.blocks;
12601271
}
12611272

0 commit comments

Comments
 (0)