Overview of Servo

Wu Yu Wei published on
5 min, 951 words

Before we deep dive into the code base of servo, I guess it's better to have a high level overview of it. Servo is a huge project and it contains over million lines of code. Sometimes it might be diificult to graspe where are you looking at or how each component interact with others. Getting a high level overview could help you building your own mental model. So let's get started:

And that's it! Don't worry about what is each component and how do they do. We'll talk about them along the way. And of course it still simplifies and ignore many parts. These include Webrender, Surfman, Mozjs, and many other web features like WebXR, media, and WebGPU etc.

What this overview trying to represent is how the main trunk of Servo looks like and where is the part handles web pages mostly. There are other processes and threads, but they will behave similar to how pipelines do.

Constellation

Let's start with the main process. There isn't acutally a module called main process. But this helps us to understand who takes the big part in the center of Servo. Every rectangles it contains is a thread. Threads with plural name mean they could be multi-threads.

The most important thread we want to focus on is the "Constellation". It is the centeral station of the engine. It stores core states of the engine like "User Agent" and also handles any workflow involving several components. The constellation the unique thread in Servo and there's no the other one. This means it couldn't get the deadlock and is also responsible for crash reporting.

Interestingly, the constellatiion doesn't receive all messages from other processes directly. Main process has a IPC Router and receiving messages is its job instead. Every arrow you see is a Channel. This allows the router thread to use select! macro to re-route all IPC messages. The router also allows other threads in other processes to register callbacks to do some operations.

Embedder

Embedder itself in servo is acutally just a few traits. It's a interface requires code who uses servo to implements. Thinking it's like several methods servo need users to define. So the implementation would be able to receive message from servo and handle its own event loop. For servo's demo, it uses winit's event loop and implements those traits for it.

Compositor

Graphic compositor is a thread renders the necessary pieces of the web pages. This includes iframe, animation and scroll bars etc. You can think it as a layer design to show what parts should be painted on the screen eventually.

Resource Thread

Resource thread's purpose is just like the name itself. Getting the resources from I/O, either from network or file system. It's a bit weird to include this thread into the main process instead of pipeline. But it will be created soon after constellation, beause it will have to load some initial assets real soon. It's the few thread that doesn't communicate via IPC router. Script threads in pipeline are able to talk to it directly.

Pipeline(s)

A pipeline is a process for servo to load your page and maintain it. It's servo's view of a "web page" or a "iframe", or we could just call it a "Window". When the constellation want to load an url, it will get or create a "BrowsingContext". It's servo's view of "WindowProxy" and it contains several states related to the page like session history. The constellation will spawn a pipeline and pair with it. You can treat them like a key value pair of a HashMap.

And yes, you can see there's a IPC router again. This is just like how main process routing incoming messages.

Script Threads

Script thread is the "main thread" of a pipeline. It runs the window event loop of a web page that belongs to the same BrowsingContext and Origin. A pipeline could possibily share the same script thread because thread itself could potentially process multiple iframe with same origin.

Script threads also connect the javasvript engine: Spider Monkey. In Rust, it's a wrapper crate called mozjs. Script itself defines the webIDL interface to communicate with it.

Layout Threads

For each pipeline, it will spawn a layout thread and it doesn't share between pipeline. It process DOM tree and stylist created frome CSS selector to produce the display lists. These lists are used for final graphic rendering. For example there might be a list to tell we need to render a rectangle and a triangle.

Web workers

And of course there will be web workers running scirpts in the background. But the web workers shown in the picture is more like dedicated workers belong to script thread. There could be another process that has standalone web workers running other web features.

What's next

There you have it! This is basically how the overview of Servo could look like. There are indeed many more processes and threads. But you should already get the insight and idea how will they interact and communicate. In the next post, we'll see how an url being loaded and its journey to finally being rendered.