components icon indicating copy to clipboard operation
components copied to clipboard

[Tooltip] Change detection runs after showing tooltip

Open victornoel opened this issue 7 years ago • 33 comments
trafficstars

Bug, feature request, or proposal:

Bug

What is the expected behavior?

Hovering an element with a matTooltip should not trigger change detection on this element if it is an OnPush element and its @Input()s does not change.

What is the current behavior?

Hovering an element with a matTooltip triggers change detection on this element.

This only happens if matTooltip is defined using [matTooltip]="..." and not when it is defined using matTooltip="..."

What are the steps to reproduce?

See https://stackblitz.com/edit/angular-material2-issue-ocg9sj

  • pass the mouse on the red div
  • you get logs everytime the function needed to draw the component are called
  • you don't get any log from ngOnChanges
  • I would expect that since the @Input() didn't change, the component shouldn't be redraw!

What is the use-case or motivation for changing an existing behavior?

Prevent useless redraws

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

cf stackblitz

Is there anything else we should know?

victornoel avatar Mar 07 '18 10:03 victornoel

Run into this today - not only the hover causes the host element to re-run change detection, but in my case whole outer *ngFor is updated...

Please consider increasing priority to P2. Because this essentially means you cannot use matTooltip in a data grid.

P.s.: removed matTooltip from our code for now, in favor of native title.

c69 avatar Mar 29 '18 20:03 c69

This only happens if matTooltip is defined using [matTooltip]="..." and not when it is defined using matTooltip="..."

Nope. Both trigger change detection.

c69 avatar Mar 29 '18 20:03 c69

@c69 thx for the extra feedback :)

victornoel avatar Mar 29 '18 21:03 victornoel

This makes matTooltip uninstantaneous to use when change detection happens to take a long time. We've decided to use the title attribute for now, but will keep monitoring this bug.

chihuahua avatar Sep 14 '18 23:09 chihuahua

I am also not able to use matTooltip when ChangeDetectionStrategy is OnPush. @chihuahua: Were you able to find any fix of the same yet?

pranavjain avatar Jan 18 '19 08:01 pranavjain

I just ran into the same problem. I guess we have to live with the title attribute for now. This doesn't seem to be very high on the priority list.

gamsterx avatar Apr 26 '19 16:04 gamsterx

I have run into this with a component injected into a portal inside a table cell (complicated enough?) When I hover over the paginator buttons, showing the tooltip, the injected component is destroyed and re-injected.

tsheils avatar May 21 '19 19:05 tsheils

Hi, I'm having this issue too with matTooltip directive. The component's changeDetection is set to ChangeDetectionStrategy.OnPush. On hover / leave, the component's change detection is triggered multiple times.

mattooltip_cd

Thx !

Need-To-Learn avatar May 31 '19 11:05 Need-To-Learn

I agree, this is a problem for bigger applications with slow change detection cycle. It brings us a lot of problems :(

klinki avatar Jun 11 '19 08:06 klinki

Hi, is this being worked on right now? Can I try to fix it and add a PR?

yard2010 avatar Jan 27 '20 07:01 yard2010

@andrewseguin any recent news about this?

pycraft114 avatar Feb 27 '20 04:02 pycraft114

Any news? I have issues with this too

vlaco avatar Apr 06 '20 20:04 vlaco

It has been 2 years since this issue has been opened and still not resolved... Is there any plan for change detection to removed for the mat tooltip's hover state? This is such a nasty side effect and causing such performance issues throughout our entire applications. Has anyone been able to come up with some sort of alternative solution? Or is that solution to remove mat tooltip module?

Affuta avatar May 12 '20 07:05 Affuta

I found out if remove the second param from ComponentPortal https://github.com/angular/components/blob/5284a57b2f24319359d0528522feeca9c1393751/src/material/tooltip/tooltip.ts#L336

the problem will disappear.

do we really need to set it?

yakimko avatar May 12 '20 14:05 yakimko

Hello all i have the same and use matTooltip="..." as @c69 not solve. I add than use all in latest version

Toso82 avatar Jun 01 '20 07:06 Toso82

HTML 'title' attribute works 100% across all browsers (even IE11 if needed).

We're developing a large scale enterprise application which uses large data grids. matTooltip brought our application to its knees as it became slow and unusable.

You can also create a pure css solution using [aria-label] but be aware that the materiel design calendar component and possibly other material design components utilize the [aria-label] attribute. We ended up not using it but, here's our code of the pure css solution.

[aria-label] { position: relative; } [aria-label]:before { top: -35px; bottom: auto; transform: translateX(-50%) scale(0); transform-origin: bottom center; } [aria-label]:hover:before { top: -35px; bottom: auto; transform: translateX(-50%) scale(0); transition: transform 0.3s ease-in-out; transform-origin: bottom center; } [aria-label]:hover:after { content: attr(aria-label); position: absolute; bottom: -35px; left: 50%; padding: 2px 8px;
transform-origin: top; background: #616161; color: white; border-radius: 2px; font-size: 14px; font-family: RobotoDraft, Roboto, Arial; font-weight: 500; z-index: 9999; min-width:200px; min-height:40px; transform: translateX(-50%) scale(1); }

3nd avatar Jun 10 '20 15:06 3nd

Here is 3nd's solution (the person who posted directly above) but formatted with syntax highlighting so its a little easier to read:

[aria-label] {
  position: relative;
}
[aria-label]:before {
  top: -35px;
  bottom: auto;
  transform: translateX(-50%) scale(0);
  transform-origin: bottom center;
}
[aria-label]:hover:before {
  top: -35px;
  bottom: auto;
  transform: translateX(-50%) scale(0);
  transition: transform 0.3s ease-in-out;
  transform-origin: bottom center;
}
[aria-label]:hover:after {
  content: attr(aria-label);
  position: absolute;
  bottom: -35px;
  left: 50%;
  padding: 2px 8px;
  transform-origin: top;
  background: #616161;
  color: white;
  border-radius: 2px;
  font-size: 14px;
  font-family: RobotoDraft, Roboto, Arial;
  font-weight: 500;
  z-index: 9999;
  min-width: 200px;
  min-height: 40px;
  transform: translateX(-50%) scale(1);
}

bradtaniguchi avatar Jun 10 '20 18:06 bradtaniguchi

Issue is still occurring (@angular/material 11.2.2) :-( any updates?

jmeinlschmidt avatar Mar 28 '21 12:03 jmeinlschmidt

i just wasted 3 hours on this. didn't understand why function running so often. also, changed from matTooltip to title.

https://stackblitz.com/edit/angular-ctmbfe?file=src/app/table-basic-example.html

ronben2311 avatar Jun 23 '21 08:06 ronben2311

same happens when hovering over mat-sort-header

ronben2311 avatar Jun 24 '21 05:06 ronben2311

Any solution? I have the same issue.

PabloLema avatar Jul 06 '21 13:07 PabloLema

Is Yakimko's suggestion a fix? https://github.com/angular/components/issues/10306#issuecomment-627378769

or perhaps it is the beginning of a fix, to make the _portal persist?

Frazer avatar Aug 02 '21 21:08 Frazer

Any solution for this as I am facing the same performance issue

carboncs16 avatar Nov 09 '21 05:11 carboncs16

The only feasible "solution" we found so far is wrapping the tooltip into a dumb component which in returns implements the tooltip. This limits the affected components re-running due to a change-detection.. Other than that, use an ugly title attribute.

PhilippMeissner avatar Nov 09 '21 07:11 PhilippMeissner

We also had to create our own tooltip component, as found no way to make this work.

Frazer avatar Nov 11 '21 00:11 Frazer

4 years later and still no fix for this??

powhound4 avatar Apr 06 '22 21:04 powhound4

Came across this today while dealing with the same issue

nhleto avatar May 23 '22 19:05 nhleto

This is quite a painful bug. With a large list contained within an OnPush CdkVirtualFor (utilising trackBy) to only render the viewable items, on every tooltip show() call, the pure pipes to retrieve the tooltip content for each visible item is retriggered.

mcost45 avatar Jun 20 '22 11:06 mcost45

This is quite a painful bug. With a large list contained within an OnPush CdkVirtualFor (utilising trackBy) to only render the viewable items, on every tooltip show() call, the pure pipes to retrieve the tooltip content for every single item in the list are retriggered.

I guess your only feasible option will be to wrap the content containing the pipe in another component to minimize the affected components that will get triggered for re-rendering. Or we wait for another 4 years until this issue eventually becomes interesting enough for the angular team.

PhilippMeissner avatar Jun 20 '22 11:06 PhilippMeissner

primeng tooltip is the best alternative 🔥

sujeetjaiswara avatar Jun 20 '22 18:06 sujeetjaiswara