Skip to content
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

[OPTIMISATION] fetch platform specific chrome image #518

Open
wants to merge 4 commits into
base: primary
Choose a base branch
from

Conversation

realityzero
Copy link

desc: Environment specific chromium image selection on development environment

Copy link

vercel bot commented Mar 4, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
tiny-helpers ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 14, 2024 8:29am

.env.example Outdated
@@ -0,0 +1 @@
NODE_ENV=development
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make development the default and change the conditions to detect the production environment instead? Then we wouldn't need the env file locally.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. That's a nice catch since there are no other envs we can default to dev.

@@ -252,6 +252,13 @@ npm run dev
<sub><b>Gonçalo Morais</b></sub>
</a>
</td>
<td align="center">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI — this readme section was broken for a while and when we're at it, i'll probably remove it because it doesn't show all contributoes.

Your avatar will still be shown on tiny-helpers.dev though.

image

console.log('exePath:', exePath);
if (isDev) {
options = {
args: [],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why args and defaultViewport are locally different than in prod?

Ahh. I see — because chromium isn't available. Could we still add --hide-scrollbars and --disable-web-security? 🤔

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@stefanjudis
Copy link
Owner

@realityzero Welcome to TH and thank you so much for contributing. 💯

This topic has been on the list for ages so I'm exited that someone is tackling it. I've left some comments and on the way and will test is locally once we discussed these.

Thanks again and have a great day!

@realityzero
Copy link
Author

@realityzero Welcome to TH and thank you so much for contributing. 💯

This topic has been on the list for ages so I'm exited that someone is tackling it. I've left some comments and on the way and will test is locally once we discussed these.

Thanks again and have a great day!

woahh @stefanjudis this made my day

@stefanjudis
Copy link
Owner

@realityzero I just checked out the branch and have run vercel dev (I should document this 🤦‍♂️ ).

Unfortunately, it's not working locally and I'm running in target closed errors.

Error log

> Ready! Available at http://localhost:3000
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
TargetCloseError: Protocol error (Page.captureScreenshot): Target closed
    at CallbackRegistry.clear (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/src/common/Connection.ts:186:30)
    at CDPSessionImpl._onClosed (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/src/common/Connection.ts:611:21)
    at Connection.#onClose (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/src/common/Connection.ts:363:15)
    at WebSocket. (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/src/common/NodeWebSocketTransport.ts:60:22)
    at callListener (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/node_modules/ws/lib/event-target.js:290:14)
    at WebSocket.onClose (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/node_modules/ws/lib/event-target.js:220:9)
    at WebSocket.emit (node:events:517:28)
    at WebSocket.emit (node:domain:489:12)
    at WebSocket.emitClose (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/node_modules/ws/lib/websocket.js:258:10)
    at Socket.socketOnClose (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/node_modules/ws/lib/websocket.js:1264:15)
Error: Navigation failed because browser has disconnected!
    at new LifecycleWatcher (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/src/common/LifecycleWatcher.ts:109:11)
    at Frame.goto (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/src/common/Frame.ts:108:21)
    at CDPPage.goto (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/src/common/Page.ts:923:35)
    at getScreenshot (/Users/stefanjudis/Projects/github.com/tiny-helpers/api/screenshot.js:62:14)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async module.exports (/Users/stefanjudis/Project
    ...
    ...

What's your local setup to test this?

@realityzero
Copy link
Author

@stefanjudis Apologies for getting onto this quite late. I couldn't test the solution end to end locally from tiny-helpers project. However, I followed the same abstracted approach of picking platform specific chromium in one of my recent projects: ScrapifyX.

That's my bad.

Could you please try this out: Stackoverflow

Or just tell me how to invoke screenshot.js after running this project. I was unable to find any references from UI.

@stefanjudis
Copy link
Owner

@realityzero

Apologies for getting onto this quite late.

No worries. I'm still very grateful that you're taking this on! 🎉

Or just tell me how to invoke screenshot.js after running this project.

That's my bad. As this project is deployed to vercel I run it via the CLI which I have installed globally.

$ vercel dev
Vercel CLI 33.6.0
> Running Dev Command “npx @11ty/eleventy --serve --watch --port $PORT”
Writing _site/index.html from ./site/index.html.
Writing _site/home/latest/index.html from ./site/tag-sorted-by-date.njk.
Writing _site/home/index.html from ./site/tag.njk.
...
...
[Browsersync] Access URLs:
 ----------------------------------------
       Local: http://localhost:3000
    External: http://192.168.178.88:3000
 ----------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 ----------------------------------------
[Browsersync] Serving files from: _site
> Ready! Available at http://localhost:3000
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
exePath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
TargetCloseError: Protocol error (Page.captureScreenshot): Target closed
    at CallbackRegistry.clear (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/src/common/CallbackRegistry.ts:93:30)
    at CdpCDPSession._onClosed (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/src/cdp/CDPSession.ts:149:21)
    at Connection.#onClose (/Users/stefanjudis/Projects/github.com/tiny-helpers/node_modules/puppeteer-core/src/cdp/Connection.ts:205:15)
...

I also looked briefly into this and no SO magic helped out for the local screenshoting. :/

@realityzero
Copy link
Author

@stefanjudis
Whenever I've read TargetCloseError or Target closed in Puppeteer, it is almost always a memory issue. Can you try adding adding following args:

  1. Let's just add this first --disable-dev-shm-usage
  2. If it still breaks, add one more argument --shm-size=3gb

Ref:

puppeteer/puppeteer#1790
puppeteer/puppeteer#1175

@stefanjudis
Copy link
Owner

@realityzero Unfortunately, neither of the options work.

I'm still running into the same exceptions. Did you try the Vercel CLI to see how to tackle it?

@realityzero
Copy link
Author

Hey @stefanjudis ! Apologies man for such a late reply. Certain life challenges.

I did some debugging locally in two different stages.

  1. Look at this diff (github wasn't allowing me to upload a .patch file)
diff --git a/api/screenshot.js b/api/screenshot.js
index c285f0c..8be5f87 100644
--- a/api/screenshot.js
+++ b/api/screenshot.js
@@ -27,7 +27,7 @@ async function getOptions(isProd) {
         options = {
           args,
           executablePath: exePath,
-          headless: 'new',
+          headless: false,
         };
     }
     return options;
@@ -57,7 +57,7 @@ function checkUrl(string) {
   return true;
 }
 
-export async function getScreenshot(url, ratio = 1) {
+async function getScreenshot(url, ratio = 1) {
   const page = await getPage();
   await page.goto(url, {
     waitUntil: 'domcontentloaded',
@@ -68,6 +68,8 @@ export async function getScreenshot(url, ratio = 1) {
     devicePixelRatio: ratio,
   });
   const file = await page.screenshot();
+  const base64Image = new Buffer(file).toString('base64');
+  console.log('done w/ SS:', base64Image);
   return file;
 }
 
@@ -92,3 +94,6 @@ module.exports = async (req, res) => {
       );
   }
 };
+
+
+getScreenshot('https://news.ycombinator.com/item?id=39894820#39916444', 1);
\ No newline at end of file

I simply executed node screenshot.js. Here I was able to get a base64 and used some base64 to image converted online and it went fine.
2. I tried vercel dev command to replicate the same connection level thing of deployment. However I couldn't navigate to a page that takes screenshots. I might need help in that. But it triggered screenshot.js behind the scenes in terminal and executed same thing as point 1.

How about we get over a call for this in the coming week?

@stefanjudis
Copy link
Owner

stefanjudis commented May 13, 2024

@realityzero Hey, so sorry for letting this slip through. :/ Life's pretty wild on my end.

But in the meantime, something changed on vercel's side and things broke entirely. I think I'll move the screenshots off serverless fns. It's just to briddle. ;/

Sorry for wasting your time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants