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.

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
You might not need as much JS as you think to accomplish common UI patterns with these new native browser APIs. Dive into new and future CSS, HTML and JS APIs that make our code leaner and faster to ship.
Rethinking Bundling Strategies
React Day Berlin 2023React Day Berlin 2023
32 min
Rethinking Bundling Strategies
We take a look at different challenges and decisions when bundling code for web applications. We look at how these are commonly solved and why we need to rethink them.
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
High quality video encoding in browsers have traditionally been slow, low-quality and did not allow much customisation. This is because browsers never had a native way to encode videos leveraging hardware acceleration. In this talk, I’ll be going over the secrets of creating high-quality videos in-browsers efficiently with the power of WebCodecs and WebAssembly. From video containers to muxing, audio and beyond, this talk will give you everything you need to render your videos in browsers today!
Visualising Front-End Performance Bottlenecks
React Summit 2020React Summit 2020
34 min
Visualising Front-End Performance Bottlenecks
There are many ways to measure web performance, but the most important thing is to measure what actually matters to users. This talk is about how to measure, analyze and fix slow running JavaScript code using browser APIs.
WebHID API: Control Everything via USB
JSNation 2022JSNation 2022
23 min
WebHID API: Control Everything via USB
Operational System allows controlling different devices using Human Interface Device protocol for a long time. With WebHID API you can do the same right from the browser. Let’s talk about the protocol features and limitations. We’ll try to connect some devices to the laptop and control them with JavaScript.
Building Figma’s Widget Code Generator
React Advanced Conference 2022React Advanced Conference 2022
19 min
Building Figma’s Widget Code Generator
Widgets are custom, interactive objects you place in a Figma or Figjam file to extend functionality and make everything a bit more fun. They are written in a declarative style similar to React components, which gets translated to become a node on the canvas. So can you go the other way, from canvas to code? Yes! We’ll discuss how we used the public Figma plugin API to generate widget code from a design file, and make a working widget together using this.

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.