首页 > 解决方案 > Contenteditable 和 Block-selected Backspace 性能问题

问题描述

我正在使用 Angular 9.1.7 和 contenteditable div 在我的应用程序中创建基本的文本编辑功能。我已经为这个 div 绑定了许多事件处理程序,但是我偶然发现的事情让我感到困惑的是,当我在 div 中选择一段文本并键入退格键时会发生什么。

TL;DR更新在 stackblitz 上创建了一个最小的可重现示例。只需尝试删除 Lorem Ipsum 文本的其中一段,看看我的意思。

整个浏览器进程似乎暂停了一会儿(> 10 秒)。我无法单击其他任何内容、滚动等。UI 完全不受我的控制,直到突然它不是并且呈现退格的效果(我选择的文本块被删除)。我在一些事件处理程序中放入了一堆控制台日志,并得出了以下事件序列:

keydown
keydown
beforeinput start
beforeinput end
input start
input end
// ... out to lunch for a few seconds ...
keyup start
keyup end

...我还计时了所有这些事件的开始 -> 结束时间,它们的执行时间可以忽略不计。所以我在我的代码中找不到占用处理器和阻塞浏览器 UI 的任何地方。我运行了 Chrome 开发工具分析器并看到如下内容:

在此处输入图像描述

...如果我滚动到紫色东西开始发生的地方,我会看到: 在此处输入图像描述

至于 Angular 如何与 contenteditable div 交互,它是我的组件的 ViewChild,在标记中看起来像这样:

      <div #editableText contenteditable="true"
        (keydown)="onKeyDown($event)"
        (keyup)="onKeyUp($event)"
        (keypress)="onKeyPress($event)"
        (input)="onInput($event)"
        (beforeinput)="onBeforeInput($event)"><br></div>

...我拦截键控事件以确定和构造元素的 innerHTML 以满足我的需要。这在组件中表现为:

@ViewChild('editableText', { static: false }) editableElem: ElementRef;
...
updateEditableText(html) {
  this.editableElem.nativeElement.innerHTML = html;
}

据我所知,我已经检查过 updateEditableText 函数没有被重复调用或以任何方式涉及性能问题。

我不确定如何更深入地了解这里发生的事情,我不确定这是否与 Angular 更改检测有关,或者更直接归因于 contenteditable。在 contenteditibale 中,作为我要删除的选择的基础的标记相当于几个span元素,这些元素具有与之关联的数据属性,但我不明白为什么 contenteditable 标记的复杂性对我来说很重要,只需选择一个内容块并按退格键.

我正在寻求有关如何深入了解这里发生的事情的建议(例如,Chrome 开发工具分析器的不同使用、Angular 诊断技术等)并查明这个性能瓶颈的根源,以便我可以要么修复它,要么解决这个问题。

标签: angularperformancecontenteditable

解决方案


推荐阅读