With web extension Manifest V3 rolling out across chromium-based browsers, support is being dropped for extensions that are not compatible with the new manifest version. For example, uBlock Origin began to be disabled for more Chrome users recently, as discussed in this article from The Verge.
Reading about this led to me wondering about how web browser ad blockers work generally, and why some are not compatible with the latest web extension manifest version. This article from cybernews has a nice overview of how web browser ad blockers typically work, including this useful summary:
But the technology behind ad blockers is usually the same: filter lists and pre-defined rules to which any webpage content gets compared. If an ad is detected, it gets blocked.
Apparently, one of the most popular lists used to filter out unwanted content is https://easylist.to/. As described on the website for the list:
EasyList is the primary filter list that removes most adverts from international webpages, including unwanted frames, images and objects. It is the most popular list used by many ad blockers and forms the basis of over a dozen combination and supplementary filter lists.
So, my understanding is, with a typical ad-blocking extension enabled, when a given webpage makes some network requests, the ad-blocking extension will check the requests against some list or lists (likely including EasyList), and prevent any requests to domains included in the filter lists. This prevents any advertising content (or other unwanted content) from being downloaded by your browser altogether.
In order to filter network requests in Manifest V3 compliant extensions, the declarativeNetRequest API should be used rather than the webRequest API (which is commonly used in content blocking extensions that work with Manifest V2). The webRequest API is still available to Manifest V3 compliant extensions, but the webRequestBlocking permission is not available for most extensions. As per the Chrome docs on the API:
Note: As of Manifest V3, the “webRequestBlocking” permission is no longer available for most extensions. Consider “declarativeNetRequest”, which enables use the declarativeNetRequest API. Aside from “webRequestBlocking”, the webRequest API is unchanged and available for normal use. Policy installed extensions can continue to use “webRequestBlocking”.
The “webRequestBlocking” permission is required to “register blocking event handlers”, so without this permission the webRequest API is not useful for blocking network requests.
From what I understand, one major change compared to the webRequest API with the webRequestBlocking permission is that the declarativeNetRequest API uses primarly static rulesets to determine which requests to filter. This means that for an extension like uBlock Origin, the list of unwanted content (for example the contents of https://easylist.to/), would need to be included in the files bundled with the extension. It follows that the list of unwanted content will then only be updated when the extension is updated, rather than updated by the extension itself dynamically.
There are many other differences between the capabilities of Manifest V2 compliant and Manifest V3 compliant extensions. The FAQ about uBlock Origin versus uBlock Origin Lite and the Manifest V3 transition has much more detail, for example.
You might notice that there is a way to dynamically add filter rules at runtime for Manifest V3 compliant extensions, as discussed in the Chrome docs on content filtering here. The FAQ linked above explains how this is not a reliable approach, due to another change in how Manifest V3 extensions work, which is that extension service workers become an extension’s central event handler (previously extensions had a long-lived background page, while extension service workers will be shut down when they are determined to not be needed by the browser). From the linked FAQ:
Non-declarative MV3-based content blockers will suffer unreliable filtering when their service worker has been suspended, since waking up a service worker requires a lot of initialization work and delays time-critical filtering abilities. Such content blocker may end up using trickery to force their service worker to always be up and running.
For instance, ABP 4.1 uses such trick to keep its service worker alive and ready to act: the service worker is force-restarted each time it is terminated by the browser, so every 30 seconds when the browser is idle. Despite using this trick, there is still no guarantee reliable filtering will occur should timely filtering be required just as when the service worker is being woken up (all event handlers are non-blocking in MV3).
…
The choice of being entirely declarative for the sake of reliability and efficiency meant sacrificing being able to import filter lists or create custom filters, hence the “Lite” in uBO Lite: it’s not meant as an MV3-compliant version of uBO, it’s meant as a reliable Lite version of uBO, suitable for those who used uBO in an install-and-forget manner.