0

Background

I want to navigate to multiple websites in separate browser tabs programmatically. Ideally, I want to be able to have these websites loading in parallel, when the code is triggered.

Problem

As a proof of concept, I have the following code to open a browser through a command.

const { exec } = require("child_process");

exec('xdg-open https://www.google.com').on('exit', () => {console.log('child 1 exited')})
exec('xdg-open https://www.github.com').on('exit', () => {console.log('child 2 exited')})

What happens when I run the code above:

  1. Both child 1 exited and child 2 exited were logged almost immediately after I run the code
  2. A browser tab opens and starts loading one of the pages. I had to wait about 3 seconds after the first page is loaded, before the 2nd tab opens and starts loading the second page.

++

I expected both tabs to open and start loading the pages almost at the same time, but this is not happening.

Other Observations

I tried running xdg-open https://www.google.com and xdg-open https://www.github.com in separate terminals (executing both at around the same time), and I am able to have 2 tabs open and start loading pages at around the same time (this is the behavior I am aiming for)

However, the code above seems to behave similarly to running xdg-open https://www.google.com && xdg-open https://www.github.com

Question

If exec() spawns a new child_process, why is the code above not triggering multiple page navigations simultaneously? How do I achieve this behavior?

artze
  • 511
  • 1
  • 4
  • 18
  • Not able to reproduce this. Worked fine for me - both tabs opened at the same time. OS - MacOS 10.15.7 – Archit Apr 14 '21 at 05:53
  • @Archit I see. Will try it on a Mac. The behavior above was observed on Ubuntu – artze Apr 14 '21 at 23:30

2 Answers2

0

I would suggest you to use open from npm. It will be a good option to just open multiple URLs from the Node.js APP.

const open = require('open');

const main = async () => {
  await open('https://www.github.com');
  await open('https://google.com');
}

main();

This code will open these URLs in parallel and it will open in the default browser selected. However, you can change the configuration in open to pass dynamic configuration to it. Please check here for more details.

You should not use the child_process to open such task as it doesn't require any computation. These are generally called when CPU is unable to handle the blocking requests as Node.js main loop runs on single thread. You can check here for more details when to use child_process.

Apoorva Chikara
  • 8,277
  • 3
  • 20
  • 35
  • I tried this lib too, and found that it does not open multiple URLs in parallel, i.e. there is a delay in between, which is similar to the behavior in my original post. – artze Apr 14 '21 at 23:28
  • How much delay are you encountering? Does it hampering the flow? – Apoorva Chikara Apr 15 '21 at 04:01
  • The delay is similar to what I described in the original post. If you look at the `open` source code, a `child_procssed` is summoned under the hood as well. – artze Apr 15 '21 at 09:43
  • I realized that this issue only happens if i'm using `open` with firefox. Getting `open` to use chrome, for example, is able to open multiple websites without delay. – artze Apr 17 '21 at 06:51
0

I found this issue to only occur when my default browser is set to Firefox. If my default browser is set to chrome, both browser tabs will open at the same time and start fetching data from both websites (at the same time).

I'm posting this observation here in case someone might find it useful, but I have not come across a solution to make this work with Firefox.

EDIT:

More Observations

When I tried to open more websites in the same way (e.g. 10 websites), firefox will open in 2 batches (with some delay in between each batch). In each batch, multiple websites will open concurrently. So far, it seems like it will always open in 2 batches.

artze
  • 511
  • 1
  • 4
  • 18