如何在单页面高效使用多个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
相关产品推荐
相关产品推荐

