【问题标题】:Performance problems when accessing the nativeElement.offsetWidth or scrollWidth properties访问 nativeElement.offsetWidth 或 scrollWidth 属性时的性能问题
【发布时间】:2022-06-28 02:28:34
【问题描述】:

假设我有一个 css 类来截断文本:

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

如果它实际上被截断,我想添加一个工具提示。为此,我创建了一个指令:

@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);
    }
  }
}

仅当我没有很多应用此指令的元素时,它才能正常工作。 例如,如果我有一个包含 10 列和数百行的表,并且我将此指令应用于每个单元格,那么我访问本机元素的 offsetWidthscrollWidth 属性的事实会使我的应用程序减慢数百倍。它有效,但速度非常慢。

如果我替换此代码:

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

this.renderer.setAttribute(...) 没有任何条件,它开始工作非常快。 我只是想知道是什么原因?有没有办法以某种方式优化它?

PS。实际上,我不使用table,只是使用了很多divs。不过我觉得没关系。

【问题讨论】:

  • 你的@HostBinding 是干什么用的?
  • @MathewBerg 明显应用 css 类。
  • 直到!不知道你可以那样做。谢谢!

标签: angular


【解决方案1】:

原因是调用offsetWidthscrollWidth 会导致回流。另见What forces layout/reflow

在您的情况下,您应该尽量减少或替换这些前面提到的调用。 另外一些可能有用的资源:

【讨论】:

    【解决方案2】:

    我在 AngularJS 1.8 中有一个类似的指令,并且在读取 offsetWidth 时遇到了同样的回流计算问题。

    我通过在“mouseenter”上决定标题而不是预先计算来缓解早期重排。

    【讨论】:

      猜你喜欢
      • 2012-09-20
      • 1970-01-01
      • 2011-02-02
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多