
Setting up GitHub Actions for Nuxt3 project on Digital Ocean
Setting up CI/CD is a common event in the world of development in modern times. However, it is not always easy to find a description or full documenta...
Nov 14, 2023
For a long time, I believed that knowledge of browser architecture was not necessary to write web applications. Many people learn HTML for layout in school, and mastering CSS to create basic styles takes only a week. All that remains is to learn JS and one of the three popular frameworks, understand a little about the builders and, it would seem, you are ready — you can go into battle.
However, this approach runs into problems even with the very first SSR (server-side rendering) application, which will most likely crash on the server side due to lack of access to the window object. Writing a high-quality server in Node.js will not be easy, and understanding what Bun is and what its advantages over a node will be even more difficult.
That is why I decided to write a series of articles in which we will go through the following questions: what is a browser? What does it consist of and what functions do its modules perform? What are compiled and interpreted programming languages? What does single-threading and multi-threading mean and why is Event Loop an ideal client-side solution? What is the difference between client-side and server-side asynchrony? How to make JavaScript multi-threaded and why might it be needed?
I decided to start diving into this topic with an analysis of browser architecture, and not with basic programming concepts. This will make it easier to draw parallels between the frontend and backend on Node.js in the future. Let’s get started.
The user interface includes tabs, bookmarks, address bar, settings menu, various security indicators such as HTTPS connection security messages, browser history navigation buttons, and more.
Nothing particularly important for us as developers, except perhaps the viewport. On the one hand, it is an interface element, but on the other hand, it is closely related to the browser rendering engine, which is responsible for displaying HTML and CSS. In the context of interface design, a “viewport” often refers to the viewport, the dimensions of which determine how web content should be displayed correctly on different devices, which is a key aspect of responsive design.
The browser engine is a fairly large module that is responsible for processing user interactions with the interface, as well as for connecting all program modules together. It is responsible for passing instructions to the rendering engine, making requests to the network layer to load various data from third-party resources, and processing user events. It’s worth noting that while the terms “browser engine” and “rendering engine” are often used interchangeably, a browser engine is a broader concept that includes many of the tasks of managing the flow of information and resources in a browser, as opposed to a rendering engine, which deals specifically with the processing and display of HTML and CSS.
Many may know the term WebKit — this is a browser engine developed by Apple in 2001 for Safari. Over time, it became open source and other companies such as Nokia and Google worked on it.
It is worth mentioning Blink — this is a rendering engine that is used in Google Chrome, Opera, new versions of Microsoft Edge, Brave and other browsers. It was created in April 2013, when Google developers decided to fork WebKit in order to simplify the codebase and speed up development. Since then, these engines have been developed in parallel, but both remain open-source.
Firefox stands apart, which uses not WebKit or Blink, but its own development — Gecko, released back in 1998. The authors list its features as strict support for web standards and a focus on user privacy. But we, as developers, should remember that a web page in Firefox may behave differently than in other browsers. In addition, this browser uses not -webkit- as vendor prefixes, like browsers of the WebKit “family”, but -moz-. So, dear developers, install Firefox to test your layout.
The render engine, also known as layout-engine, is part of the browser engine and is responsible for rendering web pages. This module is responsible for building the DOM, CSSOM and combining them into the Render Tree — topics that we will definitely talk about in more detail.
The JavaScript engine is a module that is a JS interpreter and is responsible for compiling JavaScript into machine code. Whether we are talking about V8 in WebKit, Blink or Node.js, SpiderMonkey in Firefox or Nitro in Safari, they are all written in C++.
This module is responsible for script parsing, code profiling, its compilation and optimization through function inlining, removal of unused code, etc. It also executes code on the target machine, manages memory (heap), garbage collection, exception handling, deoptimization, and includes some mechanisms for handling asynchronous code.
We will definitely talk about Event Loop in the next article. There are many interesting nuances here, since the event loop is not part of the engine itself, but is implemented at the environment level, although part of its implementation is provided by the engine. This is why the same engine (for example, V8) behaves differently when executed in a browser as part of WebKit or in Node.js, relying on functionality from the Libuv library.
Network layer. The network layer module processes external network requests and resources. He is responsible for:
sending HTTP/S requests and processing their statuses;
data encryption via SSL/TLS certificates, certificate validation and establishment of a secure connection (handshake);
caching, that is, saving copies of static resources, complying with the established caching policy for HTTP headers, updating outdated resources;
compliance with security policy: implementation of CORS policy, Same-origin policy, implementation of Pre-Flight requests and compliance with Content-Security Policy;
support for correct VPN operation;
processing DNS requests.
Data Storage. This module is responsible for storing data on the client side. It manages Cookies, Local and Session Storage, deploys and manages IndexedDB, and associates them with specific domains. The module also provides secure access to files on the user’s computer and their downloading. The cache API used by service workers to keep applications running offline also works through this module.
Developer Tools. This is a separate module, but we will not dwell on it in detail. If you’re reading this article, chances are you’ve used these tools more than once.
The Browser API is a set of interfaces for interacting with various browser features. Most of them are provided by the browser engine, but not all. Among them are the aforementioned Service Workers, DOM API, Geolocation API for accessing geolocation data, Notifications API for browser notifications, Canvas API, Web Audio/Video API, WebRTC and many others. For example, geolocation is implemented through the interaction of the browser engine with the operating system, the Web Storage API with the data storage module, and the DOM API with the rendering engine.
Worthy of mention. A few more modules, less significant than the above:
A plugin manager that allows you to expand standard browser functions by installing add-ons.
Performance optimizers are custom modules for various browsers designed to speed up work.
Accessibility tools to make content accessible to people with disabilities.
API for interacting with various devices such as webcams and microphones.
Total. Why was all this information needed? The main thing is that understanding the differences between the browser environment and the JS engine opens the way to understanding the difference between client and server development, and the modular structure makes it easier to understand asynchrony. In addition, now you know that a browser is a set of open libraries that you can independently assemble into your own browser by editing them and, possibly, editing their functionality, say, removing some of the logic from the network module. But I didn’t tell you about this 😉
Setting up CI/CD is a common event in the world of development in modern times. However, it is not always easy to find a description or full documenta...
Writing clean and maintainable code is a fundamental skill for every developer, and adhering to proper naming conventions plays a crucial role in achi...