stereobooster / react-snap

👻 Zero-configuration framework-agnostic static prerendering for SPAs
MIT License
5.07k stars 392 forks source link

Navigation Timeout Exceeded #240

Open stereobooster opened 6 years ago

stereobooster commented 6 years ago

Starting from version 1.18.0 there should be more details about this error. If you see Navigation Timeout Exceeded... and on the next line:

Tracked URLs that have not finished... or For...

You know what times out, go ahead and fix it.

But there are no pending connections

If you see this message, please report it here. It would be nice if you have reproducible example. I suspect this is a bug in puppeteer. I need reproducible examples to report it to puppeteer tracker.

Thanks.

In react-snap@1.10.x this error looks like

🔥  /path Error: Protocol error (Runtime.callFunctionOn): Target closed.

Possibly related puppeteer bugs

I suspect that the bug which causes this issue is https://github.com/GoogleChrome/puppeteer/issues/1454, which was introduced after Puppeteer 0.13.0. That is why downgrading react-snap to 1.10.0 works, because in 1.11.0 Puppeteer dependency was bumped to 1.0.0

Other:

Possible workarounds

Created those branches:

stereobooster commented 6 years ago

cc @lewisdonovan @cascornelissen @yantakus

nickjanssen commented 6 years ago

Been struggling with this for a long time. I've noticed something interesting: when you launch using headless: false and then open the network tab while Chrome is running, the page will suddenly load correctly.

Also been getting But there are no pending connections all the time. In our case Intercom is being loaded, maybe that's why networkidle0 is never fired?

Anyway I've found a workaround: simply changing await page.goto(pageUrl, { waitUntil: "networkidle0" }); to await page.goto(pageUrl, { waitUntil: "load" }); works flawlessly for me.

Reference: https://github.com/GoogleChrome/puppeteer/blob/v1.7.0/docs/api.md#pagegotourl-options

GautierT commented 6 years ago

@nickjanssen : thanks for this ! I forked and switch to load and it's now working well !

stereobooster commented 6 years ago

Be aware this is not universal solution, it can happen that react-snap silently fail to prerender something and you will not even notice it. You need to be careful here, because manipulation happens after all linters, tests, type checks, builds etc. So it can be pretty fragile, that is why react-snap so verbose with all message and warnings

GautierT commented 6 years ago

Thanks for this clarification. But it's the only way i found to avoid random Navigation Timeout Exceeded and missing cached page.

stereobooster commented 6 years ago

In our case Intercom is being loaded, maybe that's why networkidle0 is never fired?

@nickjanssen I guess you need skip intercom in prerndering stage with this check if (navigator.userAgent!='ReactSnap') { loadIntercom() }

GautierT commented 6 years ago

I also have Intercom and i added a condition like you suggest to disable loading it but it doesn't change anything. Puppeteer has very weird behavior sometimes...

kristapsstrals commented 5 years ago

Can confirm that this is still an issue. I use firebase (firestore) to fetch data on the landing page and that seems to introduce the timeout issue. Before that component react-snap worked fine. Also, changing the networkidle0 to load does work as well.

psyked commented 5 years ago

To chime in on this, I've just managed to resolve an issue I was having by downgrading my the version of react-snap from ^1.23.0 to ~1.10.0.

For my scenario we build inside Docker, and our package.json file uses the following config:

    "reactSnap": {
        "puppeteerArgs": [
            "--no-sandbox",
            "--disable-setuid-sandbox"
        ],
        "concurrency": 1,
        "inlineCss": false,
        "skipThirdPartyRequests": false
    }

We need to skip the third party requests because these are analytics tools that don't start up correctly if we prerender them. With "skipThirdPartyRequests": false everything works, but our analytics doesn't. But "skipThirdPartyRequests": true we got a timeout error.

Turns out it was all down to this same issue!

rohan-deshpande commented 5 years ago

What's weird is I am not fetching any data from third parties and am still getting this issue. Could the CRA service worker be causing it somehow I wonder...

goleary commented 4 years ago

I get no indication of what has timed out: image

mysterycommand commented 4 years ago

Hey there … I've also gotten this error and had for a while just given up on the idea of getting a WebGL context to render screenshots via react-snap (love this library for everything else though).

Yesterday I was updating some other dependencies and got sucked back into this rabbit hole. This morning I stumbled across https://github.com/puppeteer/puppeteer/issues/5306 which lead me to try implementing a simplified version of @paulirish's requestAnimationFrame polyfill (acutally based on this version) … but just override the native rAF … and, it works now!

No special puppeteerArgs or other config overrides required. No overriding the waitUntil config either … I guess headless Chromium just doesn't call requestAnimationFrame? Idk if this is exactly the same issue (though the error message seems exactly the same) … maybe Intercom and/or Firebase is using rAF to throttle/debounce some work in their libraries?

Anyway, fork is here https://github.com/stereobooster/react-snap/compare/master...mysterycommand:feat/shim-requestAnimationFrame … happy to open a PR if you think it's worthy. 🙏 🙇 ❤️

dHannasch commented 4 years ago

I am trying to add react-snap to https://github.com/raulcostajunior/react_sudoku. I followed these instructions:

Install:

npm install --save react-snap

Change package.json:

"scripts": {
  "postbuild": "react-snap"
}

Change src/index.js (for React 16+):

import { hydrate, render } from "react-dom";

const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
  hydrate(<App />, rootElement);
} else {
  render(<App />, rootElement);
}

And this is the output (probably more than you actually care about):

$ npm run build

> react_sudoku@0.1.0 build /tmp/react_sudoku
> react-scripts build

Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  45.01 KB (-257 B)  build/static/js/2.d110a93f.chunk.js
  3.63 KB (-3 B)     build/static/js/main.d373e0ce.chunk.js
  775 B              build/static/js/runtime-main.9f731acc.js
  370 B              build/static/css/main.ceaa5c7a.chunk.css

The project was built assuming it is hosted at the server root.
You can control this with the homepage field in your package.json.
For example, add this to build it for GitHub Pages:

  "homepage" : "http://myname.github.io/myapp",

The build folder is ready to be deployed.
You may serve it with a static server:

  npm install -g serve
  serve -s build

Find out more about deployment here:

  bit.ly/CRA-deploy

> react_sudoku@0.1.0 postbuild /tmp/react_sudoku
> react-snap

🔥  error at / { TimeoutError: Navigation Timeout Exceeded: 30000ms exceeded
    at Promise.then (/tmp/react_sudoku/node_modules/puppeteer/lib/LifecycleWatcher.js:142:21)
  -- ASYNC --
    at Frame.<anonymous> (/tmp/react_sudoku/node_modules/puppeteer/lib/helper.js:111:15)
    at Page.goto (/tmp/react_sudoku/node_modules/puppeteer/lib/Page.js:674:49)
    at Page.<anonymous> (/tmp/react_sudoku/node_modules/puppeteer/lib/helper.js:112:23)
    at fetchPage (/tmp/react_sudoku/node_modules/react-snap/src/puppeteer_utils.js:232:22)
    at process._tickCallback (internal/process/next_tick.js:68:7) name: 'TimeoutError' }

There is nothing about "Tracked URLs that have not finished", although this is react-snap 1.23.0.

npm install --save react-snap@1.10.0 makes npm run build go through without error.

aptlin commented 4 years ago

Encountered the problem described by @dHannasch, any updates?

nbaillie commented 4 years ago

Also having this issue. I would be happy to exclude the paths that are causing this on my app is there a way to do that? ( the issue is with my reviews page that takes some time to load all the data.)

yellowbang commented 4 years ago

I downgrade to 1.10.0 as many people suggest and it works. However, some css files are not imported properly. Any better solution beside downgrade to 1.10.0?

goleary commented 4 years ago

I ended up converting my app to Gatsby partly to get around this 😱. I suppose there were some other benefits to doing it...

FreyrThorv commented 4 years ago

+1 regarding downgrading to 1.10.0, it worked for me too.

dang1412 commented 3 years ago

I found out that firebase has this request, looks like it take long time in the Chrome debug network tab

Request URL: https://firestore.googleapis.com/google.firestore.v1.Firestore/Listen/channel?database=projects%2Fcodetube-vn%2Fdatabases%2F(default)&gsessionid=whXYSBz7qWXJcmfG0mF_ugVmcnRdZt2b&VER=8&RID=rpc&SID=Ytrhm_Mi403dKC-B-IwsbQ&CI=0&AID=0&TYPE=xmlhttp&zx=ytiov93d2ood&t=1
Request Method: GET

I only use this to get data, the request is done properly but perhaps it has extra side effect

await db.collection('db').doc(id).get()
dang1412 commented 3 years ago

It seems caused by firebase rpc request? When I switch to firestore REST api request it runs ok ✅

squalvj commented 3 years ago

+1 downgrading to 1.10.0 works

skazi019 commented 2 years ago

+1 downgrading to 1.10.0 works