Distinction between the renderer and main processe

2019-03-08 14:44发布

I originally thought that the renderer process in Electron was sandboxed in a chrome-like environment, meaning all you can do is mess with the DOM. However, I recently learned that you can access the filesystem, run child processes and get their output, and import any other node modules you want.

If this is the case, what exactly is the distinction between the main process and the renderer process? Is it not a hard separation? What kind of code goes in the main process and what kind of code goes in the renderer process?

If anyone has a good in-depth reading/presentation on Electron app architecture I would love to look at that too; might help clear up some of the confusion

标签: electron
1条回答
你好瞎i
2楼-- · 2019-03-08 15:10

The main/renderer process distinction isn't actually an Electron concept per se -- it's inherited from Chromium (here's an article on Chromium's architecture and the reasoning behind it). This is the architecture that Chrome uses for performance and stability reasons. Each webContents instance runs in it's own process (a "renderer" process). The main process (there can only be one of these) manages webContents instances, among other things.

There's a good discussion here on the differences between the two.

Some APIs are only available in one process or the other, which can help you get a sense of what logic goes where. For example, Notifications (uses the HTML5 interface but are implemented as native notifications) can only be created from a renderer process. The Menu class can only be called from within the main process. Read through the Electron modules' API docs and see what goes where. You can use IPC, remote module, or electron-remote to coordinate between the two processes (which one you use depends on your use case).

I would say it is a "hard" separation. They're all separate processes and thus don't share any resources or state. This is a paradigm shift for most JS devs I think (at least it was for me). For example if I had a stateful module that I set some state in in the main process, and then I required that module in the renderer, that state won't be there. They're two entirely different instances of that module. Sharing state like that would probably be best in the main process and then either use one of the methods described above to share that state between renderer processes.

Here is a list of real life apps and some sample apps.

Shawn Rakowski said it well (in comments below): "It may be a good rule to put code dealing with the platform infrastructure code (i.e. creating windows, registering global shortcuts, etc) in the Main process and application specific code (what your app is actually doing) in the Renderer processes."

[My app's functionality is it] parses some files and then renders the info to the screen

There's lots of approaches you can take to this in Electron because the fs module (and all node.js modules) are available to you in the renderer process.

If you're only dealing with one browser window instance and not doing CPU intensive parsing, I would say run all the fs related code in that renderer process instance. That's the simplest way.

If you're doing CPU intensive work on these files, you don't want to lock up the UI, which means you can't do your processing browser window renderer, and you can't do it in the main (this will lock up all your renderers!). So I would look into something like electron-remote or create an invisible browser window instance that runs the heavy lifting.

This article about the main and renderer processes talks about these topics more in-depth (disclosure: I wrote that).

查看更多
登录 后发表回答