FortAwesome / angular-fontawesome

Official Angular component for Font Awesome 5+
https://fontawesome.com
MIT License
1.48k stars 149 forks source link

Big impact on compilation time and the chunk size with the pro packages #34

Closed ibenjelloun closed 5 years ago

ibenjelloun commented 6 years ago

Importing only one icon from the pro packages, results in a 1MB plus in the bundles and 10 minutes additional compiling time.

Here is a minimal code to reproduce the issue :

`import { NgModule } from '@angular/core'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { library } from '@fortawesome/fontawesome-svg-core';

import { faCircleNotch } from '@fortawesome/pro-regular-svg-icons'; library.add(faCircleNotch);

@NgModule({ imports: [FontAwesomeModule] }) export class IconModule {} `

Import this module in the app.module.ts.

I have the same behavior with smaller impact with the free packages, probably because it has less icons.

Here is a reproduction repo : https://github.com/ibenjelloun/angular-fortawesome-issue34-reprodution

after the clone just update the .yarnrc with the fontawesome registry or replace pro by free in the icon.module.ts. run yarn + yarn bundle-report

devoto13 commented 6 years ago

Are you using the latest Angular CLI and FA packages? Do you use AoT or JiT compilation? There is an increase in the build time when using imports from main, but 10 minutes sounds like too much, normally I would expect 1-2 minutes. Also bundle size should only increase ~40K, when importing only 1 icon. Can you create a reproduction repository, where we can reproduce "Importing only one icon from the pro packages, results in a 1MB plus in the bundles"? Ideally it should be a new Angular CLI application with minimal code needed to reproduce the problem.

In general I've also spotted the problem before. For now I stick with deep imports of every icon in my projects, e.g. import { faCircleNotch } from '@fortawesome/pro-regular-svg-icons/faCircleNotch'. But eventually the performance issue should get resolved.

IIRC the root cause is that UglifyJS has to tree shaken 99% of the file with icon definitions and it takes a lot of time. There are some changes, which can potentially improve the situation:

ibenjelloun commented 6 years ago

@devoto13 Thank's for your answer, I updated with a reproduction repo. Deep imports reduce the compilation time, didn't test yet the impact on the chunk size.

mateuszmrozewski commented 6 years ago

I can also confirm that deep imports of every icon solved the problem, time is now 20 times shorter.

robbaman commented 6 years ago

I have this same issue, but I use the fontawesome-pro-solid package (not the pro-regular-svg-icons package, which doesn't seem to exist according to the FontAwesome docs). Whenever I import and add just one icon to the library all icons from that package work with the <fa-icon> component.

The problem I'm facing however is that when I perform a deep import like this:

import { library } from '@fortawesome/fontawesome-svg-core';
import faCalendar from "@fortawesome/fontawesome-pro-solid/faCalendar";

library.add(faCalendar);

It works just fine in develop, but when doing a prod build (using ng build --prod) I get an error:

ERROR in src/app/app.icons.ts(4,8): error TS1192: Module '"C:/Workspaces/.../ClientApp/node_modules/@fortawesome/fontawesome-pro-solid/faCalendar"' has no default export.

robmadole commented 6 years ago

@robbaman the fontawesome-pro-solid package is not compatible with angular-fontawesome because of this very issue.

Can you switch to the pro-solid-svg-icons package instead? See the UPGRADING.md guide for some helpful tips.

robbaman commented 6 years ago

I'll take a look when I'm back at work. Note though that it actually does work when using this import statement:

import * as faCalendar from "@fortawesome/fontawesome-pro-solid/faCalendar";

Thanks for the update though, I'll check back in once I've had an opportunity to try your suggestion. Probably won't be before Sunday evening though.

robbaman commented 6 years ago

I've updated my project using the steps specified in the UPGRADING.md file and while it does seem to work, the production build time for angular using ng build --prod has has gone up immensely. I haven't timed it, but I think it hangs at the step 92% chunk asset optimization UglifyJSPlugin for at least a few minutes. After which the vendor chunk is up to 7.5MB.

Using deep links ea:

import { faCalendar } from "@fortawesome/pro-regular-svg-icons/faCalendar";
import { faArrowRight } from "@fortawesome/pro-regular-svg-icons/faArrowRight";

instead of

import { faCalendar, faArrowRight } from "@fortawesome/pro-solid-svg-icons";

Does seem to fix the package size issue and make the build time acceptable, but obviously this isn't exactly a pretty solution :)

MurhafSousli commented 6 years ago

same here https://github.com/MurhafSousli/ngx-sharebuttons/issues/280

screenshot-127 0 0 1-8888-2018 05 22-12-13-43

Isn't it applicable to export the icons the same way rxjs 6 does with the operators?

mlwilkerson commented 6 years ago

@robbaman Yes, I've been working on that "92% issue", as has @devoto13. For now, a workaround is to swap out UglifyJS for Babel Minify. See my reproduction and discussion of this over in the uglifyjs-webpack-plugin repo.

robbaman commented 6 years ago

@robmadole You mentioned switching to the pro-solid-svg-icons according to the UPGRADING.md document which I did (and it works ok now), but I'm still a bit confused about which package does what.

According to the documents at https://fontawesome.com/how-to-use/use-with-node-js the correct npm package to use is the fontawesome-pro-solid package. Looking at the NPM registry this last package was updated recently, but the pro-solid-svg-icons package hasn't received an update for months.

I ask because I noticed a new version being out (5.0.13), which I seem to be unable to use in my project because I have to use the pro-solid-svg-icons package per your instructions.

Any clarification on this point would be great.

mlwilkerson commented 6 years ago

@robbaman pro-solid-svg-icons is the name of the new icon pack under the forthcoming 5.1 release. It's in preview now. That icon package used to be called fontawesome-pro-solid under 5.0. Some significant drivers of the 5.1 release are how we package these JavaScript modules to improve tree-shaking and TypeScript support. This angular-fontawesome component, in particular, is built to work with the 5.1 branch (and helped to drive some of those changes).

To view the equivalent documentation for the preview release, add "preview" to the url like this: https://fontawesome.com/preview/how-to-use/use-with-node-js

The reason you'll see more recent releases on the 5.0 branch is because we continue to issue maintenance releases.

mlwilkerson commented 6 years ago

@robbaman Is there something (like a new icon?) in the 5.0.13 release of fontawesome-pro-solid that you can't get from the most recent release of pro-solid-svg-icons? If so, that might indicate that we overlooked updating our 5.1 pre-releases when issuing the last 5.0 release. Normally, we re-release the preview packages when we add icons to the 5.0 branch so that they remain caught up.

robbaman commented 6 years ago

@mlwilkerson Thanks for clearing that up. There wasn't anything in particular that I'm missing, I was just using npm outdated on my project to fix some unrelated outdated packages and noticed there was no update for FontAwesome, even though I'd received mails that the new shiny 5.0.13 was out.

This led me to investigate and get lost in the package-forest...

mlwilkerson commented 6 years ago

Ah, the package-forest, which grows ever more deep...and dark.

robbaman commented 6 years ago

We totally should get an icon for that! But for now I'll stop spamming this useful topic with my ignorant questions...

robmadole commented 6 years ago

@robbaman we aren't updating the latest tag for those packages like we need to. I just updated those so an npm outdated should pick it up.

mlwilkerson commented 6 years ago

For others who hit the 92% chunk asset optimization UglifyJSPlugin problem, please see terser#50. There was a performance regression in uglify-js/uglify-es/terser that impacts JS modules having a format like our icon packages. There's also a patch there that you could try out to see if it solves your problem.

mlwilkerson commented 6 years ago

Looks like Webpack will be released this week with terser instead of uglify-es, which should include the fix for this. In the meantime, another potential work around (for yarn projects) is suggested here.

peturh commented 6 years ago

I've found a fix for me.

Before I imported the icons in the component, this took 30 minutes to build with ng build --prod Example in app.component.ts:

import { faHeart } from  '@fortawesome/pro-light-svg-icons';

// then assign the faHeart to your local variabel and use it in markup [icon]="faHeart"

Now instead it takes 12s. It's still twice as long as it took before. But it's good enough.

my shared.module.ts:

import { library } from '@fortawesome/fontawesome-svg-core';
import { faHeart } from '@fortawesome/pro-light-svg-icons/faHeart'; //notice I'm referencing faHeart directly
library.add(faHeart)

// then use [icon]="['fal', 'heart']" syntax
devoto13 commented 6 years ago

Angular CLI 7.0.0-beta.2 (make sure you also update @angular-devkit/build-angular to 0.9.0-beta.2) replaced uglify-es minifier with terser, which contains fix for the bug causing this issue. Now it should be possible to import icons from package root without build slowdown.

Please give it a try and let me know if it works for you as well.

robmadole commented 6 years ago

Ah excellent. Good to know @devoto13

jenbuzz commented 6 years ago

@devoto13 Thank you. I had to update other packages as well to get it to work.

I updated @angular/* to 7.0.0-beta.7, @angular-devkit/build-angular to 0.9.0-beta.2, and typescript to 3.0.1.

wja123 commented 5 years ago

Yeah, deep importing fixed this issue for me.

devoto13 commented 5 years ago

Angular CLI 7+ uses terser as a minifier and therefore includes the fix for the slow compilation. Please open a new issue with the reproduction if you still experience slow builds using Angular CLI 7+.

If you're stuck with an older version you can use deep imports approach as a workaround.

kimamula commented 5 years ago

Unfortunately deep importing still has a significant effect on the decrease of the resulting chunk size (~200kB for @fortawesome/free-solid-svg-icons after gzipped). I am using @fortawesome/free-solid-svg-icons@5.4.1, @fortawesome/angular-fontawesome@0.3.0, terser@3.10.2 and @angular-devkit/build-optimizer@0.10.6.

devoto13 commented 5 years ago

@kimamula How do you measure this? Is it webpack-bundle-analyzer? I remember there were some issues with it reporting sizes of modules before they are processed by minifier. Can you try to check with source-map-explorer instead?

kimamula commented 5 years ago

@devoto13 Thanks for the response. Yes I was using webpack-bundle-analyzer. And now I confirmed source-map-explorer showed a similar result.

I think I can provide a simple repro when I have time.

devoto13 commented 5 years ago

@kimamula I see. Repro would be super useful! Thanks!

kimamula commented 5 years ago

@devoto13 I am sorry that I found that this was totally my fault. By some chance "module": "es2015" has been removed from my tsconfig.json and that was the problem. After setting "module": "es2015" in tsconfig.json, tree shaking is working fine.

devoto13 commented 5 years ago

@kimamula Happy to hear that you solved it!

And thanks for letting us know what problem was.

VladBrok commented 9 months ago

import { faCircleNotch } from '@fortawesome/pro-regular-svg-icons/faCircleNotch'

I reduced @fortawesome bundle size in angular project from 1.1mb to 139.27kb by changing imports of 5 icons from import { faSomeIcon } from '@fortawesome/pro-regular-svg-icons/ to import { faSomeIcon } from '@fortawesome/pro-regular-svg-icons/faSomeIcon. Thanks for help