Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lighthouse "Best Practices" issue with zone.js #39484

Closed
initplatform opened this issue Oct 29, 2020 · 13 comments
Closed

Lighthouse "Best Practices" issue with zone.js #39484

initplatform opened this issue Oct 29, 2020 · 13 comments
Assignees
Milestone

Comments

@initplatform
Copy link

@initplatform initplatform commented Oct 29, 2020

🐞 bug report

Affected Package

The issue is caused by zone.js

Is this a regression?

not applicable

Description

polyfills.ts contains:

import 'zone.js/dist/zone'; // Included with Angular CLI.

When running lighthouse on my app, I see this:

Screen Shot 2020-10-28 at 9 13 11 PM

grepping though all the files that polyfills.ts pulls in, only zone.js uses unload.

The details of the issue are here ->

https://developers.google.com/web/updates/2018/07/page-lifecycle-api?utm_source=lighthouse&utm_medium=devtools#the-unload-event

🔬 Minimal Reproduction

Running Lighthouse on any angular app should exhibit the issue.

🌍 Your Environment

Angular Version:



Angular CLI: 10.1.7
Node: 12.18.3
OS: darwin x64

Angular: 10.1.6
... animations, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, platform-server, router
... service-worker
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1001.1
@angular-devkit/build-angular   0.1001.7
@angular-devkit/core            10.1.1
@angular-devkit/schematics      10.1.7
@angular/cli                    10.1.7
@nguniversal/builders           10.1.0
@nguniversal/express-engine     10.1.0
@schematics/angular             10.1.7
@schematics/update              0.1001.7
rxjs                            6.6.3
typescript                      4.0.3

Anything else relevant?

Chrome -> Version 86.0.4240.111 (Official Build) (x86_64)

@ngbot ngbot bot added this to the needsTriage milestone Oct 29, 2020
@JiaLiPassion JiaLiPassion self-assigned this Oct 30, 2020
@JiaLiPassion
Copy link
Contributor

@JiaLiPassion JiaLiPassion commented Oct 30, 2020

@initplatform, zone.js doesn't register unload event, all event listeners will call zone.js patched version, so it looks like it is from zone.js, I just checked it, in dev mode, ng serve is using socket.js to do the live loading (maybe), so the unload event is registered by the socket.js, if you run ng build --prod and try lighthouse again, this unload warning will be gone.

@AndrewKushnir
Copy link
Contributor

@AndrewKushnir AndrewKushnir commented Oct 30, 2020

Closing this ticket based on the comment above. Feel free to reopen if the problem still exists. Thank you.

@angular-automatic-lock-bot
Copy link

@angular-automatic-lock-bot angular-automatic-lock-bot bot commented Nov 30, 2020

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@initplatform
Copy link
Author

@initplatform initplatform commented Nov 30, 2020

You can run lighthouse on our app to see it.

https://startbootstrap.com/

This is build with :

npm run ng -- build --prod --crossOrigin=anonymous --build-optimizer=true --vendor-chunk=true --statsJson=true
@initplatform
Copy link
Author

@initplatform initplatform commented Nov 30, 2020

Also.. we have upgraded to angular 11, same issue.

$ ng version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 11.0.1
Node: 12.18.3
OS: darwin x64

Angular: 11.0.0
... animations, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, platform-server, router
... service-worker
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1100.1
@angular-devkit/build-angular   0.1100.1
@angular-devkit/core            11.0.1
@angular-devkit/schematics      11.0.1
@angular/cli                    11.0.1
@nguniversal/builders           11.0.0
@nguniversal/express-engine     11.0.0
@schematics/angular             11.0.1
@schematics/update              0.1100.1
rxjs                            6.6.3
typescript                      4.0.5
@initplatform
Copy link
Author

@initplatform initplatform commented Nov 30, 2020

Also, shouldn't matter, but FWIW, npm run ng is:

"ng": "cross-env NODE_OPTIONS=--max_old_space_size=2048 ./node_modules/.bin/ng",
@gkalpak
Copy link
Member

@gkalpak gkalpak commented Nov 30, 2020

I ran Lighthouse on https://startbootstrap.com/ and the one report about unload event I got was from line 23 of the fbevents.js file (which is not related to Angular). Are you seeing something different, @initplatform?

@initplatform
Copy link
Author

@initplatform initplatform commented Nov 30, 2020

This is weird.. If I do it multiple times I see one.. or the other...

Screen Shot 2020-11-30 at 3 22 10 PM

The first time I did it, I saw the facebook one like you.. but now I only seem to be getting the polyfills one https://startbootstrap.com/polyfills-es2015.9509cf6cf3660a1b8556.js

I wonder if this may have something to do with the pwa voodoo in ngsw-worker.js ...

Are you able to run it multiple times and see the polyfills-es2015.9509cf6cf3660a1b8556.js one?

@initplatform
Copy link
Author

@initplatform initplatform commented Nov 30, 2020

This is the contents of my polyfills.ts with all comments removed:

import '@angular/localize/init';

import 'zone.js/dist/zone'; // Included with Angular CLI.

import smoothscroll from 'smoothscroll-polyfill';
smoothscroll.polyfill();

smoothscroll does not appear to be using unload -> https://github.com/iamdustan/smoothscroll/blob/master/src/smoothscroll.js

I wonder if lighthouse is incorrectly thinking zone.js is using unload, since it includes ->
node_modules/zone.js/dist/zone.js - line 2332

    var windowEventNames = [
        'absolutedeviceorientation',
        'afterinput',
        'afterprint',
        'appinstalled',
        'beforeinstallprompt',
        'beforeprint',
        'beforeunload',
        'devicelight',
        'devicemotion',
        'deviceorientation',
        'deviceorientationabsolute',
        'deviceproximity',
        'hashchange',
        'languagechange',
        'message',
        'mozbeforepaint',
        'offline',
        'online',
        'paint',
        'pageshow',
        'pagehide',
        'popstate',
        'rejectionhandled',
        'storage',
        'unhandledrejection',
        'unload',
        'userproximity',
        'vrdisplayconnected',
        'vrdisplaydisconnected',
        'vrdisplaypresentchange'
    ];
@JiaLiPassion
Copy link
Contributor

@JiaLiPassion JiaLiPassion commented Dec 1, 2020

@initplatform, just like @gkalpak said, the unload is added by fbevents.js

 g.addEventListener("unload", function() {
                        return m.forceEndBatch()
                    });
@gkalpak
Copy link
Member

@gkalpak gkalpak commented Dec 1, 2020

Here is what I believe happens:
fbevents.js registers an unload listener. When zone.js is loaded, it monkey-patches the addEventListener() method, so any calls to that method appear as if they are coming from polyfills.js. Depending on whether zone.js has been loaded before fbevents.js registers the unload listener, it might appear to LightHouse that the addEventListener() call is coming from polyfills.js or fbevents.js.

So, as @JiaLiPassion has said above, zone.js does not register any unload listeners. You can also see this by running LightHouse on an Angular app that does not import any 3rd party library that registers unload listeners (for example https://angular.io/).

I am going to close this, since there doesn't seem to be anything to be fixed in Angular or zone.js. Feel free to continue the discussion below in case I have missed something or you need more clarification.

@gkalpak gkalpak closed this Dec 1, 2020
@initplatform
Copy link
Author

@initplatform initplatform commented Dec 1, 2020

Thanks @gkalpak and @JiaLiPassion. Makes sense. Looks like I need to file a bug against facebook :)

@Splaktar
Copy link
Member

@Splaktar Splaktar commented Dec 10, 2020

Investigation

I'm seeing this in https://www.devintent.com/ which does not use fbevents.js.

I looked at each of the libraries in my polyfills.ts and the only one with the string 'unload' in it is zone.js.

Then after reading this thread, I thought that I might have been wrong... so I went and looked at https://www.devintent.com/polyfills-es2015.00bf12ee6ad9d54b5a1c.js and searched for the string in there and the only place that it was found was in the zone.js code.

Screen Shot 2020-12-09 at 16 19 08

This error alone, takes 7 points off of the Lighthouse Best Practices audit.

How to find the real culprit in your app

I think that many people are going to hit this issue. It might be worth pinning it and providing clear steps for how to track down the actual library that registers the unload listener:

  1. Open your app in incognito mode to run lighthouse audits

  2. If you see this issue in the Best Practices audit, go to your Sources tab

  3. Right click on the top folder in the left panel

    Screen Shot 2020-12-09 at 22 50 42

  4. Select "Search all files"

  5. Search for addEventListener("unload"

Screen Shot 2020-12-09 at 22 52 51

In my case, the offending library is LogRocket.

Should we write up an issue in the Lighthouse repo to ask them to make it smarter? It seems like the audit should be able to do this kind of thing automatically and save us a lot of extra issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
6 participants
You can’t perform that action at this time.