'Performance problems when accessing the nativeElement.offsetWidth or scrollWidth properties

Suppose I have a css class to truncate text:

.text-truncate {
  min-width: 0;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}

And I want to add a tooltip if it is truncated actually. For this purpose I created a directive:

@Directive({
  selector: '[textTruncate]'
})
export class TextTruncateDirective implements AfterViewInit {
  constructor(
    private el: ElementRef,
    private renderer: Renderer2
  ) {}

  @HostBinding('class')
  className = 'text-truncate';

  ngAfterViewInit(): void {
    const text = this.el.nativeElement.textContent;
    if (text && this.el.nativeElement.offsetWidth < this.el.nativeElement.scrollWidth) {
      this.renderer.setAttribute(this.el.nativeElement, 'title', text);
    }
  }
}

It works fine only if I don't have a lot of elements where this directive is applied on. If I have, for example, a table which has 10 columns and couple of hundreds of rows and I apply this directive to each cell, the fact I access offsetWidth and scrollWidth properties of native element slows down my app hundred times. It works, but it's freaking slow.

If I replace this code:

if (text && this.el.nativeElement.offsetWidth < this.el.nativeElement.scrollWidth) {
  this.renderer.setAttribute(this.el.nativeElement, 'title', text);
}

for just this.renderer.setAttribute(...) without any conditions, it starts working pretty fast. I just wondering what is the reason? and is there a way to optimize it somehow?

PS. I don't use a table actually, just a lot of divs. But I don't think it's matter.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source