Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit 6c7fc94

Browse files
authored
Merge pull request #335 from ckeditor/i/4504
Fix: Improved markup operation performance of the editor with the image plugin enabled. See ckeditor/ckeditor5#4504.
2 parents 11c9f39 + 07b1b28 commit 6c7fc94

File tree

1 file changed

+7
-62
lines changed

1 file changed

+7
-62
lines changed

src/image/imageloadobserver.js

Lines changed: 7 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -20,65 +20,18 @@ import Observer from '@ckeditor/ckeditor5-engine/src/view/observer/observer';
2020
* @extends module:engine/view/observer/observer~Observer
2121
*/
2222
export default class ImageLoadObserver extends Observer {
23-
constructor( view ) {
24-
super( view );
25-
26-
/**
27-
* List of img DOM elements that are observed by this observer.
28-
*
29-
* @private
30-
* @type {Set.<HTMLElement>}
31-
*/
32-
this._observedElements = new Set();
33-
}
34-
3523
/**
3624
* @inheritDoc
3725
*/
38-
observe( domRoot, name ) {
39-
const viewRoot = this.document.getRoot( name );
40-
41-
// When there is a change in one of the view element
42-
// we need to check if there are any new `<img/>` elements to observe.
43-
viewRoot.on( 'change:children', ( evt, node ) => {
44-
// Wait for the render to be sure that `<img/>` elements are rendered in the DOM root.
45-
this.view.once( 'render', () => this._updateObservedElements( domRoot, node ) );
46-
} );
47-
}
48-
49-
/**
50-
* Updates the list of observed `<img/>` elements.
51-
*
52-
* @private
53-
* @param {HTMLElement} domRoot DOM root element.
54-
* @param {module:engine/view/element~Element} viewNode View element where children have changed.
55-
*/
56-
_updateObservedElements( domRoot, viewNode ) {
57-
if ( !viewNode.is( 'element' ) || viewNode.is( 'attributeElement' ) ) {
58-
return;
59-
}
60-
61-
const domNode = this.view.domConverter.mapViewToDom( viewNode );
26+
observe( domRoot ) {
27+
this.listenTo( domRoot, 'load', ( event, domEvent ) => {
28+
const domElement = domEvent.target;
6229

63-
// If there is no `domNode` it means that it was removed from the DOM in the meanwhile.
64-
if ( !domNode ) {
65-
return;
66-
}
67-
68-
for ( const domElement of domNode.querySelectorAll( 'img' ) ) {
69-
if ( !this._observedElements.has( domElement ) ) {
70-
this.listenTo( domElement, 'load', ( evt, domEvt ) => this._fireEvents( domEvt ) );
71-
this._observedElements.add( domElement );
72-
}
73-
}
74-
75-
// Clean up the list of observed elements from elements that has been removed from the root.
76-
for ( const domElement of this._observedElements ) {
77-
if ( !domRoot.contains( domElement ) ) {
78-
this.stopListening( domElement );
79-
this._observedElements.delete( domElement );
30+
if ( domElement.tagName == 'IMG' ) {
31+
this._fireEvents( domEvent );
8032
}
81-
}
33+
// Use capture phase for better performance (#4504).
34+
}, { useCapture: true } );
8235
}
8336

8437
/**
@@ -95,14 +48,6 @@ export default class ImageLoadObserver extends Observer {
9548
this.document.fire( 'imageLoaded', domEvent );
9649
}
9750
}
98-
99-
/**
100-
* @inheritDoc
101-
*/
102-
destroy() {
103-
this._observedElements.clear();
104-
super.destroy();
105-
}
10651
}
10752

10853
/**

0 commit comments

Comments
 (0)