question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

inlineCriticalCss + extractCss have problems with global styles that can cause layout shifts

See original GitHub issue

🐞 Bug report

What modules are related to this issue?

  • aspnetcore-engine
  • builders
  • common
  • [x ] express-engine
  • hapi-engine

Is this a regression?

No

Description

I tested the new experimental inlineCriticalCss and there are some issues with global styles defined under "styles": [...] in the angular.json file…

build": {
  ...
  "options": {
    ...
    "styles": [ ... ]
  },
  ...
}

…for example the /src/styles.[s]css or NG Material themes. To make global styles work with inlineCriticalCss you must use extractCss: true to inline some of these styles otherwise they will be added at runtime. However, this causes some selector errors in the console. So I measured the performance of different solutions with Lighthouse (Chrome 87).

inlineCriticalCss:true + extractCss:true

Bildschirmfoto 2020-12-12 um 17 23 39

With this combination you get styles errors in the console. For example for NG Material.

Bildschirmfoto 2020-12-12 um 14 02 43

inlineCriticalCss:true + extractCss:false

inlineCriticalCss-noExtractCss

inlineCriticalCss:false + extractCss:true

noInlineCriticalCss+extractCss

PS. Ignore the problems that affect the run of Lighthouse. It was audited in an incognito window but Firebase is used and writes to IndexedDB.

tl;dr

In the current form of inlineCriticalCss it looks like you get the best performance (because of lower LCP & CLS) with global styles that can cause layout shifts without inlineCriticalCss and extractCss set to true.

🔬 Minimal Reproduction

  1. Add global styles that can cause layout shifts such as .foo { display: flex; } when applied later and/or a NG Material theme to the styles option in your angular.json file.
  2. Enable or disable inlineCriticalCss and extractCss in the appropriate files.
// server.ts
  server.engine(
    "html",
    ngExpressEngine({
      bootstrap: AppServerModule,
      inlineCriticalCss: true,
    })
  );
// angular.json
      "architect": {
        "build": {
          ...
          "options": {
            ...
            "styles": [
              "node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
              "src/styles.scss"
            ],
            ...
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "commonChunk": false,
              "extractCss": true,
              "aot": true,
              "buildOptimizer": true
            }
          }
  1. Run NODE_ENV=production ng build --prod && ng run <projectName>:server:production.
  2. Run node dist/server/main.js.

🌍 Your Environment


Angular CLI: 11.1.0-next.2
Node: 12.18.0
OS: darwin x64

Angular: 11.1.0-next.2
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... platform-server, router
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1100.4
@angular-devkit/build-angular   0.1101.0-next.2
@angular-devkit/core            11.1.0-next.2
@angular-devkit/schematics      11.1.0-next.2
@angular/cdk                    11.0.1
@angular/fire                   6.1.4
@angular/material               11.0.1
@nguniversal/builders           11.1.0-next.0
@nguniversal/express-engine     11.1.0-next.0
@schematics/angular             11.1.0-next.2
@schematics/update              0.1101.0-next.2
rxjs                            6.6.3
typescript                      4.1.3

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:8

github_iconTop GitHub Comments

2reactions
akaufmanncommented, Dec 14, 2020

Hi @alan-agius4!

LCP, I download the reproduction with and without inlineCriticalCss, I get a constant LCP of ~1.2ms/1.4ms

Yes correct, I see that too. In both cases, the numbers for LCP fluctuate in the same range for multiple runs.

Thanks @alan-agius4 for finding time to look at this so quickly and creating a fix in the Critters repo.

2reactions
alan-agius4commented, Dec 14, 2020

Hi @akaufmann,

I did take a look at the reproduction and found that;

  • Critters is treating the CSS class .md\:flex as a pseudo-classes instead of a CSS selector, this is causing the class not to be inlined and caused a drastic CLS. I have PR for this https://github.com/GoogleChromeLabs/critters/pull/68
  • LCP, I download the reproduction with and without inlineCriticalCss, I get a constant LCP of ~1.2ms/1.4ms
Read more comments on GitHub >

github_iconTop Results From Across the Web

How To Fix Cumulative Layout Shift (CLS) Issues
CLS is about measuring unexpected shifts. Scrolling should not cause content to move around if a page is built optimally, and similarly hovering ......
Read more >
Extracting CSS into JS with Angular 11 (deprecated extractCss)
One of the changes for Angular CLI 11.0 is deprecation of extractCss configuration property. Getting error “extractCss is deprecated” comes ...
Read more >
This is how angular-cli/webpack delivers your CSS styles to ...
This is how angular-cli/webpack delivers your CSS styles to the client. Have you ever wondered how is it possible to import CSS into...
Read more >
How to Build a CSS Library with Vite.js - freeCodeCamp
This is cool, but it might cause a problem in larger projects where the CSS file might become very big if it had...
Read more >
Separating CSS - SurviveJS
The plugin then picks up the result aggregated by the loader and emits a separate file with the styling. It can be potentially...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found