Skip to content

Commit dc8e8eb

Browse files
committed
refactor(list): use light-weight tokens for injecting parent lists
Angular Material list items currently optionally inject a parent `MatNavList` or `MatList`. This has the downside of retaining these tokens at runtime because they are used for dependency injection as values. We can improve this by using so-called light-weight tokens. These allow us to continue injecting parent list or nav-lists, but without the risk of retaining the `MatList` and `MatNavList` classes with their factories. This was already the case before Angular v9 with View Engine, but the issue significance increases with Ivy where factories are now directly attached to the classes (such as `MatList` or `MatNavList`). Using light-weight tokens avoids this issue and gives us an additional size improvement. Notably this won't be an improvement when an application uses both the nav-list and standard `MatList`. Related to https://github.com/angular/angular-cli/issues/16866. More context on light-weight tokens in: https://hackmd.io/@mhevery/SyqDjUlrU#.
1 parent c13a5db commit dc8e8eb

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

goldens/size-test.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"material/list": 224424
2+
"material/list": 215881
33
}

src/material/list/list.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import {
2222
OnDestroy,
2323
ChangeDetectorRef,
2424
Input,
25+
InjectionToken,
26+
Inject,
2527
} from '@angular/core';
2628
import {
2729
CanDisable,
@@ -48,6 +50,20 @@ class MatListItemBase {}
4850
const _MatListItemMixinBase: CanDisableRippleCtor & typeof MatListItemBase =
4951
mixinDisableRipple(MatListItemBase);
5052

53+
/**
54+
* Injection token that can be used to inject instances of `MatList`. It serves as
55+
* alternative token to the actual `MatList` class which could cause unnecessary
56+
* retention of the class and its component metadata.
57+
*/
58+
export const MAT_LIST = new InjectionToken<MatList>('MatList');
59+
60+
/**
61+
* Injection token that can be used to inject instances of `MatNavList`. It serves as
62+
* alternative token to the actual `MatNavList` class which could cause unnecessary
63+
* retention of the class and its component metadata.
64+
*/
65+
export const MAT_NAV_LIST = new InjectionToken<MatNavList>('MatNavList');
66+
5167
@Component({
5268
selector: 'mat-nav-list',
5369
exportAs: 'matNavList',
@@ -60,6 +76,7 @@ const _MatListItemMixinBase: CanDisableRippleCtor & typeof MatListItemBase =
6076
inputs: ['disableRipple', 'disabled'],
6177
encapsulation: ViewEncapsulation.None,
6278
changeDetection: ChangeDetectionStrategy.OnPush,
79+
providers: [{provide: MAT_NAV_LIST, useExisting: MatNavList}],
6380
})
6481
export class MatNavList extends _MatListMixinBase implements CanDisable, CanDisableRipple,
6582
OnChanges, OnDestroy {
@@ -89,6 +106,7 @@ export class MatNavList extends _MatListMixinBase implements CanDisable, CanDisa
89106
inputs: ['disableRipple', 'disabled'],
90107
encapsulation: ViewEncapsulation.None,
91108
changeDetection: ChangeDetectionStrategy.OnPush,
109+
providers: [{provide: MAT_LIST, useExisting: MatList}],
92110
})
93111
export class MatList extends _MatListMixinBase implements CanDisable, CanDisableRipple, OnChanges,
94112
OnDestroy {
@@ -187,8 +205,8 @@ export class MatListItem extends _MatListItemMixinBase implements AfterContentIn
187205

188206
constructor(private _element: ElementRef<HTMLElement>,
189207
_changeDetectorRef: ChangeDetectorRef,
190-
@Optional() navList?: MatNavList,
191-
@Optional() list?: MatList) {
208+
@Optional() @Inject(MAT_NAV_LIST) navList?: MatNavList,
209+
@Optional() @Inject(MAT_LIST) list?: MatList) {
192210
super();
193211
this._isInteractiveList = !!(navList || (list && list._getListType() === 'action-list'));
194212
this._list = navList || list;

tools/public_api_guard/material/list.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
export declare const MAT_LIST: InjectionToken<MatList>;
2+
3+
export declare const MAT_NAV_LIST: InjectionToken<MatNavList>;
4+
15
export declare const MAT_SELECTION_LIST_VALUE_ACCESSOR: any;
26

37
export declare class MatList extends _MatListMixinBase implements CanDisable, CanDisableRipple, OnChanges, OnDestroy {

0 commit comments

Comments
 (0)