-
Notifications
You must be signed in to change notification settings - Fork 283
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
Largest Contentful Paint image was lazily loaded #146
Comments
Good catch. I have a pretty aggressive optimization for my own site that renders pages in puppeteer and stores the information as to whether they appear above the fold. const fs = require("fs-extra");
const puppeteer = require("puppeteer");
const updateHeroImages = async (content, outputPath) => {
if (
!outputPath.endsWith(".html") ||
isAmp(content) ||
// Must have an image element to be interesting.
!/<img/.test(content)
) {
return content;
}
const images = {};
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.emulate(puppeteer.devices["Pixel 2"]);
await page.setContent(content, {
waitUntil: "domcontentloaded",
});
for (let i of await page.$$("img")) {
const img = await page.evaluate((i) => {
const { top, left, bottom, right } = i.getBoundingClientRect();
return {
src: i.getAttribute("src"),
rect: {
top: Math.round(top),
left: Math.round(left),
bottom: Math.round(bottom),
right: Math.round(right),
},
};
}, i);
if (!images[img.src]) {
images[img.src] = {
isInFirstMobileViewport: img.rect.top < 830,
rect: img.rect,
};
}
}
} finally {
await browser.close();
}
if (Object.keys(images).length) {
const filename = `_data/images.json`;
const allImages = JSON.parse(fs.readFileSync(filename));
allImages[outputPath] = images;
fs.writeFileSync(filename, JSON.stringify(allImages, null, " "));
}
return content;
};
module.exports = {
initArguments: {},
configFunction: async (eleventyConfig, pluginOptions = {}) => {
if (!process.env.UPDATE_HERO_IMAGES) {
return;
}
eleventyConfig.addTransform("updateHeroImages", updateHeroImages);
},
};
function isAmp(content) {
return /\<html[^>]* amp/i.test(content);
} I didn't put this into the open-source code because it is too slow to run on every render and I wanted to avoid complicating the template too much. See how it is guarded with Maybe the right solution is to simply default to eager for the first N images by default. |
Ok great! I knew this would be fairly complex or heavy to do properly. I was also thinking about first N images by default even though it's not the perfect solution. |
Ideally I wish we could label an image for eager or lazy loading....because
its a matter of perspective of blog owner /post author but after
explaining the various cavears...so as to which image needs to be rendered
immediately or not. Obviously hero images need to; above the fold would
depend on UA's form factor. Also an important factor, UA's internet speed,
an important consideration here in India and other such similar regions.
…On Sun, Aug 21, 2022 at 8:26 PM Malte Ubl ***@***.***> wrote:
Good catch. I have a pretty aggressive optimization for my own site that
renders pages in puppeteer and stores the information as to whether they
appear above the fold.
const fs = require("fs-extra");const puppeteer = require("puppeteer");
const updateHeroImages = async (content, outputPath) => {
if (
!outputPath.endsWith(".html") ||
isAmp(content) ||
// Must have an image element to be interesting.
!/<img/.test(content)
) {
return content;
}
const images = {};
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.emulate(puppeteer.devices["Pixel 2"]);
await page.setContent(content, {
waitUntil: "domcontentloaded",
});
for (let i of await page.$$("img")) {
const img = await page.evaluate((i) => {
const { top, left, bottom, right } = i.getBoundingClientRect();
return {
src: i.getAttribute("src"),
rect: {
top: Math.round(top),
left: Math.round(left),
bottom: Math.round(bottom),
right: Math.round(right),
},
};
}, i);
if (!images[img.src]) {
images[img.src] = {
isInFirstMobileViewport: img.rect.top < 830,
rect: img.rect,
};
}
}
} finally {
await browser.close();
}
if (Object.keys(images).length) {
const filename = `_data/images.json`;
const allImages = JSON.parse(fs.readFileSync(filename));
allImages[outputPath] = images;
fs.writeFileSync(filename, JSON.stringify(allImages, null, " "));
}
return content;};
module.exports = {
initArguments: {},
configFunction: async (eleventyConfig, pluginOptions = {}) => {
if (!process.env.UPDATE_HERO_IMAGES) {
return;
}
eleventyConfig.addTransform("updateHeroImages", updateHeroImages);
},};
function isAmp(content) {
return /\<html[^>]* amp/i.test(content);}
I didn't put this into the open-source code because it is too slow to run
on every render and I wanted to avoid complicating the template too much.
See how it is guarded with UPDATE_HERO_IMAGES. I run this in a Github
Action as a cron a couple times a day to gather the data.
Maybe the right solution is to simply default to eager for the first N
images by default.
—
Reply to this email directly, view it on GitHub
<#146 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAQAQZD7ERZ4FA4CFHIDTBDV2I7TJANCNFSM57EBNAJA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***
com>
|
I'm trying to get perfect lighthouse scores.
When having an image in the Largest Contentful Paint (LCP) you get this warning when running Google Lighthouse Tests
⚠️ Largest Contentful Paint image was lazily loaded
My example
https://rossdallaire.com/notes/tv-interfaces-can-be-hard-to-find-active-selection/
https://pagespeed.web.dev/report?url=https%3A%2F%2Frossdallaire.com%2Fnotes%2Ftv-interfaces-can-be-hard-to-find-active-selection%2F&form_factor=mobile
When I look at the Industrial Empathy post that has an LCP image it has
loading="eager"
on the first image.https://www.industrialempathy.com/posts/viral-software-deadlines/
I'm wondering if I did something incorrectly or it looks like there needs to be an updated way to detect LCP image and load it differently.
I haven't tried anything but I'm assuming it has something to do in img-dim.js
https://github.com/google/eleventy-high-performance-blog/blob/main/_11ty/img-dim.js#L91
May explore further if no one else takes a look.
The text was updated successfully, but these errors were encountered: