Search code examples
processelectronchromium

Does Electron have a standard way of killing a useless renderer process?


My app creates a window with a local page that requires node integration to be enabled.

After I click a button on this page, I am navigated to a third party page.

Because I want node to be disabled in this third party page, and I can't toggle node integration in a BrowserWindow, I load this third party page in a sandboxed BrowserView that is embedded inside of the window and is stretched to fit the entire screen.

Now doing this navigates the embedded view, but the BrowserWindow is stuck pointing to the old local page that is no longer relevant.

To prevent this extra page from sitting around in the background, I navigate my BrowserWindow to "about:blank" to effectively clear it out and make room for the BrowserView.

I am realizing now that while this "clears" out the old page, it keeps the renderer process that's associated with it alive. From here:

Chromium creates a renderer process for each instance of a site the user visits

And understandably, navigating to "about:blank" doesn't signal to Electron that it should kill the other process.

I want to get rid of this renderer process, so it doesn't sit around unnecessarily and use CPU and memory when I interact with the window.

Two things that have worked:

I removed the extra navigation to "about:blank" since we're now killing the process and:

1) When my button in my renderer sends a message to the main process telling it to create a BrowserView and navigate to the new site, I do a process.exit();. I guess a part of me is nervous about the process exit interfering with the message that gets queued up for main, though it seems to work fine.

2) Instead of killing the process from the renderer, I created and navigated my BrowserView and then ran a little browserWindow.webContents.executeJavascript("process.exit()");. I find this uglier, though it does mitigate by concern above in #1.

There isn't a webcontents.destroy() type of method, and I don't know of a way to signal to Electron that it needs to destroy this unnecessary process.

I suppose I might have a pretty unique case, but is there a nicer way (or more standard way) of handling this than explicitly doing a process.exit()?


Solution

  • There is now a WebContents::forcefullyCrashRenderer() API that accomplishes this (introduced by this PR):

    Forcefully terminates the renderer process that is currently hosting this webContents. This will cause the render-process-gone event to be emitted with the reason=killed || reason=crashed. Please note that some webContents share renderer processes and therefore calling this method may also crash the host process for other webContents as well.