Components: [Tooltip] Change detection runs after showing tooltip

Created on 7 Mar 2018  路  17Comments  路  Source: angular/components

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?

P3 materiatooltip

Most helpful comment

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

All 17 comments

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.

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

Nope. Both trigger change detection.

@c69 thx for the extra feedback :)

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.

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

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.

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.

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 !

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

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

@andrewseguin any recent news about this?

Any news? I have issues with this too

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?

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?

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

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; }
top: -35px;
bottom: auto;
transform: translateX(-50%) scale(0);
transition: transform 0.3s ease-in-out;
transform-origin: bottom center;
}
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);
}

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);
}
Was this page helpful?
0 / 5 - 0 ratings