You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单页面高效使用多个CKEditor5实例避免页面加载卡顿

单CKEditor5实例复用优化方案

核心逻辑为全局最多仅维护1个激活的CKEditor5实例,页面初始只渲染富文本预览节点,点击对应区域后才挂载编辑器,失焦或切换编辑项时销毁旧实例,首屏无额外编辑器加载开销,不会卡顿也不影响手风琴组件动画效果。

1. 修改模板代码

移除默认全局渲染的<ckeditor>组件,仅在当前点击的编辑项位置动态加载编辑器:

<mat-accordion>
  <mat-expansion-panel *ngFor="let question of questionList; let i = index">
    <!-- 原有其他视图代码 -->
    <!-- 非编辑状态展示富文本预览 -->
    <div 
      class="editor-preview" 
      *ngIf="activeEditorIndex !== i"
      (click)="initEditor(i)"
      [innerHTML]="getSafeHtml(question.prompt)"
      tabindex="0"
      (keydown.enter)="initEditor(i)"
    ></div>
    <!-- 仅当前激活项渲染编辑器 -->
    <ckeditor 
      *ngIf="activeEditorIndex === i"
      [editor]="editor" 
      [(ngModel)]="questionList[i].prompt"
      (blur)="destroyEditor()"
      [config]="editorConfig"
    ></ckeditor>
  </mat-expansion-panel>
</mat-accordion>

2. 调整组件逻辑

新增激活索引变量控制编辑器的显隐,保证同一时间仅存在1个编辑器实例:

import * as InlineEditor from '@ckeditor/ckeditor5-build-inline';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
// 其他原有导入

@Component({
  selector: 'app-questions',
  templateUrl: './questions.component.html',
  styleUrls: ['./questions.component.scss']
})
export class QuestionsComponent {
  @Input() questionList: QuestionModel[];
  editor = InlineEditor;
  // 初始值-1代表无激活编辑器
  activeEditorIndex = -1;
  // 自定义编辑器配置,按需调整
  editorConfig = {
    toolbar: ['bold', 'italic', 'link', 'bulletedList', 'numberedList']
  };

  constructor(private sanitizer: DomSanitizer) {}

  // 初始化当前项编辑器
  initEditor(index: number): void {
    // 销毁已有激活编辑器
    if (this.activeEditorIndex !== -1) {
      this.destroyEditor();
    }
    this.activeEditorIndex = index;
    // 视图更新后自动聚焦编辑器
    setTimeout(() => {
      const editableDom = document.querySelector('.ck-editor__editable') as HTMLElement;
      editableDom?.focus();
    }, 0);
  }

  // 销毁当前激活编辑器
  destroyEditor(): void {
    this.activeEditorIndex = -1;
  }

  // 富文本安全过滤,避免XSS警告
  getSafeHtml(htmlStr: string): SafeHtml {
    return this.sanitizer.bypassSecurityTrustHtml(htmlStr);
  }

  // 其他原有业务代码
}

3. 补充样式抹平预览与编辑状态差异

避免切换时出现布局跳动,保证视觉一致性:

.editor-preview {
  min-height: 60px; // 与编辑器最小高度对齐
  padding: 8px 12px;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  cursor: text;
  transition: border-color 0.2s;

  &:hover {
    border-color: #2196f3;
  }

  // 继承CKEditor内容样式,保证预览效果与编辑状态一致
  p, ul, ol {
    margin: 0 0 10px 0;
    &:last-child {
      margin-bottom: 0;
    }
  }
}

优化点

  • 双向绑定会自动同步编辑内容到questionList,兼容原有表单验证逻辑
  • 可在手风琴面板折叠回调中调用destroyEditor主动销毁编辑器,进一步节省资源
  • 若需要支持Tab键切换编辑项,已在模板中预留tabindex和回车触发逻辑,可直接使用

内容的提问来源于stack exchange,提问作者M. Akar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 16:15:01