Building a Network Stack for our Browser Extension

Rate this content
Bookmark

Engineering problems often repeat themselves in places you wouldn't expect. Sometimes the best solution has already been invented, in a different corner of the software engineering domain. 

In this talk, we show how and why we mirrored the TCP/IP network stack to solve a communication problem between different components of a browser extension.

This talk has been presented at Node Congress 2024, check out the latest edition of this JavaScript Conference.

FAQ

Jam is a browser extension for bug reporting that helps you receive detailed and perfect bug reports every time.

Jam allows product managers to select a screenshot, record the tab, or an instant replay when filing a bug. It automatically bundles additional information like console logs, network requests, page metadata, and repro steps, making the bug reporting process detailed and efficient.

The main components of the Jam browser extension are the background script, pop-up, content script, and host script. The background script acts like a server, while the pop-up and scripts handle user interactions and data processing.

The components communicate bidirectionally using different messaging APIs. The background script can communicate with the pop-up and content script directly, but messages to the host script must be proxied through the content script.

Jam addresses challenges such as different messaging APIs, size constraints on messages, indirect communication between components, multiple instances of components, dropped messages, and memory sharing limitations.

Jam implemented message chunking to handle large messages in incognito mode. This involves breaking down large messages into smaller chunks and sending them sequentially, then reassembling them on the other side.

The network stack in Jam is modeled after the TCP/IP stack, consisting of layers like the link layer, packet layer, datagram layer, and application layer. Each layer addresses specific communication challenges, making the messaging system efficient and reliable.

Jam's new network stack provided easier debugging, smooth rollout without changing application code, and allowed developers to focus on building features without worrying about underlying messaging complexities.

Incognito mode support is important for Jam because QA testers often use incognito mode when running through certain flows, making it crucial for accurate bug reporting.

The background script in Jam's browser extension acts like a local server that runs in the background, handling long-lived tasks and communication between other components.

Cyrus Roshan
Cyrus Roshan
19 min
04 Apr, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
The Talk discusses the development of the Jam browser extension, which is a bug reporting tool. It explores the challenges of messaging between different execution environments within a browser and the need for message chunking to overcome size constraints. The Talk also explains how the development team rebuilt the system using a TCP/IP network stack approach, which allowed them to solve messaging difficulties similar to networking problems. The benefits of this approach include a smoother rollout, simpler debugging, and a focus on feature development without worrying about messaging constraints.

1. Introduction to Jam Browser Extension

Short description:

Hi, I'm Cyrus, an engineer at Jam. Today, I'll talk about building a network stack for our browser extension called Jam. Jam is a bug reporting extension that helps you receive detailed bug reports with features like screenshots, network requests, and console logs. It saves time and provides a hassle-free experience. The extension consists of components like background script, pop-up, content script, and host script, all operating within a browser window.

Hi, I'm Cyrus. I'm an engineer at Jam, and this talk is about building a network stack for our browser extension.

Now, if you don't know what a network stack is, or if you do know what a network stack is, and it just sounds weird that we're building one in at the application layer inside a browser extension, don't worry, we'll answer all those questions in this talk.

So first, what are we building? What is Jam? Jam is a browser extension for bug reporting. And what that means is we help you receive perfect bug reports every time. Typically, when you receive a bug report from a product manager or a QA, it's not a fun experience because you don't get a lot of details on the bug. You might get a sentence or two of like, this page is broken, and you have to decipher what that means. With Jam, whenever your product manager files a bug, they have to select a screenshot or record the tab or an instant replay. So you can actually visually see what the bug is. And then we automatically bundle in a bunch of other information like the console logs, network requests, page metadata, repro steps. So like, whenever a user clicks a button on the device info timestamp, bunch of other details that you would want to get a picture of what actually happened. When you receive this bug, you can open up the bug, and it's kind of like having the DevTools in your browser open, as if you had the bug right there on your laptop. And you can look at the headers, the request body, the response body, the console logs, whatever. So basically, we save you a bunch of time on back and forth. You don't have to jump on a call. And it's just a headache free experience.

So in order to do this, we have a browser extension. And this browser extension has a few components inside it. The main component is a background script. And a background script is kind of like a server for a browser extension. Like it's running in the background, but it's local. There are a few other ephemeral components, like the pop-up, the content script, the host script. These all live inside a browser window. And so a browser window is just like, you open up a Chrome window. A Chrome window can have multiple tabs. And it can have a pop-up too. So the pop-up is like, whenever you click on an extension icon, there's this pop-up window. You can interact with it, and then it closes. And then a tab is like whenever you go to Hacker News or Google, or something like that.

2. Execution Environments and Messaging

Short description:

Inside a tab, there are two execution environments: content script and host script. They communicate differently and have specific constraints. Messaging APIs like window.postMessage and Chrome messaging API are used. Some APIs have size limitations. The host script can only communicate with the content script, requiring message forwarding. Multiple instances of components can pose challenges in addressing messages to the correct content script.

And then a tab is like whenever you go to Hacker News or Google, or something like that. And inside this tab, there are two components, or really two execution environments. One of those is the content script execution environment. And one of those is the host script execution environment. The content script execution environment is like a custom environment where it's isolated from the page itself. So if the page that you're on modifies a window property, the content script doesn't get affected by it. And this is basically for extensions to inject code inside this content script execution environment and not have their scripts get modified by the host page.

And then the host script execution environment is just where the host page's scripts live. So all of these components of this browser extension communicate, but they communicate in slightly different ways. So all these components communicate bidirectionally. So from the pop-up to the background script and vice versa, you can send messages from the content script and the background script and vice versa. But the host script is the one exception. And the host script can only communicate with a content script. So if you want to send a message from the background script to the host script and get a response, you have to forward that through the content script. You have to basically set up a handler that will proxy that message to the host script and then proxy the host script's message back to the content script.

And this is kind of difficult to deal with when you're just trying to create a feature within your browser extension. Like, you just want to build something, and then now you have to think about all these different constraints that you have to think about with sending messages back and forth to power that feature. The constraints are basically these listed right here. We have different messaging APIs that we have to use for all of these components. So between the content script and the host script, we might be using window.postMessage. But then between the content script and the background, we might be using a Chrome messaging API. And that's a different API than between the pop-up and the background script. So there's a few different APIs that we're using here, and we have to keep that in mind. Additionally, some of those APIs have size constraints. So the size of a message is limited. And then, just like before, some of these components can't communicate directly. So when you're dealing with the host script, you have to proxy messages back and forth to it unless you're just messaging from the content script. And a lot of these components can... You can have multiple instances of them, so you can have multiple tabs, you can have multiple pop-ups. And that can present some problems when you're trying to address messages to the right tabs content script.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Install Nothing: App UIs With Native Browser APIs
JSNation 2024JSNation 2024
31 min
Install Nothing: App UIs With Native Browser APIs
This Talk introduces real demos using HTML, CSS, and JavaScript to showcase new or underutilized browser APIs, with ship scores provided for each API. The dialogue element allows for the creation of modals with minimal JavaScript and is supported by 96% of browsers. The web animations API is a simple and well-supported solution for creating animations, while the view transitions API offers easy animation workarounds without CSS. The scroll snap API allows for swipers without JavaScript, providing a smooth scrolling experience.
Rethinking Bundling Strategies
React Day Berlin 2023React Day Berlin 2023
32 min
Rethinking Bundling Strategies
Watch video: Rethinking Bundling Strategies
The talk discusses rethinking bundling strategies, focusing on challenges such as long-term caching and improving the state of Next.js and Webpack. It explores handling immutable caching and content hashes, optimizing asset references and page manifests, and addressing issues with client-side navigation and long-term caching. The talk also covers tree shaking and optimization, optimizing module fragments and code placement, and the usage and relationship of TurboPack with Webpack. Additionally, it touches on customizing configuration and hash risks, barrel imports and code splitting, and entry points and chunking heuristics.
Pushing the Limits of Video Encoding in Browsers With WebCodecs
JSNation 2023JSNation 2023
25 min
Pushing the Limits of Video Encoding in Browsers With WebCodecs
Top Content
Watch video: Pushing the Limits of Video Encoding in Browsers With WebCodecs
This Talk explores the challenges and solutions in video encoding with web codecs. It discusses drawing and recording video on the web, capturing and encoding video frames, and introduces the WebCodecs API. The Talk also covers configuring the video encoder, understanding codecs and containers, and the video encoding process with muxing using ffmpeg. The speaker shares their experience in building a video editing tool on the browser and showcases Slantit, a tool for making product videos.
WebHID API: Control Everything via USB
JSNation 2022JSNation 2022
23 min
WebHID API: Control Everything via USB
Today's Talk introduces the webHID API, which allows developers to control real devices from the browser via USB. The HID interface, including keyboards, mice, and gamepads, is explored. The Talk covers device enumeration, input reports, feature reports, and output reports. The use of HID in the browser, especially in Chrome, is highlighted. Various demos showcase working with different devices, including a DualShock controller, microphone, gamepad, and Stream Deck drum pad. The Talk concludes with recommendations and resources for further exploration.
Visualising Front-End Performance Bottlenecks
React Summit 2020React Summit 2020
34 min
Visualising Front-End Performance Bottlenecks
React's web-based tools allow for independent learning. Dazzone, a sports streaming service, faces challenges with low memory and CPU targets. Measuring, analyzing, and fixing performance issues is crucial. Virtualization improves rendering efficiency and performance. The application is now much faster with significantly less jank.
Automate the Browser With Workers Browser Rendering API
JSNation 2024JSNation 2024
20 min
Automate the Browser With Workers Browser Rendering API
The Talk discusses browser automation using the Worker's Browser Rendering API, which allows tasks like navigating websites, taking screenshots, and creating PDFs. Cloudflare integrated Puppeteer with their workers to automate browser tasks, and their browser rendering API combines remote browser isolation with Puppeteer. Use cases for the API include taking screenshots, generating PDFs, automating web applications, and gathering performance metrics. The Talk also covers extending sessions and performance metrics using Durable Objects. Thank you for attending!

Workshops on related topic

Build React-like apps for internal tooling 10x faster with Retool
JSNation Live 2021JSNation Live 2021
86 min
Build React-like apps for internal tooling 10x faster with Retool
Workshop
Chris Smith
Chris Smith
Most businesses have to build custom software and bespoke interfaces to their data in order to power internal processes like user trial extensions, refunds, inventory management, user administration, etc. These applications have unique requirements and often, solving the problem quickly is more important than appearance. Retool makes it easy for js developers to rapidly build React-like apps for internal tools using prebuilt API and database interfaces as well as reusable UI components. In this workshop, we’ll walk through how some of the fastest growing businesses are doing internal tooling and build out some simple apps to explain how Retool works off of your existing JavaScript and ReactJS knowledge to enable rapid tool building.
Prerequisites:A free Retool.com trial accountSome minimal JavaScript and SQL/NoSQL database experience
Retool useful link: https://docs.retool.com/docs
Writing Universal Modules for Deno, Node and the Browser
Node Congress 2022Node Congress 2022
57 min
Writing Universal Modules for Deno, Node and the Browser
Workshop
Luca Casonato
Luca Casonato
This workshop will walk you through writing a module in TypeScript that can be consumed users of Deno, Node and the browsers. I will explain how to set up formatting, linting and testing in Deno, and then how to publish your module to deno.land/x and npm. We’ll start out with a quick introduction to what Deno is.