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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

NG 8 IE 11 & Differential Loading #16653

Open
vespertilian opened this issue Jan 9, 2020 · 8 comments
Open

NG 8 IE 11 & Differential Loading #16653

vespertilian opened this issue Jan 9, 2020 · 8 comments

Comments

@vespertilian
Copy link

@vespertilian vespertilian commented Jan 9, 2020

馃悶 bug report

Affected Package

The issue is caused by package @angular/ ... not sure cli? it's a build issue

Description

So there are a few things to track here:

Specifically in IE11

If I build the linked project with the tsconfig.json target "es5" everything works. (baseline).

If I build the project with tsconfig.json target "es2015" a few things do not work as I expect:

  1. It builds both es2015 and es5 bundles. Strangely IE11 will load both the es2015 and the es5 bundles, when I expected it to just load the es5 bundle. Chrome correctly loads just the es2015 bundle.

ie11-loading-both-bundles

  1. The es5 bundle created when differential loading is enabled is larger than the es5 bundle created when ts.config is set to es5 and differential loading is off. In my small sample app the differences are not that large but in our production app the difference is substantial. I would have thought that the es5 differential loading bundle would be no bigger than the non differential loading use case.

Differential loading
ng8-ie11-app-diff-loading

No differential loading
ng8-ie11-no-d-loading

From the above images you can see that the main bundle for the base ES5 scenario is 282 but for the differential loading its 298. Again this is a small sample app, in our production app this is more pronounced.

  1. The bundle created produces errors when running in IE11, loading ESRI maps. Again I find this strange as I would have assumed the es5 differential loading bundle would be equivalent to the bundle created when setting ts.config to es5, which works fine.

ie11-error

馃敩 Minimal Reproduction

https://github.com/vespertilian/ng8-ie11

build with npm run build
serve the dist build with ng run serve-dist (might need to install http-server)

change ts.config from es5 to es2015 to build the different packages.

馃敟 Exception or Error

Just for the third case


ERROR Error: Uncaught (in promise): TypeError: Object expected

馃實 Your Environment

Angular Version:



Angular CLI: 8.3.22
Node: 12.14.0
OS: darwin x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.21
@angular-devkit/build-angular     0.803.21
@angular-devkit/build-optimizer   0.803.21
@angular-devkit/build-webpack     0.803.21
@angular-devkit/core              8.3.21
@angular-devkit/schematics        8.3.22
@angular/cli                      8.3.22
@ngtools/webpack                  8.3.21
@schematics/angular               8.3.22
@schematics/update                0.803.22
rxjs                              6.4.0
typescript                        3.5.3
webpack                           4.39.2

Anything else relevant?

@vespertilian vespertilian changed the title IE 11 & Differential Loading NG 8 IE 11 & Differential Loading Jan 9, 2020
@destus90

This comment has been minimized.

Copy link

@destus90 destus90 commented Jan 10, 2020

  1. Check out the official docs (alert number 2) or this issue.
  2. Is there any difference between the images? Seems like you have uploaded the same image twice.
@vespertilian

This comment has been minimized.

Copy link
Author

@vespertilian vespertilian commented Jan 11, 2020

@destus90 Thank you for your reply.

2- Yes I uploaded the same image twice 馃榿 (fixed)

1- I see from your link on the angular site it does mention:

"Some legacy browsers still download both bundles, but only execute the appropriate scripts based on the attributes mentioned above."

That's a little disappointing, we just moved to Angular 8 and differential loading seemed to be one of the killer features, reading @StephenFluin blog post I was excited. The thing is that most of our users are running modern browsers, it's just IE11 that's the issue for corporate clients and I feel like this is where differential loading would shine. However it looks like for our clients this is the reality:

ie-bundle-size

Could we not also just wrap the ES2015 bundle in something like:

<!--[if !IE]>--> <script src="scripts.js"></script> <!--<![endif]-->

I feel like this is a solvable problem for the whole Angular community, I also feel like IE11 should be the focus of differential loading as most of the other browsers are evergreen and can all use the 2015 feature set.

3 -

Still the biggest issue for me is that the es5 bundle (non differential loading works) but the es5 bundle (when differential loading is turned on) does not work. But they should be the same es5 bundle, it's just that we have a second bundle for modern browsers, right?

The most upvoted "How do I make Angular 8 compatible with IE11?" answer on stack overflow is to disable differential loading, but it should work with IE11 and differential loading, so I feel like others have this issue maybe I am just the first one to raise it.

@zero-1

This comment has been minimized.

Copy link

@zero-1 zero-1 commented Jan 13, 2020

linked the wrong issue id in prev edit...
the build breaking in IE11 -- please check #16366

@gkalpak gkalpak transferred this issue from angular/angular Jan 13, 2020
@alan-agius4

This comment has been minimized.

Copy link
Collaborator

@alan-agius4 alan-agius4 commented Jan 13, 2020

Can you try to update @angular-devkit/build-angular to 0.803.22 please?

With regards to the conditional html comments ie: <!--[if !IE]--> these are not supported from IE 10 onwards.

@zero-1

This comment has been minimized.

Copy link

@zero-1 zero-1 commented Jan 13, 2020

Tried the attached demo project with
@angular-devkit/architect 0.803.22
Still able to reproduce the problem....

Downgrading to ...
@angular-devkit/build-angular": "0.803.19
fixes the issue......

This still leaves the bigger issue of both packages being downloaded on IE 11
It seems the choices are ...

  1. go with ES2015. Reduce the download size for modern browser while doubling(almost) it for IE 11.
  2. Or... go with ES5
@vespertilian

This comment has been minimized.

Copy link
Author

@vespertilian vespertilian commented Jan 13, 2020

@alan-agius4

Maybe we could use something like:

https://stackoverflow.com/questions/29987969/how-to-load-a-script-only-in-ie

<script type="text/javascript">
    if(/MSIE \d|Trident.*rv:/.test(navigator.userAgent))
        document.write('<script src="../nolng/js/ex1IE.js"><\/script>
        <script src="../nolng/js/ex2IE.js"><\/script>');
    else
        document.write('<script src="../nolng/js/ex1.js"><\/script>
       <script src="../nolng/js/ex2.js"><\/script>');
</script>

to prevent downloading both bundles in IE11.

@clydin

This comment has been minimized.

Copy link
Member

@clydin clydin commented Jan 14, 2020

The current method used for execution bifurcation was chosen after research into a variety of methods. There are indeed tradeoffs for some older browsers (IE in particular). However, as best explained in this comment from one of the Chrome team members, the real world affect of the double download is generally minimal to non-existent. This is in contrast to the effect of the method in the above comment (as well as others), which can have large performance issues for modern browsers especially on mobile platforms.

If the user base of a particular application is predominantly using IE, targeting ES5 may be the best option for the application. It is also possible to post process the generated index to alter the differential loading method if testing reveals non-ideal performance metrics for a given application's usage environment. Another option would be using a server generated index per request and opens up potential additional avenues regarding attempts at browser detection guided script selection.

@vespertilian

This comment has been minimized.

Copy link
Author

@vespertilian vespertilian commented Jan 14, 2020

@clydin thanks for the link. Web development = complexity!

Your argument about desktop vs mobile does make sense. For us, currently, I don't think we can choose almost a double initial bundle for IE and other older browsers to get faster performance in modern browsers, as our bundle is embarrassingly large 馃榿 . Hopefully, this will change in the future.

I feel like the marketing for this feature missed the mark a bit.

The statement "When users load your application, they鈥檒l automatically get the bundle they need." from Version 8 of Angular 鈥 Smaller bundles, CLI APIs, and alignment with the ecosystem is not super accurate. As you pointed out it's really a compromise, and while modern browsers get better smaller bundles and parse performance older browsers initial bundle size is almost doubled, I know the docs do make a cursory reference to this but it might be worthwhile to make this tradeoff more prominent, for anyone else with embarrassingly large bundles, as I thought I could just drop this in and win!

I don't think we will be using this feature for the next couple of months until our initial bundle is not embarrassingly large (working on it), but we should still work to fix issues 2 and 3 for others 馃槂 .

Thanks again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can鈥檛 perform that action at this time.