Skip to content
This repository was archived by the owner on Sep 16, 2022. It is now read-only.
This repository was archived by the owner on Sep 16, 2022. It is now read-only.

Off-stage rendering - CLS optimization #1900

@daniel-v

Description

@daniel-v

Hello there!

With the introduction of Web Vitals, we started to see some new metrics we should pay attention to. One of them is CLS (Content Layout Shift). Right now, our application, an SPA, is seeing huge numbers for that.
Part of the reason for the large CLS is the amount of things the app needs to do before the app would completely finish loading (deferred libraries, images, etc).

We came up with a way to work around this problem, while we are working on a component level as well, to improve. The idea is (hardly new):

  1. instead of an app scaffold (the good ol' Loading please wait in a pretty form), we will use cached pre-rendered snapshot of the page
  2. load the app and start it off-stage (render into a document fragment)
  3. intercept, record user events
  4. replace the pre-rendered "scaffold" with the Angular app generated DOM tree
  5. play back events

Out of all that, as a first step, we are looking into off-stage rendering. Right now, the approach is that we register a service ApplicationMountLocator (needs better name) which is used in ApplicationRef.bootstrap to locate the rootElement.

Example implementation: https://github.com/easyling/angular/blob/8c91af5b4d9114fbec1a0ca6ec46a368a25bdf6a/angular/lib/src/core/application_ref.dart#L72

This would allow use to do something like:

class FragmentApplicationMountLocator implements ApplicationMountLocator {
  @override
  Element locateMountElement(String componentSelector) {
    offStageFragment = DocumentFragment();
    final element = Element.tag(componentSelector);
    offStageFragment.append(element);
    return element;
  }
}

Leter, we can then relocate the document fragment's root element into the DOM to get a fully loaded/bootstrapped Angular app.

Of course, I'm open to ideas how better to approach this issue. Is it likely that such a solution could land in Angular?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions