From ed14dff9e8eb26639ccfd7f13634b9e042ec8720 Mon Sep 17 00:00:00 2001 From: Frank <25704248+rakuzen25@users.noreply.github.com> Date: Sun, 14 Jun 2026 19:51:04 -0500 Subject: [PATCH 1/4] feat(screenshot): implement lazy load --- source/plugins/community/screenshot/index.mjs | 44 +++++++++++++++++-- .../plugins/community/screenshot/metadata.yml | 8 ++++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/source/plugins/community/screenshot/index.mjs b/source/plugins/community/screenshot/index.mjs index 2c4d5521678..23490e87a50 100644 --- a/source/plugins/community/screenshot/index.mjs +++ b/source/plugins/community/screenshot/index.mjs @@ -7,7 +7,7 @@ export default async function({login, q, imports, data, account}, {enabled = fal return null //Load inputs - let {url, selector, title, background, viewport, wait, mode} = imports.metadata.plugins.screenshot.inputs({data, account, q}) + let {url, selector, title, background, viewport, lazyload, wait, mode} = imports.metadata.plugins.screenshot.inputs({data, account, q}) if (!url) throw {error: {message: "URL is not set"}} @@ -19,6 +19,40 @@ export default async function({login, q, imports, data, account}, {enabled = fal await page.setViewport(viewport) console.debug(`metrics/compute/${login}/plugins > screenshot > loading ${url}`) await page.goto(url, {waitUntil: ["domcontentloaded", "networkidle2"]}) + + await page.waitForSelector(selector) + if (lazyload) { + await page.evaluate(async sel => { + const element = document.querySelector(sel) + if (!element) + return + + //Progressive scroll + await new Promise(resolve => { + const timer = setInterval(() => { + const rect = element.getBoundingClientRect() + if (rect.bottom <= window.innerHeight || window.scrollY + window.innerHeight >= document.body.scrollHeight) { + clearInterval(timer) + resolve() + } + else { + window.scrollBy(0, 300) + } + }, 100) + }) + + await Promise.all([...element.querySelectorAll("img")].map(img => + new Promise(solve => { + if (img.complete) + solve() + else { + img.addEventListener("load", solve) + img.addEventListener("error", solve) + } + }) + )) + }, selector) + } if (wait) await new Promise(solve => setTimeout(solve, wait)) @@ -26,12 +60,16 @@ export default async function({login, q, imports, data, account}, {enabled = fal let content = null let image = null const metadata = {height: null, width: null} - await page.waitForSelector(selector) switch (mode) { case "image": { const clip = await page.evaluate(selector => { const {x, y, width, height} = document.querySelector(selector).getBoundingClientRect() - return {x, y, width, height} + return { + x: x + window.scrollX, + y: y + window.scrollY, + width, + height, + } }, selector) console.debug(`metrics/compute/${login}/plugins > screenshot > coordinates ${JSON.stringify(clip)}`) const [buffer] = await imports.record({page, ...clip, frames: 1, background}) diff --git a/source/plugins/community/screenshot/metadata.yml b/source/plugins/community/screenshot/metadata.yml index 338ea57fef6..957e0b55e2d 100644 --- a/source/plugins/community/screenshot/metadata.yml +++ b/source/plugins/community/screenshot/metadata.yml @@ -65,6 +65,14 @@ inputs: "height": 1280 } + plugin_screenshot_lazyload: + description: | + Progressively scroll to the selected element and wait for images to load before taking the screenshot + + When combined with `plugin_screenshot_wait`, wait will happen after lazy loading is complete + type: boolean + default: no + plugin_screenshot_wait: description: | Wait time before taking screenshot (ms) From 85a2622d031e36c491f950714178e46eeaad8e46 Mon Sep 17 00:00:00 2001 From: Frank <25704248+rakuzen25@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:04:58 -0500 Subject: [PATCH 2/4] docs: update lazy load description Signed-off-by: Frank <25704248+rakuzen25@users.noreply.github.com> --- source/plugins/community/screenshot/metadata.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/plugins/community/screenshot/metadata.yml b/source/plugins/community/screenshot/metadata.yml index 957e0b55e2d..89df8f4da55 100644 --- a/source/plugins/community/screenshot/metadata.yml +++ b/source/plugins/community/screenshot/metadata.yml @@ -67,6 +67,8 @@ inputs: plugin_screenshot_lazyload: description: | + Lazy load images + Progressively scroll to the selected element and wait for images to load before taking the screenshot When combined with `plugin_screenshot_wait`, wait will happen after lazy loading is complete From a399eeaff370068c3eafd29f3dc340d0d5cdc4d7 Mon Sep 17 00:00:00 2001 From: Eli <88557639+lishaduck@users.noreply.github.com> Date: Fri, 26 Jun 2026 20:54:25 -0500 Subject: [PATCH 3/4] fix: spellcheck --- source/plugins/community/screenshot/index.mjs | 2 +- source/plugins/community/screenshot/metadata.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/plugins/community/screenshot/index.mjs b/source/plugins/community/screenshot/index.mjs index 23490e87a50..252c331bb52 100644 --- a/source/plugins/community/screenshot/index.mjs +++ b/source/plugins/community/screenshot/index.mjs @@ -7,7 +7,7 @@ export default async function({login, q, imports, data, account}, {enabled = fal return null //Load inputs - let {url, selector, title, background, viewport, lazyload, wait, mode} = imports.metadata.plugins.screenshot.inputs({data, account, q}) + let {url, selector, title, background, viewport, lazy_load: lazyload, wait, mode} = imports.metadata.plugins.screenshot.inputs({data, account, q}) if (!url) throw {error: {message: "URL is not set"}} diff --git a/source/plugins/community/screenshot/metadata.yml b/source/plugins/community/screenshot/metadata.yml index 89df8f4da55..a3281c4525f 100644 --- a/source/plugins/community/screenshot/metadata.yml +++ b/source/plugins/community/screenshot/metadata.yml @@ -65,7 +65,7 @@ inputs: "height": 1280 } - plugin_screenshot_lazyload: + plugin_screenshot_lazy_load: description: | Lazy load images From 7ddaf6104b5f652996c57bee1830c7efcfeff66e Mon Sep 17 00:00:00 2001 From: Eli <88557639+lishaduck@users.noreply.github.com> Date: Fri, 26 Jun 2026 20:59:56 -0500 Subject: [PATCH 4/4] right --- source/plugins/community/screenshot/index.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/plugins/community/screenshot/index.mjs b/source/plugins/community/screenshot/index.mjs index 252c331bb52..d230604e1e7 100644 --- a/source/plugins/community/screenshot/index.mjs +++ b/source/plugins/community/screenshot/index.mjs @@ -7,7 +7,7 @@ export default async function({login, q, imports, data, account}, {enabled = fal return null //Load inputs - let {url, selector, title, background, viewport, lazy_load: lazyload, wait, mode} = imports.metadata.plugins.screenshot.inputs({data, account, q}) + let {url, selector, title, background, viewport, lazy_load: lazyLoad, wait, mode} = imports.metadata.plugins.screenshot.inputs({data, account, q}) if (!url) throw {error: {message: "URL is not set"}} @@ -21,7 +21,7 @@ export default async function({login, q, imports, data, account}, {enabled = fal await page.goto(url, {waitUntil: ["domcontentloaded", "networkidle2"]}) await page.waitForSelector(selector) - if (lazyload) { + if (lazyLoad) { await page.evaluate(async sel => { const element = document.querySelector(sel) if (!element)