Multithreading comparison between Chromium and Firefox
Multithreading in Chrome
If you see the processes running on your computer (Task Manager) in Windows, you will see that for each tab opened in Chrome there is a corresponding process running. But Google Chrome still takes advantage of the multithreading ability of Windows. It uses threads for dividing the work inside a given tab.
As stated in the Chromium (the open source project behind Chrome) documentation, the browser uses separate processes for the browser tabs to protect the application from bugs in the rendering engine. The figure below is an illustration of the Chromium architecture.
To make sure the user interface is as responsive as possible Chromium ensures that the UI thread is not blocked by I/O or other operations. Chromium uses message passing as a communication channel between threads. Objects in Chromium live on only one thread and messages are used for communication. Chromium also uses callback interfaces when two separate threads need to communicate with each other.
Chromium implements its own dispatcher for scheduling the threads.
The MessageLoop.PostTask and MessageLoop.PostDelayedTask methods are used for dispatching. PostTask will schedule a task to be run on a thread. PostDelayedTask, as the name suggest will schedule a task to run after a given amount of time.
All the new tasks are put in the message loop’s queue where the specified delay will be handled by the operating system. In Windows the small delays will be scheduled after longer ones. Another usage of the PostTask is to make sure that a thread will not starve other time-critical threads.
Figure below shows the browser process and its threads, IPC channels and other components such as message filter etc.
Because Chromium is based on a multi-process architecture communication between these processes is fundamental.
The figure below shows the multi-process architecture of Chromium:
Chromium uses named pipes as the main IPC method. For the communication between a renderer process and the browser process a named pipe is assigned to the renderer process. These are asynchronous pipes, which ensure that both the renderer process and the browser process don’t block each other while waiting for a message.
In the browser process the communication with the renderer process is handled by I/O thread called IO. Messages that come to the IO thread are then sent to the main thread. This model has the advantage that when request are handled by the I/O thread, which will ensure that the UI is never blocked.
The renderer processes have a thread for handling the communication with other threads as well.
The two types of messages that Chromium uses are “routed” and “control” messages. A routed message is specific to a page and therefore routed directly to that pages’ process. An example if this message would be a message that tells a view to paint an element of the website.
Control messages on the other hand are not addressed to a specific view. They are handled by the render or the browser. An example of a control message which is not specific to a view would be a request for resources.
Multithreading in Firefox
Firefox creates a thread for each tab. The documentation of the threading API can be found at mozilla.org website. The threading interface allows the creation of threads for any job. The two main parts in the Mozillas’ threading API are the Thread Manager and the Workers classes.
The Workers class makes possible the creation of worker threads, which can also create other worker threads which Mozilla refers to as sub-workers. This is very handy in the case of a thread ,which might be a tab in Firefox, that needs to create several other threads for performing parts of the job to load the page. Regarding thread safety according to the Mozilla.org:
“The Worker interface spawns real OS-level threads, and concurrency can cause interesting effects in your code if you aren't careful. However, in the case of web workers, the carefully controlled communication points with other threads means that it's actually very hard to cause concurrency problems. There's no access to non-thread safe components or the DOM and you have to pass specific data in and out of a thread through serialized objects. So you have to work really hard to cause problems in your code.”
As you can see from the Thread Manager interface documentation, Firefox makes use of thread pools. Thread Manager also manages the interaction of the user-mode threading implemented by Firefox and the kernel-mode scheduling (dispatcher).
Comparing the two browsers performance: