Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plate 38: Performance optimization #3506

Merged
merged 13 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import React from 'react';

import { BasicElementsPlugin } from '@udecode/plate-basic-elements/react';
import { BasicMarksPlugin } from '@udecode/plate-basic-marks/react';
import { Plate, usePlateEditor } from '@udecode/plate-common/react';

import { editableProps } from '@/plate/demo/editableProps';
import { PlateUI } from '@/plate/demo/plate-ui';
import { createMultiEditorsValue } from '@/plate/demo/values/createMultiEditorsValue';
import { Editor } from '@/registry/default/plate-ui/editor';

Expand All @@ -14,8 +11,8 @@ const values = createMultiEditorsValue();
function WithPlate({ id, value }: any) {
const editor = usePlateEditor({
id,
override: { components: PlateUI },
plugins: [BasicElementsPlugin, BasicMarksPlugin],
// override: { components: PlateUI },
// plugins: [BasicElementsPlugin, BasicMarksPlugin],
value,
});

Expand Down
17 changes: 10 additions & 7 deletions apps/www/src/registry/default/example/playground-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ import { SlashPlugin } from '@udecode/plate-slash-command';
import { TablePlugin } from '@udecode/plate-table/react';
import { TogglePlugin } from '@udecode/plate-toggle/react';
import { TrailingBlockPlugin } from '@udecode/plate-trailing-block';
import Prism from 'prismjs';

import { CheckPlugin } from '@/components/context/check-plugin';
import { settingsStore } from '@/components/context/settings-store';
Expand Down Expand Up @@ -106,8 +105,9 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {
const key = settingsStore.use.version();

const editorId = id || 'playground-' + key;
console.time('usePlaygroundEditor');

return usePlateEditor(
const a = usePlateEditor(
{
id: editorId,
override: {
Expand All @@ -121,11 +121,11 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {
// Nodes
HeadingPlugin,
BlockquotePlugin,
CodeBlockPlugin.configure({
options: {
prism: Prism,
},
}),
// CodeBlockPlugin.configure({
// options: {
// prism: Prism,
// },
// }),
HorizontalRulePlugin,
LinkPlugin.extend({
render: { afterEditable: () => <LinkFloatingToolbar /> },
Expand Down Expand Up @@ -315,6 +315,9 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {
},
[]
);
console.timeEnd('usePlaygroundEditor');

return a;
};

export default function PlaygroundDemo({
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/lib/editor/withSlate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ export const withSlate = <
...pluginConfig
}: WithSlateOptions<V, P> = {}
): TSlateEditor<V, InferPlugins<P[]>> => {
console.time('withSlate');

const editor = e as SlateEditor;

// Override incremental id generated by slate
Expand Down Expand Up @@ -188,7 +190,9 @@ export const withSlate = <
rootPluginInstance = rootPlugin(rootPluginInstance) as any;
}

console.time('resolvePlugins');
resolvePlugins(editor, [rootPluginInstance]);
console.timeEnd('resolvePlugins');

if (typeof value === 'string') {
editor.children = editor.api.html.deserialize({ element: value }) as Value;
Expand All @@ -210,9 +214,13 @@ export const withSlate = <
pipeNormalizeInitialValue(editor);
}
if (shouldNormalizeEditor) {
console.time('normalizeEditor');
normalizeEditor(editor, { force: true });
console.timeEnd('normalizeEditor');
}

console.timeEnd('withSlate');

return editor as any;
};

Expand Down
8 changes: 2 additions & 6 deletions packages/core/src/lib/plugin/createSlatePlugin.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import type { Modify } from '@udecode/utils';

import cloneDeep from 'lodash/cloneDeep.js';
import merge from 'lodash/merge.js';

import type { SlateEditor } from '../editor/SlateEditor';
import type { AnyPluginConfig, PluginConfig } from './BasePlugin';
import type {
Expand Down Expand Up @@ -111,8 +108,7 @@ export function createSlatePlugin<

const key = baseConfig.key ?? '';

const plugin = merge(
{},
const plugin = mergeWithoutArray(
{
__apiExtensions: [],
__configuration: null,
Expand All @@ -135,7 +131,7 @@ export function createSlatePlugin<
shortcuts: {},
transforms: {},
},
cloneDeep(config)
config
) as unknown as SlatePlugin<PluginConfig<K, O, A, T>>;

plugin.configure = (config) => {
Expand Down
24 changes: 21 additions & 3 deletions packages/core/src/lib/plugin/getSlatePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import type {
} from './BasePlugin';
import type { AnySlatePlugin, SlatePlugin } from './SlatePlugin';

import { resolvePlugin } from '../utils';

/** Get editor plugin by key or plugin object. */
export function getSlatePlugin<C extends AnyPluginConfig = PluginConfig>(
editor: SlateEditor,
Expand All @@ -22,7 +20,27 @@ export function getSlatePlugin<C extends AnyPluginConfig = PluginConfig>(
const editorPlugin = editor.plugins[p.key] as any;

if (!editorPlugin) {
return plugin.__resolved ? p : resolvePlugin(editor, plugin);
return {
__apiExtensions: [],
__configuration: null,
__extensions: [],
__optionExtensions: [],
dependencies: [],
editor: {},
handlers: {},
inject: {},
node: {},
override: {},
parser: {},
parsers: {},
plugins: [],
priority: 100,
render: {},
shortcuts: {},
transforms: {},
...plugin,
};
// return plugin.__resolved ? p : resolvePlugin(editor, plugin);
}

return editorPlugin;
Expand Down
61 changes: 48 additions & 13 deletions packages/core/src/lib/utils/resolvePlugin.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { cloneDeep } from 'lodash';

import type { SlateEditor } from '../editor';
import type { PluginConfig } from '../plugin/BasePlugin';
import type { AnySlatePlugin, SlatePlugin } from '../plugin/SlatePlugin';

import { mergeWithoutArray } from '../../internal/mergeWithoutArray';
import { createSlatePlugin, getEditorPlugin } from '../plugin';
import { getEditorPlugin } from '../plugin';
import { mergeLevel } from './resolvePlugins';

/**
* Resolves and finalizes a plugin configuration for use in a Plate editor.
Expand All @@ -24,8 +26,38 @@ export const resolvePlugin = <P extends AnySlatePlugin>(
editor: SlateEditor,
_plugin: P
): P => {
// if (_plugin.key === 'p') {
// // Minimize the number of calls
// console.log(editor.key, _plugin.key);
// }

// Create a deep clone of the plugin
let plugin = createSlatePlugin(_plugin) as P;
let plugin = {
__apiExtensions: [],
__configuration: null,
__extensions: [],
__optionExtensions: [],
dependencies: [],
editor: {},
handlers: {},
inject: {},
node: {},
override: {},
parser: {},
parsers: {},
plugins: [],
priority: 100,
render: {},
shortcuts: {},
transforms: {},
...(_plugin as any),
} as P;

plugin.node = { type: plugin.key, ...(_plugin.node as any) };
// plugin.api = mergeOneLevel(plugin.api, _plugin.api);
// plugin.options = mergeOneLevel(plugin.options, _plugin.options);
plugin.api = cloneDeep(_plugin.api);
plugin.options = cloneDeep(_plugin.options);

plugin.__resolved = true;

Expand All @@ -35,33 +67,34 @@ export const resolvePlugin = <P extends AnySlatePlugin>(
getEditorPlugin(editor, plugin as any)
);

plugin = mergeWithoutArray({}, plugin, configResult);
plugin = mergeLevel(plugin, configResult, 3);

delete (plugin as any).__configuration;
}
// Apply all stored extensions
if (plugin.__extensions && plugin.__extensions.length > 0) {
plugin.__extensions.forEach((extension) => {
plugin = mergeWithoutArray(
{},
plugin = mergeLevel(
plugin,
extension(getEditorPlugin(editor, plugin as any))
extension(getEditorPlugin(editor, plugin as any)),
3
);
});
plugin.__extensions = [];
}
if (plugin.plugins) {
plugin.plugins = plugin.plugins.map((p) => resolvePlugin(editor, p));
// plugin.plugins = plugin.plugins.map((p) => {
// return resolvePlugin(editor, p);
// });
}

const targetPluginToInject = plugin.inject?.targetPluginToInject;
const targetPlugins = plugin.inject?.targetPlugins;

if (targetPluginToInject && targetPlugins && targetPlugins.length > 0) {
plugin.inject = plugin.inject || {};
plugin.inject.plugins = mergeWithoutArray(
{},
plugin.inject.plugins,
plugin.inject.plugins = mergeLevel(
plugin.inject.plugins ?? {},
Object.fromEntries(
targetPlugins.map((targetPlugin) => {
const injectedPlugin = targetPluginToInject({
Expand All @@ -71,11 +104,13 @@ export const resolvePlugin = <P extends AnySlatePlugin>(

return [targetPlugin, injectedPlugin];
})
)
),
4
);
}
// PERF
if (plugin.plugins) {
plugin.plugins = plugin.plugins.map((p) => resolvePlugin(editor, p));
// plugin.plugins = plugin.plugins.map((p) => resolvePlugin(editor, p));
}
// TODO React
if ((plugin as any).node?.component) {
Expand Down
Loading
Loading