ckeditor5-vue icon indicating copy to clipboard operation
ckeditor5-vue copied to clipboard

Building from Source with multiple editors on a page is causing lag on initialization

Open benjaminprojas opened this issue 5 years ago • 17 comments

Possibly related: https://github.com/ckeditor/ckeditor5-vue/issues/82

When only adding one editor to a page, it loads pretty quick (not as quick as I'd like, but ok).

However, when I have multiple on a page (5 in my tests), at the time the components are being initialized the entire browser freezes for about 3 seconds when mounting the components.

After the page loads each editor works great without any issues. When I navigate away and return (using vue-router so no reloading of assets) it happens again. It seems like its something on the mounted or created lifecycle event that is causing the issue.

I've got everything set up in webpack correctly and there are no console errors.

Here is my editor component:

<template>
	<ckeditor
		:editor="editor"
		:config="config"
		:value="value"
		@input="$emit('input', $event)"
	/>
</template>

<script>
import CKEditor from '@ckeditor/ckeditor5-vue'
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials'
import Heading from '@ckeditor/ckeditor5-heading/src/heading'
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'
import Underline from '@ckeditor/ckeditor5-basic-styles/src/underline'
import Strikethrough from '@ckeditor/ckeditor5-basic-styles/src/strikethrough'
import Font from '@ckeditor/ckeditor5-font/src/font'
import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight'
import InlineHighlight from './plugins/InlineHighlight'
import Alignment from '@ckeditor/ckeditor5-alignment/src/alignment'
import Code from '@ckeditor/ckeditor5-basic-styles/src/code'
import List from '@ckeditor/ckeditor5-list/src/list'
import TodoList from '@ckeditor/ckeditor5-list/src/todolist'
import HorizontalLine from '@ckeditor/ckeditor5-horizontal-line/src/horizontalline'
import Indent from '@ckeditor/ckeditor5-indent/src/indent'
import IndentBlock from '@ckeditor/ckeditor5-indent/src/indentblock'
import Link from '@ckeditor/ckeditor5-link/src/link'
import Table from '@ckeditor/ckeditor5-table/src/table'
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar'
import Image from '@ckeditor/ckeditor5-image/src/image'
import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar'
import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption'
import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle'
import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize'
export default {
	components : {
		// Use the <ckeditor> component in this view.
		ckeditor : CKEditor.component
	},
	props : {
		value : String
	},
	data () {
		return {
			editor : ClassicEditor,
			config : {
				plugins : [
					Essentials,
					Heading,
					Paragraph,
					Bold,
					Italic,
					Underline,
					Strikethrough,
					Font,
					Highlight,
					InlineHighlight,
					Alignment,
					Code,
					TodoList,
					HorizontalLine,
					Indent,
					IndentBlock,
					Link,
					Table,
					TableToolbar,
					List,
					Image,
					ImageToolbar,
					ImageCaption,
					ImageStyle,
					ImageResize ], // Code, Subscript, Superscript ],
				alignment : {
					options : [ 'left', 'center', 'right' ]
				},
				fontSize : {
					options : [ 10, 12, 14, 'default', 18, 20, 24, 30, 32 ]
				},
				heading : {
					options : [
						{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
						{ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
						{ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
						{ model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },
						{ model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' }
					]
				},
				highlight : {
					options : [
						{
							model : 'yellowMarker',
							class : 'marker-yellow',
							title : 'Yellow marker',
							color : '#fdfd77',
							type  : 'marker'
						},
						{
							model : 'greenMarker',
							class : 'marker-green',
							title : 'Green marker',
							color : '#63f963',
							type  : 'marker'
						}
					]
				},
				table : {
					contentToolbar : [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
				},
				toolbar : {
					items : [
						'heading', '|',
						'bold', 'italic', 'underline', 'strikethrough', 'alignment', '|',
						'fontSize', 'fontColor', 'fontBackgroundColor', '|',
						'bulletedList', 'numberedList', 'todoList', 'indent', 'outdent', '|',
						'link', 'horizontalLine', 'insertTable', 'code', '|',
						'undo', 'redo', '|',
						/* 'imageInsert', */ 'imageTextAlternative', 'imageStyle:full', 'imageStyle:side' ]
				}
			}
		}
	}
}
</script>

<style lang="scss">
:root {
	/* Overrides the border radius setting in the theme. */
	--ck-border-radius: 0.25rem;
	--ck-color-base-border: #dee2e6;
	--ck-color-focus-border: #5e72e4;
	--ck-color-toolbar-background: #fff;
	--ck-color-button-default-hover-background: #e9ecef;
}
.ck-editor__editable_inline {
	min-height: 400px;
}
</style>

benjaminprojas avatar Jan 23 '20 12:01 benjaminprojas

One other note...

As I eliminate plugins, the page begins to load faster and faster. If I remove them all, it loads instantaneously.

benjaminprojas avatar Jan 23 '20 12:01 benjaminprojas

Hi! Thanks for this report. I checked it and indeed there is a tiny difference of speed in those cases. I also built a standalone editor from source ( with multiple instances ) and Vue seems to be slower ( ~3 seconds ) in this comparison.

cc @oleq Can you take a look at this?

FilipTokarski avatar Feb 03 '20 13:02 FilipTokarski

I'm afraid this is nothing new (or related to Vue). I ran your code and checked the performance stats and this is what it looks like when a single editor is created on a button click:

image

The initialization of the toolbar takes nearly .5s. We are aware of the issue and we track it here https://github.com/ckeditor/ckeditor5/issues/6178.

oleq avatar Feb 03 '20 14:02 oleq

Is it related to the UI itself? You linked to ckeditor/ckeditor5#6178, but I only saw performance issue reports (related to bootstrap time) from the Vue integration. Isn't there something related to Vue which deoptimizes the editor? Could you make some quick timeline comparison for identical Vue+CKE and standalone CKE setups?

Reinmar avatar Feb 03 '20 14:02 Reinmar

You were right @Reinmar.

I created the same builds with Vue.js stack (vue-cli) and without it (same plugins, same config, no content). In my scenario, the editor instance is created upon button click to eliminate any network impact.

The vanilla CKEditor from source:

image

Vue CLI app in the development (yarn serve) mode:

image

The difference undeniable (480 vs 780ms per click) though I couldn't find any obvious bottleneck in the chart.

Production Vue CLI app (yarn build)

image

The gain is not that great (710 vs 770ms).


I think the culprit could be the build size (vanilla-prod vue.js app = 252KB). That's a lot and maybe it comes down to what the vue-cli does to the code (e.g. lots of polyfills?)

oleq avatar Feb 03 '20 15:02 oleq

The standard 480ms is definitely nothing spectacular – we should definitely be looking there for improvements someday.

However, it's disturbing how badly Vue affects CKEditor 5. I wonder if this happens with other kinds of apps/libs too.

Reinmar avatar Feb 03 '20 15:02 Reinmar

I was right about nasty polyfills. I used the "modern mode" of Vue CLI and the bundle size decreased to 700kb (was 890, vanilla CKEditor is 640) and the performance is way better now (it corresponds to vanilla CKEditor):

image

oleq avatar Feb 03 '20 15:02 oleq

@benjaminprojas Can you confirm dropping heavy polyfills speeds up the editor?

oleq avatar Feb 04 '20 09:02 oleq

@oleq I am happy to give that a try, but this is the first time I've heard of "Modern Mode". I need to see if there is a way to convert my already existing application into that before I can fully test. I'll let you know.

benjaminprojas avatar Feb 04 '20 13:02 benjaminprojas

@oleq, I just did a build using "Modern Mode" (which required some significant restructuring) and I can see no noticeable difference when loading the page with 5 editors. It still locks up for me for roughly 3 seconds or so. Here is a video of it happening built with modern mode: https://help.supportally.com/KouepDmw

benjaminprojas avatar Feb 05 '20 12:02 benjaminprojas

which required some significant restructuring

Why? It all comes down to babel configuration. The app should work fine in any modern browser without polyfills.

Anyway, we're keeping track of performance issues. Hopefully, some improvements proposed in https://github.com/ckeditor/ckeditor5/issues/5880 will make things better for you.

oleq avatar Feb 06 '20 11:02 oleq

Why? It all comes down to babel configuration.

Yes, the restructuring was for babel, not the app itself. At any rate, I know what to do now to test again.

Thanks @oleq, I'm hoping so as well.

benjaminprojas avatar Feb 06 '20 12:02 benjaminprojas

Let me also mention that we did a bit of research recently and we identified a couple of performance issues (recent regressions) that we're fixing now. Some fixes will make into the upcoming release. Some will have to wait a bit, probably till the next one.

Depending on the setup, I think that we can save up to 40% on bootstrap time.

Reinmar avatar Feb 12 '20 08:02 Reinmar

I've updated to 18.0.0 and while I do see some improvement, the general issue remains. More than one editor and it still lags to load the page.

benjaminprojas avatar Mar 26 '20 11:03 benjaminprojas

We have a similar usecase and use 3 editors on a page(React) at once - like a form with each instance as a field.

The lag is heavy. @benjaminprojas Did you ever find a solution?

amit-coditas avatar Aug 27 '20 07:08 amit-coditas

@amit-coditas Unfortunately, no. At this point just living with it as it doesn't lag after that initial load time. I'm on 21.0.0 currently.

benjaminprojas avatar Aug 27 '20 10:08 benjaminprojas

I'm using with Vue.js

and import plugins, it's take 2s to render Editor. When i removed Table plugin, it's faster a little bit.

My plugins was imported:

import ClassicEditor from "@ckeditor/ckeditor5-editor-classic/src/classiceditor" import Alignment from "@ckeditor/ckeditor5-alignment/src/alignment" import Autoformat from "@ckeditor/ckeditor5-autoformat/src/autoformat" import Autolink from "@ckeditor/ckeditor5-link/src/autolink" import Autosave from "@ckeditor/ckeditor5-autosave/src/autosave" import Base64UploadAdapter from "@ckeditor/ckeditor5-upload/src/adapters/base64uploadadapter" import BlockQuote from "@ckeditor/ckeditor5-block-quote/src/blockquote" import Bold from "@ckeditor/ckeditor5-basic-styles/src/bold" import Essentials from "@ckeditor/ckeditor5-essentials/src/essentials" import FontBackgroundColor from "@ckeditor/ckeditor5-font/src/fontbackgroundcolor" import FontColor from "@ckeditor/ckeditor5-font/src/fontcolor" import FontSize from "@ckeditor/ckeditor5-font/src/fontsize" import Heading from "@ckeditor/ckeditor5-heading/src/heading" import HorizontalLine from "@ckeditor/ckeditor5-horizontal-line/src/horizontalline" import Image from "@ckeditor/ckeditor5-image/src/image" import ImageCaption from "@ckeditor/ckeditor5-image/src/imagecaption" import ImageResize from "@ckeditor/ckeditor5-image/src/imageresize" import ImageStyle from "@ckeditor/ckeditor5-image/src/imagestyle" import ImageToolbar from "@ckeditor/ckeditor5-image/src/imagetoolbar" import ImageUpload from "@ckeditor/ckeditor5-image/src/imageupload" import Indent from "@ckeditor/ckeditor5-indent/src/indent" import IndentBlock from "@ckeditor/ckeditor5-indent/src/indentblock" import Italic from "@ckeditor/ckeditor5-basic-styles/src/italic" import Link from "@ckeditor/ckeditor5-link/src/link" import List from "@ckeditor/ckeditor5-list/src/list" import MediaEmbed from "@ckeditor/ckeditor5-media-embed/src/mediaembed" import Paragraph from "@ckeditor/ckeditor5-paragraph/src/paragraph" import PasteFromOffice from "@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice" import RemoveFormat from "@ckeditor/ckeditor5-remove-format/src/removeformat" import SpecialCharacters from "@ckeditor/ckeditor5-special-characters/src/specialcharacters" import SpecialCharactersArrows from "@ckeditor/ckeditor5-special-characters/src/specialcharactersarrows" import SpecialCharactersCurrency from "@ckeditor/ckeditor5-special-characters/src/specialcharacterscurrency" import SpecialCharactersMathematical from "@ckeditor/ckeditor5-special-characters/src/specialcharactersmathematical" import SpecialCharactersText from "@ckeditor/ckeditor5-special-characters/src/specialcharacterstext" import Strikethrough from "@ckeditor/ckeditor5-basic-styles/src/strikethrough" import Subscript from "@ckeditor/ckeditor5-basic-styles/src/subscript" import Superscript from "@ckeditor/ckeditor5-basic-styles/src/superscript" import Table from "@ckeditor/ckeditor5-table/src/table" import TableCellProperties from "@ckeditor/ckeditor5-table/src/tablecellproperties" import TableProperties from "@ckeditor/ckeditor5-table/src/tableproperties" import TableToolbar from "@ckeditor/ckeditor5-table/src/tabletoolbar" import TextTransformation from "@ckeditor/ckeditor5-typing/src/texttransformation" import TodoList from "@ckeditor/ckeditor5-list/src/todolist" import Underline from "@ckeditor/ckeditor5-basic-styles/src/underline"

datdevs avatar Sep 08 '20 02:09 datdevs