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

Angular 8 Polyfills ES2015 Bundle Javascript Execution Time is very high - Google Pagespeed shows warning #14871

Closed
naveedahmed1 opened this issue Jun 24, 2019 · 18 comments
Labels

Comments

@naveedahmed1
Copy link

🐞 bug report

Is this a regression?

Yes, the previous version in which this bug was not present was: 7.x

Description

After upgrading to Angular 8, the Google Pagespeed score of my website has been decreased.
One of the warning Pagespeed displays is Reduce JavaScript execution time, which is 4.6 seconds. Its surprising that most of the script execution time is for the "Angular Polyfills ES2015 Javascript bundle" which is 3.8 seconds.

angular-polyfills-es2015-javascript-execution-time

Another warning it shows is "Minimize main-thread work" which is 6.5 s and I think its also due to the polyfills bundle.

angular-main-thread-work

🔬 Minimal Reproduction

Check Pagespeed score for any Angular website with SSR enabled and notice the warnings for the Mobile devices.

🔥 Exception or Error




Google Pagespeed performance issues:
JavaScript execution time is very high for Pollyfills bundle.
Main thread work is high, and probably its also due to the Polyfills.

🌍 Your Environment

Angular Version:





Angular CLI: 8.1.0-beta.2
Node: 10.16.0
OS: win32 x64
Angular: 8.1.0-next.3
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... platform-server, router, service-worker

Package                                    Version
--------------------------------------------------------------------
@angular-devkit/architect                  0.800.1
@angular-devkit/build-angular              0.800.1
@angular-devkit/build-optimizer            0.800.1
@angular-devkit/build-webpack              0.800.1
@angular-devkit/core                       8.0.2
@angular-devkit/schematics                 8.0.2
@angular/cdk                               8.0.1
@angular/cli                               8.1.0-beta.2
@angular/fire                              5.2.1
@angular/flex-layout                       8.0.0-beta.26
@angular/http                              8.0.0-beta.3
@angular/material                          8.0.1
@angular/material-moment-adapter           8.0.1
@angular/pwa                               0.800.2
@ngtools/webpack                           8.0.1
@nguniversal/module-map-ngfactory-loader   8.0.0-rc.1
@schematics/angular                        8.0.2
@schematics/update                         0.801.0-beta.2
rxjs                                       6.5.2
typescript                                 3.4.5
webpack                                    4.30.0

@gkalpak gkalpak transferred this issue from angular/angular Jun 24, 2019
@alan-agius4
Copy link
Collaborator

alan-agius4 commented Jun 24, 2019

@naveedahmed1, which are the polyfills that you have defined in polyfills.ts?

@naveedahmed1
Copy link
Author

Here's my polyfills.ts file:

`/** IE9, IE10 and IE11 requires all of the following polyfills. **/
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

/** IE10 and IE11 requires the following for the Reflect API. */
import 'core-js/es6/reflect';

/** Evergreen browsers require these. **/
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import 'core-js/es7/reflect';

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

/***************************************************************************************************

  • APPLICATION IMPORTS
    */

import 'hammerjs';

import { polyfill } from 'smoothscroll-polyfill';
polyfill();
`

@clydin
Copy link
Member

clydin commented Jun 24, 2019

None of these are required to be manually imported with 8.0+:

import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

The two reflect imports are also only needed if the project directly uses the Reflect APIs (typically this is rare).

import 'core-js/es6/reflect';
import 'core-js/es7/reflect';

@naveedahmed1
Copy link
Author

@clydin I removed these imports and it reduced the JavaScript Execution time from 4.6s to 3.4s and Main thread work from 6.5s to 4.9s.

I think its still a lot.

Can you please confirm if below import is necessary or can we remove that as well?

import 'zone.js/dist/zone';

@alan-agius4
Copy link
Collaborator

alan-agius4 commented Jun 25, 2019 via email

@naveedahmed1
Copy link
Author

@alan-agius4 what else could be causing the issue? Lighthouse show errors "Reduce JavaScript execution time" and "Minimize main-thread work".

@clydin
Copy link
Member

clydin commented Jun 25, 2019

zone.js is required and included in all Angular projects.

hammerjs is quite commonly used and we haven't had any reports such as this in relation to its use.

I'm not familiar with the last one, however (smoothscroll-polyfill).

Can you try commenting out each one (probably one at a time) to see if that has any effect?

@sod
Copy link

sod commented Jul 8, 2019

There is a typo in zone.js for 2 years that causes massive CPU & memory burn. PRs are ignored for a year.

angular/zone.js#1102
angular/angular#31208

Edit: Fixes got merged 🎉

@longgt
Copy link

longgt commented Jul 10, 2019

#6325
#13491

@naveedahmed1
Copy link
Author

@clydin I have removed everything and now only have zone.js and hammerjs, still the situation is same.

@mgechev
Copy link
Member

mgechev commented Jul 11, 2019

@naveedahmed1 did you deploy your web app publicly? I can try to have a look and profile to see what's wrong.

@naveedahmed1
Copy link
Author

@mgechev yes its available at https://www.mustakbil.com/

@sod
Copy link

sod commented Jul 11, 2019

There is way to much javascript in main.js (1,9 MB).

By glossing over https://www.mustakbil.com/main-es2015.6fa4605db52f9bbfb86f.js it seems like you use moment.js and bundle all locales with it (thats ~400kb). You have to configure webpack to pick only the locales you need, like described in https://github.com/jmblog/how-to-optimize-momentjs-with-webpack. Or you switch to something like https://github.com/iamkun/dayjs thats way leaner by default and has a similar syntax to moment.

Then there seems to be a lot of material design. Be sure to only include the modules you really use.

If you use angular-cli, you can inspect the composition of your bundles & chunks. A good way to see if there is to much bundled with the app. You can do that from the commandline with:

# generates a stats json file along with your build
ng build --prod --aot --stats-json

# opens a page in your browser to visualize bundle composition:
npx webpack-bundle-analyzer dist/*/stats-es2015.json

@sod
Copy link

sod commented Jul 11, 2019

On the landingpage https://www.mustakbil.com/ you have an incredible amount of force reflows. If you do a profiling via chrome in the web inspector performance tab, and you see this:
image
The purple pins are force reflows. So you put something into the dom, then you call a method that forces the browser to update the view.

It's the lazy loaded images in the job cards, that fade in upon scroll. You might wanna change the code so it doesn't do the visiblity check right after it got put into the dom. We on our page batch those things up and process them after a single setTimeout to avoid any force reflows.

@sod
Copy link

sod commented Jul 11, 2019

On https://www.mustakbil.com/employers the 3 boxes on the top left seems to need an incredible amount of computation:
image

If you profile it, it looks like 70% of CPU is spend there:
image

It may have to do with how the material design qantity dropdown with 500 values (number 1 to 500) is constructed. But I'm not sure.

@filipesilva
Copy link
Contributor

I think (but have not verified) that I know why the Total CPU time in your original post shows up very high for polyfills.

It's not the polyfills themselves that are spending so much time, but rather that there is a lot of time spent in inside zone.js calls. Since zone.js is imported in polyfills, the time is logged as spent there. This is similar to how stack traces for some errors show up from polyfills as well, and then you have to check the whole stack trace to figure out in what component the error came from.

Which is to say, I think the Total CPU time for polyfills is actually spent on your app. You can validate this by importing zone.js in main.ts instead of in polyfills.

Also, I think that removing a given volume of code shouldn't ever affect Total CPU time much. That value is the sum of Script Evaluation (how long it took running the code) and Script Parse (how long it took to parse all the code). The bigger one is Script Evaluation.

Which is to say, it looks like your code is doing a lot of work. This is similar to what @sod found. You can validate this by commenting out your bootstrap code in main.ts. If my interpretation is correct, you will get a very low evaluation time.

@mgechev
Copy link
Member

mgechev commented Jul 11, 2019

@sod, @filipesilva, thanks for looking into that :)

@naveedahmed1, you should be able to take it from here. Doesn't seem like a CLI issue. Let us know how it goes!

@mgechev mgechev closed this as completed Jul 11, 2019
@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

7 participants