Extension Architecture

347 views
Skip to first unread message

ibanez

unread,
Mar 9, 2021, 2:44:49 PM3/9/21
to Chromium Extensions
A general question regarding the chrome extension architecture

Are content scripts ran in a separate process or they a separate thread within the tab process ? 

Also, are chrome.runtime connections socket based IPC?
Message has been deleted
Message has been deleted

wOxxOm

unread,
Mar 10, 2021, 6:30:56 AM3/10/21
to Chromium Extensions, ibanez
Reposting the fixed version of my initial comment to avoid confusing anyone who might come here in the future and miss the correction.

Content scripts run in the same process as the page/frame. All content scripts of this page/frame run in a single isolated JS environment. Each extension has its own such environment so its global variables/functions aren't visible to the page or other extensions and vice versa, their global types and prototypes like Array.prototype, DOM expandos, custom element methods, are isolated, too.

Web pages/frames use one process per site so all pages/frames of one site will run in the same process although Chrome and Firefox may group several sites in one process under memory pressure, AFAIK.

All pages of an extension have a chrome-extension:// URL and run in a single process. Each extension has its own process and it is never grouped with anything else in Chrome to lower the possibility of privilege escalation via bug exploits. Examples of such pages/entities are the background page, the background service worker, options page, action popup page, any html opened in a tab, or an iframe from web_accessible_resources which is often used to add UI of the extension to a web page. All these entities have a chrome-extension:// URL.

Doing a computationally heavy operation (technically "a single long task of JS event loop") in any of chrome-extension:// pages will block the entire extension process i.e. all pages/frames of this extension will be blocked. Not content scripts of course because they run in the web page process. Since JS is single-threaded per specification, the closest thing to a thread is a worker. It's relatively heavyweight compared to a thread in more capable languages but practically they are often called threads anyway and devtools uses this term, too. So even though workers aren't threads, they would still help with such computationally heavy tasks to free up the main extension process. One of the few good aspects of ManifestV3 switch from the background scripts to a service worker is that the latter won't be blocked in this case and vice versa: the service worker won't block the UI or scripts of extension pages.

chrome.runtime messaging (both port-based and one-time messaging) is using custom implementation, see the source code. When the message needs to be sent across different processes it technically becomes IPC (inter-process communication), but it also can be used within the same process i.e. when the popup page sends a message to the background script or vice versa. Note that since it internally uses JSON.stringify/JSON.parse, it kills any nontrivial values like Set or Map. So, for same-process messaging between extension pages you may want to use the web platform API such as BroadcastChannel which utilizes the structured clone algorithm and thus is much faster (noticeable when the transferred data is a deeply nested object), it also supports many complex types.

hrg...@gmail.com

unread,
Mar 11, 2021, 4:16:46 PM3/11/21
to Chromium Extensions, wOxxOm, ibanez

So even though workers aren't threads

Is it correct to say that a worker is not a separate thread?
The Javascript code in the main thread and the code in a worker run in parallel. Which means they have separate event loops and task queues.
Are you saying that this separation is not implemented using threads under the hood?

 

the service worker won't block the UI or scripts of extension pages.

True. However, this will rarely give any benefit at all since it's quite uncommon that an extension requires one of its pages to be open permanently or regularly.
Most of the time, extension pages are only open for brief periods of time in order to change settings or to interact with the extension's popup.
 

 
for same-process messaging between extension pages you may want to use the web platform API such as BroadcastChannel which utilizes the structured clone algorithm and thus is much faster

Is this the same mechanism used when ".postMessage()" sends a message between an iframe and it's parent window?
However, postMessage can work across origins, whereas BroadcastChannel apparently cannot.

 

wOxxOm

unread,
Mar 11, 2021, 4:33:52 PM3/11/21
to Chromium Extensions, hrg...@gmail.com, wOxxOm, ibanez
Works are threads under the hood, in C++. In JS they're workers, not threads, so it's best to call them workers. It's bad that devtools is using the term "thread" but I guess it's because devtools programmers are using C++ a lot so they refer to the internal implementation.

BroadcastChannel is similar to postMessage and indeed it's only useful for messaging between extension pages as they run in the same origin.
Reply all
Reply to author
Forward
0 new messages