These browser engines power not only "web browsers", but also any technology that uses these language to create a User Interface ("Embedded browser engine"). While the foundation might be the same, there are some key differences between these two sub-categories.
With more than 4 billion internet users and 1.7 billion websites, the web is one (if not the most) popular platform.
While websites started as a way to render documents back in 1990, they have come a long way. They provide rich experiences with real time communication, video, and 3D graphics. They also adapt dynamically to any form factor, work offline, send notifications, and more. With all these new features and capabilities, browsers have had to evolve and become more like mini OSes, protecting users from malicious attacks and poorly written code.
The most used ones are Chrome (Chromium), Safari (WebKit), and Firefox (Gecko). But even though they all are considered modern engines, they are not the same. Even for the same browser there can be significant differences accross platforms (more notably on iOS where they are force to be a wrapper around the WebKit's WebView).
As with all other technologies, there are pros and cons that developers need to evaluate. The main questions to ask are around:
- Feature requirements and platform support
- Distribution and infrastructure
Feature requirements and platform support
As mentioned earlier, the Web API has become richer over the last few years. Yet there are features that are still not available (nor they will be, like platform specific features).
It is important for developers to know what are the required features and if there is an API to enable that. The capabilities status website is a good place to learn about what is already available or in development. Not all these APIs are supported by all browsers at the same time, so developers need to additionally take into account what does their user base look like, if there are alternatives that could be use, or if the experience they are planning could be progressively enhanced instead of rely entirely on it.
Distribution and infrastructure
This sections needs to be written. Some talking points are:
- Talk about server vs install file
- Requiring a web server to deliver the app
Embedded browser engine
To fill this opportunity Apache Cordova is created (formerly PhoneGap): a mobile development platform that uses the platforms’ WebView control (a control that allows you to render web content inside an application) to create web UI driven applications that also have access to native features not available in the web.
Since that year, there have been multiple technologies that have been created that use the WebView provided by the Operating System or even bundle a full browser engine such as Electron (2013), Chromium Embedded Framework (CEF) (2009), NW.js (2012), Capacitor (2019), Tauri (2021), Chromely (2018) and more.
The high-level architecture of these technologies is very similar and can be seen as the following:
While each project has its own characteristics (is it OSS? what is its release cadence? etc.), the main technical questions can be grouped in the following categories:
- Platform support and rendering engine
- Hosting language, features and hotpaths
- Inter-Process Communication layer
Platform support and Rendering engine
At first it can be a bit surprising to group "Platform support" and "Rendering engine". The reason is that they are intertwined and one impacts the other (and vice-versa). Technologies that bundle their own rendering engine (Electron, CEF) will only work on platforms that allow engine diversity. Because iOS devices do not allow that, their teams usually limit themselves to desktop platforms (Linux, macOS, and Windows). Those that rely on the platform's provided WebView have an easier time to reach more platforms (i.e.: mobile as well), at the expense, in some cases, of quirks between the different platforms or if the device is running an older version of the control.
Hosting language, features and hotpaths
A few questions that can help us make a decission are:
- Does the technology provide all the needed features out of the box (or via plugins)? If so the team will be spending most of the time working on the web side and while being familiar with the hosting language is always good, it might not be necessary to be an expert. In the opposite side, if there are gaps does that need to be filled, does the team have the experience? Does any of the languages or hosting technologies have any limitation that might prevent implementing those features? Is there another technology that can better leverage the knowledge they already have?
- Where are the possible bottlenecks in the application? If they are going to be in the host, it might be worth exploring if there is one that might have an advantage for your particular scenario. Another important thing to consider in this situation is how the communication between the host and the guest is done (the Inter-Process Communication layer). You could be running the fastest possible version of an algorithm on the host and still have poor results if that communication is done in an efficient way.
Inter-Process Communication layer
While there are many browsers and cross-platform technologies, the reality is that there are not that many browser enginges as we have seen before. In fact, most of the technologies that render web rely on Chromium or WebKit. Unsurprisingly, when using the same engine and the same web content all these technologies show similar performance characteristics (memory, processes, threads...). It makes sense, the cost of running a browser engine is considerably larger than any “overhead” that might come with the hosting technology (C++, C#, Node.js, etc.). But how come that even if the same engine is used, two technologies can show different results? This difference comes mainly on how the communication with the world outside what is provided by the web platform is done, basically, how information flows from one process to another.
There are many strategies in here, each one with its pros and cons:
- Message serialization: The sender serializes a message into a format that can be understood
by the receiver (usually a JSON string) and sends it via a built-in mechanism. The received then
parses this message and creates a copy of the original message.
JSON.parse(JSON.serialize(myObject))with an extra step to send the string to another process. This mechanism is commonly used by technologies that use a WebView control (e.g.: Apache Cordova, Capacitor) and sometimes is done automatically.
- Sockets: In this case, the host creates a server that the guest can connect to to communicate. It could be via WebSockets, or even via regular HTTP requests (with the Fetch API). An example that uses this approach is Blazor Desktop.