Open Bug 1587326 Opened 2 years ago Updated 3 months ago

Firefox memory usage in Angular + Polymer WebComponents application is huge in comparison to other browsers

Categories

(Core :: DOM: CSS Object Model, defect, P3)

69 Branch
defect

Tracking

()

UNCONFIRMED

People

(Reporter: msbasanth, Unassigned, NeedInfo)

References

(Blocks 2 open bugs)

Details

(Whiteboard: [MemShrink])

Attachments

(9 files)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36

Steps to reproduce:

Test Scenario: Angular page with 30 Dropdowns with 120 items each, 30 Tabs, 100 Checkboxes and 20 buttons.

Demos
Angular + HTML: https://github.com/msbasanth/AngularHtmlHeavyUIApp
Angular + Polymer WebComponents: https://github.com/msbasanth/AngularPolymerHeavyUIApp

Steps to Reproduce

  1. Launch an Angular application with 30 Dropdowns with 120 items each, 30 Tabs, 100 Checkboxes and 20 buttons.
  2. Check the performance using Chrome performance tab with Memory check enabled.
  3. Note down the initial load time and total memory usage by the application.
  4. There is very high memory usage in firefox with Polymer WebComponents enabled at the same time a performance degradation observed with IE11 (no webcomponents support, polyfills used)

Actual results:

As you could see firefox memory usage is very high (726MB/276MB) compared to other browsers and IE11 initial load time is drastically high (2 Minutes)

Expected results:

We should have a comparable results across browsers when we use polymer webcomponents.

I'm setting a component in order to involve the development team in reviewing this issue.
If it is not the correct one, please feel free to set a more approriate one.

Thank you for reporting!

Component: Untriaged → DOM: Core & HTML
Product: Firefox → Core

Thanks for the test-case!

In case this is browser dependent, could you export your about:memory, or provide a test-case? You can click Measure and Save on that page and attach the result.

Also, is this using just web components, or web components + shadow DOM? I'm not familiar with polymer itself.

Finally, how is memory measured in that table?

Thanks again.

Flags: needinfo?(msbasanth)

(Just so I don't forget about it for too long)

Flags: needinfo?(emilio)
Whiteboard: [MemShrink]

Any chance for a testcase one could just load in a browser without need for local server?

Well I'll wait for the questions to be answered, otherwise I don't know what's being measured, but feel free to ni? me back if they get answered and I miss it or something :)

Flags: needinfo?(emilio)

Tested on my computer(MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)), about:memory :

72.0a1 (2019-10-22) (64-bit): 580MB, And it doesn't seem to load properly
68.0 (64-bit): 2.49GB, And it doesn't seem to load properly

Google Chrome 80.0.3947.0 (Official Build) canary (64-bit)
1.3G

When I open devtools:
4.4GB

Attached file memory-report.json.gz

This is the about:memory taken from Firefox with the Angular + Polymer application shared.

Attached image firefox_memoryIssue.gif
Flags: needinfo?(msbasanth)

(In reply to Emilio Cobos Álvarez (:emilio) from comment #2)

Thanks for the test-case!

In case this is browser dependent, could you export your about:memory, or provide a test-case? You can click Measure and Save on that page and attach the result.

Also, is this using just web components, or web components + shadow DOM? I'm not familiar with polymer itself.

Finally, how is memory measured in that table?

Thanks again.

Hi,

I am attached about:memory (Measure and Save) result here.
We are using Polymer WebComponents for developing our UI elements. As I understand the latest Firefox builds we have WebComponents enabled by default and not required to enable using dom.webcomponents.enabled flag. So by default the UI elements will use WebComponents with with ShadowDOM in modern browsers. As mentioned in the table in older Mozilla Firefox (v67) when we tried disabling WebComponents we are not getting this high memory usage issue.

So here it is something to do with WebComponents with ShadowDOM.

How the memory is measured?

  1. We opened diagnostic window
  2. Took a memory snapshot.
  3. We can also see the high memory usage in task manager

Attached a GIF for detailing the same.

(In reply to Olli Pettay [:smaug] from comment #4)

Any chance for a testcase one could just load in a browser without need for local server?

Polymer +WebComponents controls require local server. Not sure about a way to load with the server.

Attached image chrome_memory.gif

I am attaching my observation in Chrome here. I could see memory usage below 200MB with Chrome Version 77.0.3865.120 (Official Build) (64-bit).

I'll find some time to dig through the memory report...

But there's only one attached (the one with web components, looks like). Could you attach the one without web components too?

Flags: needinfo?(msbasanth)
Flags: needinfo?(emilio)

797.01 MB (52.41%) ── heap-unclassified

344.77 MB (22.67%) ── text-nodes

The heap-unclassified is rather annoying. We're missing some memory reporters.

But that text-nodes part... how could we have that much data attached to DOM if Chrome shows just 32MB memory usage.
Is the Chrome memory usage for its parent process, not for the renderer process, by any chance?

(Or does Polymer somehow leave text nodes in the DOM when one uses Firefox. Polymer used to have leaks when using webcomponents, but I think at least some of them were fixed.)

To take the memory snapshot without webcomponent I had to go to Firefox version 66. I uninstalled latest Firefox and installed version 66. Now we are seeing a different memory snapshot, it's 3GB!.

It was not the case when initially I tested with webcomponent disabled (It was 50MB). I will attach the previous observations for webcomponent disabled separately.

One thing I could observe is in the 2nd launch there is a forceful update happening to version 69. Will it happen that I am seeing Firefox 69 results instead of version 66 (with WC disabled)?

Flags: needinfo?(msbasanth)

Attaching my observations with Firefox version 66 with webcomponents disabled. Now I am not able to reproduce this as each time firefox gets updated to version 69 automatically. The option in the setting for disabling auto update doesn't help.

But as shown in the screenshot it was 50MB with webcomponents disabled to load the same UI (offcourse time taken is more).

Priority: -- → P3
Attached image chrome_shadowdom.jpg
Attached image ff_shadowdom.jpg

@msbasanth This should use the Constructable Stylesheets API

https://bugzilla.mozilla.org/show_bug.cgi?id=1520690

Attached image ff84_memorysnapshot.PNG

I have some further observations related to high memory usage in Firefox with WebComponents.

One difference in Firefox when comparing with Chrome is how styles are handled.
Style nodes are not static but per instance and in our example we have high (7000 nos) icon elements used which is having big style node. And this gets duplicated per instance in firefox and memory usage grows drastically.

Attached shadowdom style tag difference - chrome_shadowdom.jpeg & ff_shadowdom.jpeg.

It is observed because of this style duplication there is a huge memory usage (5,8 GB now) in #document. I am attaching a newer Firefox 84 (64Bit) memory snapshot from the same application.

As you could see #document contributes to maximum (4GB) to total memory usage.
Another observation is with shadowDom we have a huge number of DOM node created (more than 2lc) here.

Depending on the size style tag that we have it creates high memory usage. Is there any option(config) to modify the style tag not getting duplicated per instance?

Flags: needinfo?(continuation)
Flags: needinfo?(bugs)
Flags: needinfo?(709922234)

(In reply to 709922234 from comment #19)

@msbasanth This should use the Constructable Stylesheets API

https://bugzilla.mozilla.org/show_bug.cgi?id=1520690

Thanks for the reply

I will look into it.
(In reply to 709922234 from comment #19)

@msbasanth This should use the Constructable Stylesheets API

https://bugzilla.mozilla.org/show_bug.cgi?id=1520690

Thank you @709922234 with Constructable Stylesheets API I could see the style duplication per instance of shadow dom is not there.
i.e. by layout.css.constructable-stylesheets.enabled to true reduced the memory usage in my case from 6GB to 470MB.

I could see this option is available in Fireox Nightly (86.0a1 (2020-12-20) ) and also in Firefox 84.0.

Any information on when we can get this enabled y default in Firefox? :)

Perhaps Erik has some estimate when we could enable Constructable Stylesheets.

Flags: needinfo?(bugs) → needinfo?(enordin)
Component: DOM: Core & HTML → DOM: CSS Object Model

Ok, so it seems most of the duplication actually comes from the text nodes in the DOM... Is there any chance to use a shared blob URI and <link rel="stylesheet" href="blob:..."> rather than <style> to inject the stylesheet inside the shadow tree? That should have roughly the same memory savings as using constructable stylesheet and doesn't need the new API.

Flags: needinfo?(emilio) → needinfo?(msbasanth)

The major memory is contributed by icon component CSS section with face types. I tried adding style as link to the component but then it is not picking face types the way it normally do when we link the styles outside shadow dom.

Is there any known restrictions @facetypes inserted using <link> inside shadowdom?

Flags: needinfo?(msbasanth)

I'm not familiar with CSS memory, sorry.

Flags: needinfo?(continuation)

With regard to enabling Constructable StyleSheets, the feature is currently blocked on implementing Observable Array for WebIDL (Bug 1683281).

I am working on getting an estimate on the scope of work required for that.

Otherwise, there remains the spec-level issue that is still be discussed regarding whether the array should be assignable or not. Here is the latest comment (as of right now) regarding this discussion:

https://github.com/WICG/construct-stylesheets/issues/45#issuecomment-719640907

Flags: needinfo?(enordin)
You need to log in before you can comment on or make changes to this bug.