Uploaded image for project: 'Magnolia Frontend Helpers'
  1. Magnolia Frontend Helpers
  2. MGNLFE-428

PageEditorBridge listeners create memory leak with Angular Universal SSR

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Neutral
    • 1.4
    • 1.3.3
    • Angular Renderer
    • None
    • node v16.15.0

    Description

      Steps to reproduce

      1. Clone the spa minimal demos repository: https://git.magnolia-cms.com/scm/demos/minimal-headless-spa-demos.git

      2. Follow the setup instructions for the Angular Universal demo, so that you have a page available at http://localhost:4200/angular-universal-minimal: https://git.magnolia-cms.com/projects/DEMOS/repos/minimal-headless-spa-demos/browse

      3. Restart the SPA with node.js in debug / profiling mode

        1. Stop the `dev:ssr` run

        2. Run the following command from the angular-universal-minimal directory: `node --trace-gc --inspect-brk dist/angular-universal-minimal/server/main.js`

        3. Open Chrome and type `about:inspect` in the address bar

        4. Click the "inspect" link on the remote target `dist/angular-universal-minimal/server/main.js` in the Devices tab

        5. A DevTools window opens for the Node server process

        6. Resume script execution
      4. Load the page (http://localhost:4200/angular-universal-minimal) repeatedly - about 100 times produces a noticeable result


      5. Take a heap snapshot from the DevTools window of the Node server process, in the Memory tab
      6. Expand the `Object` tree branch
        Screenshot of the heap view:

       

      Link to a heap dump: 
      https://drive.google.com/file/d/1LhlKFrPNlWa-lp1psUIqhdF9GxTb4FEk/view?usp=sharing

      Actual results

      • There is one large object in the heap (16 MB for about 100 page loads) containing an array named `updatestate`, which contains callback functions. These function objects each hold a reference to an instance of the Magnolia `EditablePageComponent` as their `this` context.
      • The `updatestate` array grows larger with every Angular Universal render, as callbacks are pushed to it in the constructor of `EditablePageComponent` (delegating to `PageEditorBridge`) but never cleared on Angular destroy events
      • The references to `EditablePageComponent` can retain quite a bit of memory in the heap, as the components hold references to the entire Angular context

        Expected results

      • Objects used for a single Angular Universal render are not retained when the rendering is completed, resp. for the remainder of the server running time
      • The instances of EditablePageComponent are properly garbage collected after an Angular Universal render

        Workaround

      No effective workaround found

      Development notes

      Checklists

        Acceptance criteria

        Attachments

          Issue Links

            Activity

              People

                plequoc Phong Le Quoc
                jc.puja@codify.ch Jean-Christophe Puja
                DeveloperX
                Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Work Started:

                  Checklists

                    Bug DoR
                    Task DoD

                    Time Tracking

                      Estimated:
                      Original Estimate - Not Specified
                      Not Specified
                      Remaining:
                      Remaining Estimate - Not Specified
                      Not Specified
                      Logged:
                      Time Spent - 18d 4.5h
                      18d 4.5h