Skip to content

Commit 7ac3e93

Browse files
committed
feat: lazy initialization for editor setup
Signed-off-by: Enjeck C. <patrathewhiz@gmail.com>
1 parent 234ebc8 commit 7ac3e93

2 files changed

Lines changed: 46 additions & 4 deletions

File tree

lib/Controller/PageController.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ public function index(): TemplateResponse {
4343
Util::addStyle(Application::APP_ID, 'grid');
4444
Util::addStyle(Application::APP_ID, 'modal');
4545
Util::addStyle(Application::APP_ID, 'tiptap');
46-
Util::addStyle(Application::APP_ID, 'tables-style');
4746

4847
if (class_exists(LoadViewer::class)) {
4948
$this->eventDispatcher->dispatchTyped(new LoadViewer());

src/shared/components/ncEditor/NcEditor.vue

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ export default {
6363
textAppAvailable: !!window.OCA?.Text?.createEditor,
6464
editor: null,
6565
localValue: '',
66+
observer: null,
67+
initialized: false,
68+
idleHandle: null,
6669
}
6770
},
6871
@@ -96,16 +99,56 @@ export default {
9699
97100
async mounted() {
98101
this.localValue = this.text
99-
await this.setupEditor()
100-
this.editor?.setContent(this.localValue, false)
102+
// Lazy initialize the editor:
103+
// 1) When the component becomes visible (IntersectionObserver)
104+
// 2) Or when the browser is idle (requestIdleCallback fallback)
105+
this.setupLazyInitialization()
101106
},
102107
103108
beforeDestroy() {
104-
this?.editor?.destroy()
109+
this?.observer?.disconnect?.()
110+
if (this.idleHandle && typeof cancelIdleCallback === 'function') {
111+
cancelIdleCallback(this.idleHandle)
112+
}
113+
this?.editor?.destroy?.()
105114
},
106115
107116
methods: {
108117
t,
118+
setupLazyInitialization() {
119+
if (this.initialized) return
120+
121+
// Prefer initializing when the editor wrapper enters the viewport
122+
if ('IntersectionObserver' in window) {
123+
this.observer = new IntersectionObserver((entries) => {
124+
for (const entry of entries) {
125+
if (entry.isIntersecting && !this.initialized) {
126+
this.initialized = true
127+
this.setupEditor().then(() => {
128+
this.editor?.setContent(this.localValue, false)
129+
})
130+
this.observer?.disconnect?.()
131+
break
132+
}
133+
}
134+
}, { rootMargin: '200px' })
135+
this.$nextTick(() => {
136+
const el = this.$el
137+
if (el) this.observer.observe(el)
138+
})
139+
} else {
140+
// Fallback: schedule during idle time to avoid blocking
141+
const idle = window.requestIdleCallback || ((cb) => setTimeout(() => cb({ timeRemaining: () => 0 }), 50))
142+
const cancel = window.cancelIdleCallback || clearTimeout
143+
this.idleHandle = idle(() => {
144+
if (this.initialized) return
145+
this.initialized = true
146+
this.setupEditor().then(() => {
147+
this.editor?.setContent(this.localValue, false)
148+
})
149+
})
150+
}
151+
},
109152
async setupEditor() {
110153
this?.editor?.destroy()
111154
if (this.textAppAvailable) {

0 commit comments

Comments
 (0)