Passing data from extension to content script using runtime connection port

When passing data, using a runtime connection port, from an indexedDB database of an extension to the content script to build a document fragment to append to the page, would it be more efficient to build the fragment in the extension, serialize it to a string using XMLSerializer and pass the string to be appended using insertAdjacentHTML instead of passing the data and having a copy at each location?


After working with this further, it appears that I was being rather stupid in not considering the memory required to build the fragment in the extension just to serialize it to a string afterward. A few data objects are less than all the objects that need created to build the DOM tree to be serialized to a string.

In the content script, it may be possible to consume an amount of RAM once to hold the data passed and write the new data to the same object each time. However, in the background script, there appears to be no way of controlling where the get request is written; and in the content script there appears to be no way of controlling where the object passed in the communication port is held before being written to an object in the content script.

Whatever it is, it appears that it must consume less RAM overall than generating instances of elements for a DOM tree just to convert it to a string instead of passing only the data and building the tree in the content script.

Thank you.

Usage of insertAdjacentHTML or innerHTML or similar methods is kind of forbidden because it allows script injection. So stick with the manual DOM building.

The data you send should be garbage collected and unless you are sending serialized images, usually it’s just few bytes / kilobytes so nothing significant.

Usually it’s more important to save memory in the background script because it’s running all the time and content script only on pages where it’s executed (unless it’s executed on every page :slight_smile: ).

Thank you.

When you write that insertAdjacentHTML is “kind of forbidden”, is that in every case?

I was trying to save memory in the background script by storing the HTML of a large DOM tree as a text file in the extension files, and fetching it as text and inserting into the page using insertAdjacentHTML.

I thought it would be more efficient than holding the DOM tree as a template in the background page (which would require insertAdjacentHTML to be inserted into the page anyway), and more efficient than storing it in the extension files as an HTML file and using a DOMParser to convert it to a document and then extract the DOM tree from that document to be appended.

Will this use be denied also?

Thank you.

When I say it’s kind of forbidden, I actually mean it’s forbidden :slight_smile:.
There may be some exceptions, but usually there are not and reviewer will complain.
From the MDN innerHTML:

Warning: If your project is one that will undergo any form of security review, using innerHTML most likely will result in your code being rejected. For example, if you use innerHTML in a browser extension and submit the extension to addons.mozilla.org, it will not pass the automated review process.

This applies to all methods that can insert HTML, for example element.append or element.prepend (which can be replaced with safe version insertAdjacentElement).

Some further reading here:


Regarding caching things in the background script - be careful :slight_smile:. Unless the data are needed for every single page, it’s usually better to cache it using one of the persistent storage like browser.storage.local or IndexedDB.
But often the performance difference is so small or none, that it’s not worth your time :slight_smile:.

Thank you very much for the additional information and links. I read about innerHTML before but did not know about the rest of these.

May I ask one additional follow up question please?

I understand the importance of these issues when using external content. If an extension does not accept external content but uses these methods only to add its own content to a web page it owns, are these methods still a security issue?

Similarly, can a web page that is not part of the match pattern of an extension’s manifest, make use of an extension in some manner, causing a security issue for the user? Or, are all these security concerns in reference to attempting to use external content only?

Thank you.

Extensions are well encapsulated so there is no way for the page to call any extension API that could compromise security - except if you program it explicitly using the window.postMessage.

Regarding innerHTML - for the reviewer it’s very hard or almost impossible to tell what kind of code are you putting there, especially if you concatenate it or if it comes from different part of your extension or from the extension storage. So this is here to prevent bad developers from hiding malicious code inside their extensions.

I just wanted to mention a third option, which is HTML templates. You can build your structure and then shove data into it using DOM methods such as setting textContent.

Thank you. You suggested this to me some time ago also and I have been using templates since then. They are very useful for what I’ve been working on.

After reading over the information that @ juraj.masiar provided concerning security, it appears that what I’ve been doing isn’t the best approach since the extension is to not insert UI elements into the page but instead should use extension UI options.

I was holding templates in the background page and passing them to the content script to be added to the page, and then thought that was taking up RAM unnecessarily and it would be better to hold them in an extension file to be fetched and added to the page. I tried holding the template/DOM tree as an HTML file and using DOMParser and as a text file and using insertAdjacentHTML to add it to the page. Both worked but the latter seems to use less memory and less code since a new document is not created and elements cloned.

I’ve been using a local HTML file that is just an empty container into which the extension adds the content. Perhaps, I need to rethink the overall structure.

The reason for doing these things is that I’ve been trying to find a way to let users easily get their local resources into the extension but there doesn’t appear to be a good method. Perhaps I’m attempting to use the extension environment for something for which it was not intended.

It works for me personally but I’m trying to make it flexible, easy, and secure for the general user and that has been difficult for my limited skill set.

Thanks again.

1 Like