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

Allow custom decorators that use lifecycle hooks in AoT - these are our version of hooks, but we can't use them #30497

Closed
alshdavid opened this issue May 15, 2019 · 11 comments
Labels
area: core Issues related to the framework runtime feature Issue that requests a new feature freq1: low
Milestone

Comments

@alshdavid
Copy link

When writing a custom decorator, lifecycle methods you patch are removed in AoT because the compiler doesn't check that custom decorators are using them.

This results in an inability to create custom decorators with any meaningful component specific behaviour.

React uses hooks to help patch into setup/teardown of your functional components, decorators are Angulars form of hooks. It would be super useful to have this functionality in Angular.

@christopher-kiss
Copy link

christopher-kiss commented May 16, 2019

@alshdavid,

It looks like the onChanges life cycle works, but ngOnInit doesn't. Using a production build running with AoT, in the console I can see required and on changes, but not init. Switching to JIT development I correctly see the init messages.

Would be great to have this fixed.

export function RequiredInput<TValue>(defaultValue?: TValue) {
    return function<TInstance extends { [P in TKey]: TValue }, TKey extends keyof TInstance>(
        propertyClass: TInstance & Target,
        propertyKey: TKey & string
    ) {
        console.log('required');
      
        const originalInit = propertyClass.ngOnInit;
        const originalChanges = propertyClass.ngOnChanges;

        propertyClass.ngOnChanges = function(changes: SimpleChanges) {
            console.log('on changes');
             if (originalChanges) {
                 originalChanges.apply(this, [changes]);
             }
        };

        propertyClass.ngOnInit = function() {
            console.log('init');
            if (originalInit) {
                 originalInit.apply(this);
            }
        };
    };
}

Edit -
As a workaround, I've had to resort to creating a class that implements these and extend this class.

export abstract class RequiredClass implements OnInit, OnChanges {
    public ngOnInit() {}
    public ngOnChanges(_: SimpleChanges) {}
}
@Component({ ... })
public TestComponent extends RequiredClass {}

@alshdavid
Copy link
Author

If it's hard for the compiler to statically analyse a custom decorator to determine what lifecycle methods are being patched, perhaps a basic solution like using comments which target the compiler will be a simple temporary solution.

eg

// @AoT [ 'ngOnInit', 'onDestroy' ]
export function RequiredInput<TValue>(defaultValue?: TValue) {
    ...
}

@trotyl
Copy link
Contributor

trotyl commented May 16, 2019

Duplicate of #16023

@jasonaden jasonaden added the area: core Issues related to the framework runtime label May 16, 2019
@ngbot ngbot bot added this to the needsTriage milestone May 16, 2019
@alxhub alxhub added fixed by Ivy freq1: low feature Issue that requests a new feature labels May 28, 2019
@ngbot ngbot bot modified the milestones: needsTriage, Backlog May 28, 2019
@alxhub
Copy link
Member

alxhub commented May 28, 2019

I have some good news!

In Ivy, lifecycle hooks are purely a runtime concern. They're read off the prototype of the component as soon as the first instance is created, which means that if a decorator adds hooks to the prototype then Ivy will notice them.

@stupidawesome
Copy link

stupidawesome commented May 29, 2019

@alxhub Should this be working in 8.0? I enabled Ivy and tried adding hooks with decorators using renderComponent() and platformBrowserDynamic().bootstrapModule() but it still doesn't work in AoT without adding an empty stub to the class definition.

Should this code theoretically work?

@Component()
export class MyComponent {}

MyComponent.prototype.ngOnInit = function () {
    console.log("init fired")
}

@trotyl
Copy link
Contributor

trotyl commented May 29, 2019

@alxhub

They're read off the prototype of the component as soon as the first instance is created

This is not true, lifecycle hooks are determined in defineComponent(), which happen when the constructor is created, not the instance.

lifecycle hooks are purely a runtime concern.

However, decorators* are also purely a runtime concern, as explained in #16023 (comment), decorators runs after static properties, can be reproduce easily in TypeScript playground.

When defineComponent() get called, all the decorators hasn't being executed yet, so no methods can be found in the prototype.

The current decorator proposal has changed to compile-time semantics, but what implemented in TypeScript is still the obsolete stage-0 proposal.

@christopher-kiss
Copy link

@trotyl,

So it looks like this is blocked until Typescript updates the decorator implementation? Which doesn't look like it's in a release plan yet: https://github.com/Microsoft/TypeScript/wiki/Roadmap#future

@trotyl
Copy link
Contributor

trotyl commented May 29, 2019

So it looks like this is blocked until Typescript updates the decorator implementation?

@ChristopherKiss I really don't know, the decisions are made by Angular team, I have no way to change their mind.

@mhevery
Copy link
Contributor

mhevery commented Feb 15, 2020

Here is how it should work in Ivy: https://ng-run.com/edit/TIbZM8JylZuhdZCM5KdO

Unfortunately this works only in JIT mode (but fails in AOT mode). The issue is that in AOT mode the @Component decorator is converted into defineComponent assignment which runs before the decorator has a chance to run. As a result the defineComponent collects the lifecycle hooks before the custom decorator has a chance to run.

mhevery added a commit to mhevery/angular that referenced this issue Feb 15, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Mar 10, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Mar 11, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
@klemenoslaj
Copy link
Contributor

@mhevery Will this be supported by AOT in the future?
If so, maybe we could take the risk and use target.ɵcmp until then.

mhevery added a commit to mhevery/angular that referenced this issue Jun 4, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jun 4, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jun 4, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jun 5, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jun 5, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jun 19, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jun 22, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jun 22, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jun 22, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jul 14, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`. The result is that it is not possible to do any sort of meta-programing such as mixins or adding lifecycle hooks using custom decorators since any such code executes after `ɵɵdefineComponent` has extracted the lifecycle hooks from the prototype. Additionally the behavior is inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle hooks is possible because the whole `ɵɵdefineComponent` is placed in getter which is executed lazily. This is because JIT mode must compile a template which can be specified as `templateURL` and those we are waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the `ɵɵdefineComponent` so that lifecycle hook access would be monomorphic. This decision was made before we had `T*` data structures. By not reading the lifecycle hooks we are moving the megamorhic read form `ɵɵdefineComponent` to instructions. However, the reads happen on `firstTemplatePass` only and are subsequently cached in the `T*` data structures. The result is that the overall performance should be same (or slightly better as the intermediate `ComponentDef` has been removed)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jul 14, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`.
The result is that it is not possible to do any sort of meta-programing
such as mixins or adding lifecycle hooks using custom decorators since
any such code executes after `ɵɵdefineComponent` has extracted the
lifecycle hooks from the prototype. Additionally the behavior is
inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle
hooks is possible because the whole `ɵɵdefineComponent` is placed in
getter which is executed lazily. This is because JIT mode must compile a
template which can be specified as `templateURL` and those we are
waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy
  lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the
  codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the
`ɵɵdefineComponent` so that lifecycle hook access would be monomorphic.
This decision was made before we had `T*` data structures. By not
reading the lifecycle hooks we are moving the megamorhic read form
`ɵɵdefineComponent` to instructions. However, the reads happen on
`firstTemplatePass` only and are subsequently cached in the `T*` data
structures. The result is that the overall performance should be same
(or slightly better as the intermediate `ComponentDef` has been
removed.)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer
      be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jul 14, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`.
The result is that it is not possible to do any sort of meta-programing
such as mixins or adding lifecycle hooks using custom decorators since
any such code executes after `ɵɵdefineComponent` has extracted the
lifecycle hooks from the prototype. Additionally the behavior is
inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle
hooks is possible because the whole `ɵɵdefineComponent` is placed in
getter which is executed lazily. This is because JIT mode must compile a
template which can be specified as `templateURL` and those we are
waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy
  lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the
  codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the
`ɵɵdefineComponent` so that lifecycle hook access would be monomorphic.
This decision was made before we had `T*` data structures. By not
reading the lifecycle hooks we are moving the megamorhic read form
`ɵɵdefineComponent` to instructions. However, the reads happen on
`firstTemplatePass` only and are subsequently cached in the `T*` data
structures. The result is that the overall performance should be same
(or slightly better as the intermediate `ComponentDef` has been
removed.)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer
      be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit to mhevery/angular that referenced this issue Jul 17, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`.
The result is that it is not possible to do any sort of meta-programing
such as mixins or adding lifecycle hooks using custom decorators since
any such code executes after `ɵɵdefineComponent` has extracted the
lifecycle hooks from the prototype. Additionally the behavior is
inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle
hooks is possible because the whole `ɵɵdefineComponent` is placed in
getter which is executed lazily. This is because JIT mode must compile a
template which can be specified as `templateURL` and those we are
waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy
  lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the
  codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the
`ɵɵdefineComponent` so that lifecycle hook access would be monomorphic.
This decision was made before we had `T*` data structures. By not
reading the lifecycle hooks we are moving the megamorhic read form
`ɵɵdefineComponent` to instructions. However, the reads happen on
`firstTemplatePass` only and are subsequently cached in the `T*` data
structures. The result is that the overall performance should be same
(or slightly better as the intermediate `ComponentDef` has been
removed.)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer
      be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
mhevery added a commit that referenced this issue Jul 17, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`.
The result is that it is not possible to do any sort of meta-programing
such as mixins or adding lifecycle hooks using custom decorators since
any such code executes after `ɵɵdefineComponent` has extracted the
lifecycle hooks from the prototype. Additionally the behavior is
inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle
hooks is possible because the whole `ɵɵdefineComponent` is placed in
getter which is executed lazily. This is because JIT mode must compile a
template which can be specified as `templateURL` and those we are
waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy
  lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the
  codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the
`ɵɵdefineComponent` so that lifecycle hook access would be monomorphic.
This decision was made before we had `T*` data structures. By not
reading the lifecycle hooks we are moving the megamorhic read form
`ɵɵdefineComponent` to instructions. However, the reads happen on
`firstTemplatePass` only and are subsequently cached in the `T*` data
structures. The result is that the overall performance should be same
(or slightly better as the intermediate `ComponentDef` has been
removed.)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer
      be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix #30497
mhevery added a commit to mhevery/angular that referenced this issue Jul 17, 2020
…strap

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`.
The result is that it is not possible to do any sort of meta-programing
such as mixins or adding lifecycle hooks using custom decorators since
any such code executes after `ɵɵdefineComponent` has extracted the
lifecycle hooks from the prototype. Additionally the behavior is
inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle
hooks is possible because the whole `ɵɵdefineComponent` is placed in
getter which is executed lazily. This is because JIT mode must compile a
template which can be specified as `templateURL` and those we are
waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy
  lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the
  codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the
`ɵɵdefineComponent` so that lifecycle hook access would be monomorphic.
This decision was made before we had `T*` data structures. By not
reading the lifecycle hooks we are moving the megamorhic read form
`ɵɵdefineComponent` to instructions. However, the reads happen on
`firstTemplatePass` only and are subsequently cached in the `T*` data
structures. The result is that the overall performance should be same
(or slightly better as the intermediate `ComponentDef` has been
removed.)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer
      be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497
AndrewKushnir pushed a commit that referenced this issue Jul 17, 2020
…strap (#38119)

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`.
The result is that it is not possible to do any sort of meta-programing
such as mixins or adding lifecycle hooks using custom decorators since
any such code executes after `ɵɵdefineComponent` has extracted the
lifecycle hooks from the prototype. Additionally the behavior is
inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle
hooks is possible because the whole `ɵɵdefineComponent` is placed in
getter which is executed lazily. This is because JIT mode must compile a
template which can be specified as `templateURL` and those we are
waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy
  lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the
  codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the
`ɵɵdefineComponent` so that lifecycle hook access would be monomorphic.
This decision was made before we had `T*` data structures. By not
reading the lifecycle hooks we are moving the megamorhic read form
`ɵɵdefineComponent` to instructions. However, the reads happen on
`firstTemplatePass` only and are subsequently cached in the `T*` data
structures. The result is that the overall performance should be same
(or slightly better as the intermediate `ComponentDef` has been
removed.)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer
      be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix #30497

PR Close #38119
@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 Aug 15, 2020
profanis pushed a commit to profanis/angular that referenced this issue Sep 5, 2020
…strap (angular#35464)

Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`.
The result is that it is not possible to do any sort of meta-programing
such as mixins or adding lifecycle hooks using custom decorators since
any such code executes after `ɵɵdefineComponent` has extracted the
lifecycle hooks from the prototype. Additionally the behavior is
inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle
hooks is possible because the whole `ɵɵdefineComponent` is placed in
getter which is executed lazily. This is because JIT mode must compile a
template which can be specified as `templateURL` and those we are
waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy
  lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the
  codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the
`ɵɵdefineComponent` so that lifecycle hook access would be monomorphic.
This decision was made before we had `T*` data structures. By not
reading the lifecycle hooks we are moving the megamorhic read form
`ɵɵdefineComponent` to instructions. However, the reads happen on
`firstTemplatePass` only and are subsequently cached in the `T*` data
structures. The result is that the overall performance should be same
(or slightly better as the intermediate `ComponentDef` has been
removed.)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer
      be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix angular#30497

PR Close angular#35464
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: core Issues related to the framework runtime feature Issue that requests a new feature freq1: low
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants