Repository navigation
Boot: lazy-load the editor instead of importing it eagerly in the save UI #79913
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
Changes from all commits
6522421
4a61f6f
539c9d3
96cf727
387177b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| /** | ||
| * External dependencies | ||
| */ | ||
| import type { ComponentProps } from 'react'; | ||
|
|
||
| /** | ||
| * WordPress dependencies | ||
| */ | ||
| import { lazy, Suspense } from '@wordpress/element'; | ||
| import { Spinner } from '@wordpress/components'; | ||
|
|
||
| /** | ||
| * `EntitiesSavedStates` lives in `@wordpress/editor`, a classic script that would | ||
| * otherwise be pulled into boot's eager dependencies and force the whole editor | ||
| * (block-editor, block-library, media-utils, …) to load on every view. | ||
| * | ||
| * Loading it through `@wordpress/lazy-editor` — a script module — defers the editor | ||
| * until the "Review changes" modal actually opens, which only happens while editing, | ||
| * when the editor has already been loaded by the canvas. | ||
| */ | ||
| const EntitiesSavedStates = lazy( () => | ||
| import( '@wordpress/lazy-editor' ).then( ( module ) => ( { | ||
| default: module.EntitiesSavedStates, | ||
| } ) ) | ||
| ); | ||
|
|
||
| export default function LazyEntitiesSavedStates( | ||
| props: ComponentProps< typeof EntitiesSavedStates > | ||
| ) { | ||
| return ( | ||
| <Suspense fallback={ <Spinner /> }> | ||
| <EntitiesSavedStates { ...props } /> | ||
| </Suspense> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,12 +7,17 @@ import { | |
| store as keyboardShortcutsStore, | ||
| } from '@wordpress/keyboard-shortcuts'; | ||
| import { __ } from '@wordpress/i18n'; | ||
| import { useDispatch, useSelect } from '@wordpress/data'; | ||
| import { useDispatch, useSelect, useRegistry } from '@wordpress/data'; | ||
| import { store as coreStore } from '@wordpress/core-data'; | ||
| import { store as editorStore } from '@wordpress/editor'; | ||
|
|
||
| const shortcutName = 'core/boot/save'; | ||
|
|
||
| // The editor store is provided by the classic @wordpress/editor script, which is | ||
| // loaded lazily (via the canvas / lazy-editor). Referencing it by name here — rather | ||
| // than importing the store descriptor — keeps @wordpress/editor out of boot's eager | ||
| // dependency graph so the editor only loads when there is something to edit. | ||
| const EDITOR_STORE_NAME = 'core/editor'; | ||
|
|
||
| /** | ||
| * Register the save keyboard shortcut in view mode. | ||
| * | ||
|
|
@@ -24,11 +29,9 @@ export default function useSaveShortcut( { | |
| }: { | ||
| openSavePanel: () => void; | ||
| } ) { | ||
| const registry = useRegistry(); | ||
| const { __experimentalGetDirtyEntityRecords, isSavingEntityRecord } = | ||
| useSelect( coreStore ); | ||
| const { hasNonPostEntityChanges, isPostSavingLocked } = | ||
| useSelect( editorStore ); | ||
| const { savePost } = useDispatch( editorStore ); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we replace these with things from "core-data" instead. Core Data should already have all what's needed to check dirtiness and things like that. One thing that might be missing in "core-data" is the "save lock" behavior which probably belongs there, rather than "editor". I wonder if we should do a small refactor to move things there? |
||
| const { registerShortcut, unregisterShortcut } = useDispatch( | ||
| keyboardShortcutsStore | ||
| ); | ||
|
|
@@ -57,10 +60,14 @@ export default function useSaveShortcut( { | |
| if ( ! hasDirtyEntities || isSaving ) { | ||
| return; | ||
| } | ||
| if ( hasNonPostEntityChanges() ) { | ||
| // The editor store is only registered once the editor has been loaded. | ||
| // When it isn't present there is nothing post-related to save, so fall | ||
| // back to the entity-only save panel. | ||
| const editorSelectors = registry.select( EDITOR_STORE_NAME ); | ||
| if ( ! editorSelectors || editorSelectors.hasNonPostEntityChanges() ) { | ||
| openSavePanel(); | ||
| } else if ( ! isPostSavingLocked() ) { | ||
| savePost(); | ||
| } else if ( ! editorSelectors.isPostSavingLocked() ) { | ||
| registry.dispatch( EDITOR_STORE_NAME ).savePost(); | ||
| } | ||
| } ); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, this component doesn't belong in "editor" package. So instead of adding complexity, maybe the right solution is to move it to the right place. This is what I tried to do in this old PR #71948 (worth reviving?)