-
Notifications
You must be signed in to change notification settings - Fork 6.8k
feat(material/button): make button ripples lazy #26568
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
Conversation
127faf5 to
89ee76f
Compare
6f12cda to
6b2cbec
Compare
d6b4ec3 to
71841bc
Compare
9b96733 to
3d72aca
Compare
|
Here is the design doc which describes this feature as well as the rationale for why it was written this way: |
| * Traverses the element and its parents (heading toward the document root) | ||
| * until it finds a mat-button that has not been initialized. | ||
| */ | ||
| private _closest(element: Element): Element | null { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use the native Element.closest API here instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mleibman could probably speak to this best but from what I remember in our last discussions, this is actually a performance improvement. I have added a link to their example at the bottom of our design doc
https://docs.google.com/document/d/13paaXem1sXg6462-bb05M8GHguvQcsXGC8FxDeK6w_Q/edit?usp=sharing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's not exactly the same, because it's setting a symbol on the DOM node whereas here we have an attribute.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm very skeptical that a userspace closest is faster than the browser native closest. I would need to see some compelling evidence, and then I would go complain to Chrome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds plausible - I could have just misremembered. I switched to using the native Element.closest and I can revisit this if it really is a performance bottleneck
| * Traverses the element and its parents (heading toward the document root) | ||
| * until it finds a mat-button that has not been initialized. | ||
| */ | ||
| private _closest(element: Element): Element | null { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm very skeptical that a userspace closest is faster than the browser native closest. I would need to see some compelling evidence, and then I would go complain to Chrome.
src/material/button/button-ripple.ts
Outdated
| constructor( | ||
| _elementRef: ElementRef<HTMLElement>, | ||
| readonly ngZone: NgZone, | ||
| readonly platform: Platform, | ||
| @Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalOptions?: RippleGlobalOptions, | ||
| @Optional() @Inject(ANIMATION_MODULE_TYPE) _animationMode?: string, | ||
| @Optional() @Inject(DOCUMENT) document?: Document, | ||
| ) { | ||
| super(_elementRef, ngZone, platform, globalOptions, _animationMode, document); | ||
| this._buttonEl = _elementRef.nativeElement; | ||
| this._buttonEl.classList.remove('mat-ripple'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer the inject function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was able to do this for document, but not any of the other symbols because they are referenced in the call to super and references to this are not allowed before super is called
54ba026 to
fc7f0a8
Compare
|
@wagnermaciel it doesn't actually have to be a directive instance, it just has to have the same API shape, no? rough pseudo-code for the idea type PublicInterface<T> = {[K in keyof T]: T[K]};
class DeferredRipple implements PublicInterface<MatRipple> {
// ripple stuff
}
class MatButton {
get ripple(): MatRipple {
if (!this._rippleInternal) this._rippleInternal = this.createRipple();
return this._rippleInternal;
}
private _rippleInternal = null;
}(it's possible I'm missing some detail, admittedly) |
|
@jelbourn Previously, when I considered this approach I was against it because I didn't want to be creating & having to maintain a MatRipple-like object. This time around, I just tried creating a |
b253a9a to
369e74e
Compare
jelbourn
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good- the only main thing left is adding additional tests for MatButtonLazyLoader
jelbourn
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
22df8c7 to
24757b4
Compare
24757b4 to
f4a22d4
Compare
|
Hi @wagnermaciel @jelbourn, |
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
No description provided.