@@ -175,7 +175,13 @@ function openCheckboxPreview(
175175
176176 Logger . info ( `Created preview panel for ${ document . uri . toString ( ) } in column two` ) ;
177177
178+ let isWebviewReady = false ;
178179 const sendMessage = ( message : { type : string ; [ key : string ] : unknown } ) => {
180+ if ( ! panel . visible && message . type !== 'rerender' ) {
181+ Logger . debug ( `Skipping message type ${ message . type } ; panel not visible` ) ;
182+ return ;
183+ }
184+
179185 panel . webview . postMessage ( message ) . then ( sent => {
180186 if ( ! sent ) {
181187 Logger . warn ( `Webview message of type ${ message . type } was not delivered` ) ;
@@ -188,35 +194,51 @@ function openCheckboxPreview(
188194 // Set the initial HTML content
189195 panel . webview . html = getWebviewContent ( panel . webview , context , document . getText ( ) ) ;
190196 Logger . debug ( `Initial preview content rendered for ${ document . uri . toString ( ) } ` ) ;
197+
198+ // Mark webview as ready after short delay to ensure initialization
199+ setTimeout ( ( ) => {
200+ isWebviewReady = true ;
201+ Logger . debug ( `Webview ready for ${ document . uri . toString ( ) } ` ) ;
202+ } , 100 ) ;
191203
192204 // Register panel with auto-preview manager to prevent duplicates
193205 if ( autoPreviewManager ) {
194206 autoPreviewManager . registerPanel ( panel , document . uri ) ;
195207 }
196208
197- // Handle document changes
209+ // Handle document changes with debouncing to avoid flooding webview
210+ let updateTimeout : NodeJS . Timeout | undefined ;
198211 const changeDisposable = vscode . workspace . onDidChangeTextDocument ( event => {
199212 if ( event . document . uri . toString ( ) === document . uri . toString ( ) ) {
200213 Logger . debug ( `Document change detected for ${ document . uri . toString ( ) } (${ event . contentChanges . length } change(s))` ) ;
201- const newContent = event . document . getText ( ) ;
202- const html = renderMarkdown ( newContent ) ;
203- const stats = getTaskListCount ( newContent ) ;
204-
205- sendMessage ( {
206- type : 'rerender' ,
207- html : html
208- } ) ;
209-
210- sendMessage ( {
211- type : 'updateProgress' ,
212- completed : stats . completed ,
213- total : stats . total
214- } ) ;
215-
216- // Refresh tree view if available
217- if ( treeDataProvider ) {
218- treeDataProvider . refresh ( ) ;
214+
215+ // Clear existing timeout
216+ if ( updateTimeout ) {
217+ clearTimeout ( updateTimeout ) ;
219218 }
219+
220+ // Debounce updates by 150ms to batch rapid changes
221+ updateTimeout = setTimeout ( ( ) => {
222+ const newContent = event . document . getText ( ) ;
223+ const html = renderMarkdown ( newContent ) ;
224+ const stats = getTaskListCount ( newContent ) ;
225+
226+ sendMessage ( {
227+ type : 'rerender' ,
228+ html : html
229+ } ) ;
230+
231+ sendMessage ( {
232+ type : 'updateProgress' ,
233+ completed : stats . completed ,
234+ total : stats . total
235+ } ) ;
236+
237+ // Refresh tree view if available
238+ if ( treeDataProvider ) {
239+ treeDataProvider . refresh ( ) ;
240+ }
241+ } , 150 ) ;
220242 }
221243 } ) ;
222244
@@ -237,6 +259,9 @@ function openCheckboxPreview(
237259
238260 // Clean up when panel is disposed
239261 panel . onDidDispose ( ( ) => {
262+ if ( updateTimeout ) {
263+ clearTimeout ( updateTimeout ) ;
264+ }
240265 changeDisposable . dispose ( ) ;
241266 Logger . debug ( `Disposed preview panel for ${ document . uri . toString ( ) } ` ) ;
242267 // Auto-preview manager automatically unregisters via its own onDidDispose handler
0 commit comments