mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-02 14:31:31 +01:00
Use morphdom to reduce number of full page updates to md preview
This should help improve scroll sync and also reduce the number of times we go out to the network if images are in the preview
This commit is contained in:
@@ -16,7 +16,7 @@ import { WebviewResourceProvider } from '../util/resources';
|
||||
import { getVisibleLine, LastScrollLocation, TopmostLineMonitor } from '../util/topmostLineMonitor';
|
||||
import { urlToUri } from '../util/url';
|
||||
import { MarkdownPreviewConfigurationManager } from './previewConfig';
|
||||
import { MarkdownContentProvider, MarkdownContentProviderOutput } from './previewContentProvider';
|
||||
import { MarkdownContentProvider } from './previewContentProvider';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -63,7 +63,7 @@ interface PreviewStyleLoadErrorMessage extends WebviewMessage {
|
||||
|
||||
export class PreviewDocumentVersion {
|
||||
|
||||
private readonly resource: vscode.Uri;
|
||||
public readonly resource: vscode.Uri;
|
||||
private readonly version: number;
|
||||
|
||||
public constructor(document: vscode.TextDocument) {
|
||||
@@ -314,13 +314,18 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldReloadPage = !this.currentVersion || this.currentVersion.resource.toString() !== pendingVersion.resource.toString();
|
||||
this.currentVersion = pendingVersion;
|
||||
const content = await this._contentProvider.provideTextDocumentContent(document, this, this._previewConfigurations, this.line, this.state);
|
||||
|
||||
const content = await (shouldReloadPage
|
||||
? this._contentProvider.provideTextDocumentContent(document, this, this._previewConfigurations, this.line, this.state)
|
||||
: this._contentProvider.markdownBody(document, this));
|
||||
|
||||
// Another call to `doUpdate` may have happened.
|
||||
// Make sure we are still updating for the correct document
|
||||
if (this.currentVersion?.equals(pendingVersion)) {
|
||||
this.setContent(content);
|
||||
this.updateWebviewContent(content.html, shouldReloadPage);
|
||||
this.updateImageWatchers(content.containingImages);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,7 +371,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
|
||||
this._webviewPanel.webview.html = this._contentProvider.provideFileNotFoundContent(this._resource);
|
||||
}
|
||||
|
||||
private setContent(content: MarkdownContentProviderOutput): void {
|
||||
private updateWebviewContent(html: string, reloadPage: boolean): void {
|
||||
if (this._disposed) {
|
||||
return;
|
||||
}
|
||||
@@ -377,9 +382,19 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
|
||||
this._webviewPanel.iconPath = this.iconPath;
|
||||
this._webviewPanel.webview.options = this.getWebviewOptions();
|
||||
|
||||
this._webviewPanel.webview.html = content.html;
|
||||
if (reloadPage) {
|
||||
this._webviewPanel.webview.html = html;
|
||||
} else {
|
||||
this._webviewPanel.webview.postMessage({
|
||||
type: 'updateContent',
|
||||
content: html,
|
||||
source: this._resource.toString(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const srcs = new Set(content.containingImages.map(img => img.src));
|
||||
private updateImageWatchers(containingImages: { src: string }[]) {
|
||||
const srcs = new Set(containingImages.map(img => img.src));
|
||||
|
||||
// Delete stale file watchers.
|
||||
for (const [src, watcher] of [...this._fileWatchersBySrc]) {
|
||||
|
||||
@@ -81,7 +81,7 @@ export class MarkdownContentProvider {
|
||||
const nonce = getNonce();
|
||||
const csp = this.getCsp(resourceProvider, sourceUri, nonce);
|
||||
|
||||
const body = await this.engine.render(markdownDocument, resourceProvider);
|
||||
const body = await this.markdownBody(markdownDocument, resourceProvider);
|
||||
const html = `<!DOCTYPE html>
|
||||
<html style="${escapeAttribute(this.getSettingsOverrideStyles(config))}">
|
||||
<head>
|
||||
@@ -97,7 +97,6 @@ export class MarkdownContentProvider {
|
||||
</head>
|
||||
<body class="vscode-body ${config.scrollBeyondLastLine ? 'scrollBeyondLastLine' : ''} ${config.wordWrap ? 'wordWrap' : ''} ${config.markEditorSelection ? 'showEditorSelection' : ''}">
|
||||
${body.html}
|
||||
<div class="code-line" data-line="${markdownDocument.lineCount}"></div>
|
||||
${this.getScripts(resourceProvider, nonce)}
|
||||
</body>
|
||||
</html>`;
|
||||
@@ -107,6 +106,18 @@ export class MarkdownContentProvider {
|
||||
};
|
||||
}
|
||||
|
||||
public async markdownBody(
|
||||
markdownDocument: vscode.TextDocument,
|
||||
resourceProvider: WebviewResourceProvider,
|
||||
): Promise<MarkdownContentProviderOutput> {
|
||||
const rendered = await this.engine.render(markdownDocument, resourceProvider);
|
||||
const html = `<div class="markdown-body">${rendered.html}<div class="code-line" data-line="${markdownDocument.lineCount}"></div></div>`;
|
||||
return {
|
||||
html,
|
||||
containingImages: rendered.containingImages
|
||||
};
|
||||
}
|
||||
|
||||
public provideFileNotFoundContent(
|
||||
resource: vscode.Uri,
|
||||
): string {
|
||||
|
||||
Reference in New Issue
Block a user