Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

(WIP)(core): add scoped zone.js support #1126

Closed
wants to merge 2 commits into from

Conversation

JiaLiPassion
Copy link
Collaborator

Add scoped zone.js support.
The purpose of this PR is the same as this one #1073.
To allow zone.js only run inside a scope. So in Angular Elements, we can let zone.js only work inside Angular Elements without impacting outside world.

  1. monkey patch every async APIs before zone.run
  2. remove monkey patch after zone.run.

This can work but have a performance impact, although repatch and remove patch is only assign references, but the amount of the async APIs is a lot (espesially onProperty), so there will be some performance loss.

  • The new idea in this PR is,
  1. before zone.run, set a flag I am in the zone.
  2. after zone.run, set a flag I am outside of zone.

And we still monkey patch all async APIs (but only once), it will look like this.
For example, setTimeout.

// keep a native setTimeout
const nativeSetTimeout = window.setTimeout;
window.setTimeout = function() {
  if (flag === 'I am outside of zone') {
    return nativeSetTimeout.apply(this, arguments);
  }
  return zonePatchedSetTimeout(...)
}

So we will wrap the async API, if currently, we are not in zone, we will just
use the native APIs.

So we don't have any performance loss when call zone.run.

@mhevery, @robwormald, please review this idea is ok or not, I am adding test cases to make sure all APIs can work in both mode.
If this idea is OK, we only need to do a simple setup to let Angular Elements support scoped zone like this.

 import 'zone.js';
 (Zone as any).__set_scope('scoped');

That's all, please review, thank you.

@mhevery
Copy link
Contributor

mhevery commented Sep 17, 2018

Hi @JiaLiPassion and thank you for this PR. I am a little confused about this PR. My understanding is that RootZone is indistinguishable from having no zone.js in the browser. So when I see

        if (api.getCurrentScope() === 'outside') {
          return originalMethod.apply(this, arguments);
        }

it is not clear to me how this is different from being called in the RootZone.

If there are differences in how the RootZone behaves than we should fix that so that the RootZone is indistinguishable from no zone.js being placed on the page.

The flag getCurrentScope() === 'outside' seems to be just another way of talking about the RootZone

Any insight on this would be appreciated.

@collinstevens
Copy link

@JiaLiPassion Is there a reason why this was closed? Is there another fix covering this somewhere? I'm coming over from angular/angular#24185.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants