1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-06-15 23:00:36 +02:00

Desktop, Mobile: Fixes #2357: Fix slow rendering and memory leak issues with Katex notes

This commit is contained in:
Laurent Cozic
2020-02-08 11:11:04 +00:00
parent 639712c003
commit 3b200e5c92
8 changed files with 41 additions and 15 deletions

View File

@ -132,7 +132,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
this.viewerRef_.current.wrappedInstance.send('setHtml', result.html, { this.viewerRef_.current.wrappedInstance.send('setHtml', result.html, {
cssFiles: result.cssFiles, cssFiles: result.cssFiles,
pluginAssets: result.pluginAssets, pluginAssets: result.pluginAssets,
pluginAssetsHeadersHtml: assetsToHeaders(result.pluginAssets), pluginAssetsHeaders: assetsToHeaders(result.pluginAssets),
}); });
} }

View File

@ -2030,7 +2030,7 @@ class NoteTextComponent extends React.Component {
if (htmlHasChanged) { if (htmlHasChanged) {
let options = { let options = {
pluginAssets: this.state.lastRenderPluginAssets, pluginAssets: this.state.lastRenderPluginAssets,
pluginAssetsHeadersHtml: assetsToHeaders(this.state.lastRenderPluginAssets), pluginAssetsHeaders: assetsToHeaders(this.state.lastRenderPluginAssets),
downloadResources: Setting.value('sync.resourceDownloadMode'), downloadResources: Setting.value('sync.resourceDownloadMode'),
}; };
this.webviewRef_.current.wrappedInstance.send('setHtml', html, options); this.webviewRef_.current.wrappedInstance.send('setHtml', html, options);

View File

@ -47,6 +47,8 @@
window.postMessage({ target: 'main', name: methodName, args: [ arg ] }, '*'); window.postMessage({ target: 'main', name: methodName, args: [ arg ] }, '*');
} }
let pluginAssetsAdded_ = {};
try { try {
const contentElement = document.getElementById('joplin-container-content'); const contentElement = document.getElementById('joplin-container-content');
@ -93,6 +95,22 @@
setPercentScroll(percentScroll_); setPercentScroll(percentScroll_);
} }
// Note that this function keeps track of what's been added so as not to add the same CSS files multiple times
// It also means that once an asset has been added it is never removed from the view, which in many case is
// desirable, but still something to keep in mind.
function addPluginAssets(assets) {
if (!assets) return;
for (let name in assets) {
if (pluginAssetsAdded_[name]) continue;
pluginAssetsAdded_[name] = true;
const pluginAssetsContainer = document.createElement('div');
pluginAssetsContainer.innerHTML = assets[name];
document.getElementById('joplin-container-styleContainer').appendChild(pluginAssetsContainer);
}
}
ipc.scrollToHash = (event) => { ipc.scrollToHash = (event) => {
if (window.scrollToHashIID_) clearInterval(window.scrollToHashIID_); if (window.scrollToHashIID_) clearInterval(window.scrollToHashIID_);
window.scrollToHashIID_ = setInterval(() => { window.scrollToHashIID_ = setInterval(() => {
@ -142,11 +160,7 @@
}, 1); }, 1);
} }
if (event.options.pluginAssetsHeadersHtml) { addPluginAssets(event.options.pluginAssetsHeaders);
const pluginAssetsContainer = document.createElement('div');
pluginAssetsContainer.innerHTML = event.options.pluginAssetsHeadersHtml;
document.getElementById('joplin-container-styleContainer').appendChild(pluginAssetsContainer);
}
if (event.options.downloadResources === 'manual') { if (event.options.downloadResources === 'manual') {
webviewLib.setupResourceManualDownload(); webviewLib.setupResourceManualDownload();

View File

@ -101,7 +101,7 @@ class NoteBodyViewer extends Component {
<html> <html>
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
${assetsToHeaders(result.pluginAssets)} ${assetsToHeaders(result.pluginAssets, { asHtml: true })}
</head> </head>
<body> <body>
${html} ${html}

View File

@ -1,18 +1,28 @@
// Utility function to convert the plugin assets to a list of LINK or SCRIPT tags // Utility function to convert the plugin assets to a list of LINK or SCRIPT tags
// that can be included in the HEAD tag. // that can be included in the HEAD tag.
function assetsToHeaders(pluginAssets) { function assetsToHeaders(pluginAssets, options = null) {
const headers = []; options = Object.assign({}, { asHtml: false }, options);
const headers = {};
for (let i = 0; i < pluginAssets.length; i++) { for (let i = 0; i < pluginAssets.length; i++) {
const asset = pluginAssets[i]; const asset = pluginAssets[i];
if (asset.mime === 'text/css') { if (asset.mime === 'text/css') {
headers.push(`<link rel="stylesheet" href="pluginAssets/${asset.name}">`); headers[asset.name] = `<link rel="stylesheet" href="pluginAssets/${asset.name}">`;
} else if (asset.mime === 'application/javascript') { } else if (asset.mime === 'application/javascript') {
// NOT TESTED!! // NOT TESTED!!
headers.push(`<script type="application/javascript" src="pluginAssets/${asset.name}"></script>`); headers[asset.name] = `<script type="application/javascript" src="pluginAssets/${asset.name}"></script>`;
} }
} }
return headers.join('\n'); if (options.asHtml) {
let output = [];
for (let name in headers) {
output.push(headers[name]);
}
return output.join('');
}
return headers;
} }
module.exports = assetsToHeaders; module.exports = assetsToHeaders;

View File

@ -114,7 +114,7 @@ class InteropService_Exporter_Html extends InteropService_Exporter_Base {
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
${assetsToHeaders(result.pluginAssets)} ${assetsToHeaders(result.pluginAssets, { asHtml: true })}
<title>${escapeHtml(item.title)}</title> <title>${escapeHtml(item.title)}</title>
</head> </head>
<body> <body>

View File

@ -1,7 +1,8 @@
module.exports = { module.exports = {
hash:"964177e31d959b03bc63f11216c61e3e", files: { hash:"d3aff2e2510d28ed82c0ab64a230499d", files: {
'highlight.js/atom-one-dark-reasonable.css': { data: require('./highlight.js/atom-one-dark-reasonable.css.base64.js'), mime: 'text/css', encoding: 'base64' }, 'highlight.js/atom-one-dark-reasonable.css': { data: require('./highlight.js/atom-one-dark-reasonable.css.base64.js'), mime: 'text/css', encoding: 'base64' },
'highlight.js/atom-one-light.css': { data: require('./highlight.js/atom-one-light.css.base64.js'), mime: 'text/css', encoding: 'base64' }, 'highlight.js/atom-one-light.css': { data: require('./highlight.js/atom-one-light.css.base64.js'), mime: 'text/css', encoding: 'base64' },
'katex/fonts/KaTeX_AMS-Regular.woff2': { data: require('./katex/fonts/KaTeX_AMS-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
'katex/fonts/KaTeX_Main-Regular.woff2': { data: require('./katex/fonts/KaTeX_Main-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' }, 'katex/fonts/KaTeX_Main-Regular.woff2': { data: require('./katex/fonts/KaTeX_Main-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
'katex/fonts/KaTeX_Math-Italic.woff2': { data: require('./katex/fonts/KaTeX_Math-Italic.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' }, 'katex/fonts/KaTeX_Math-Italic.woff2': { data: require('./katex/fonts/KaTeX_Math-Italic.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
'katex/fonts/KaTeX_Size1-Regular.woff2': { data: require('./katex/fonts/KaTeX_Size1-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' }, 'katex/fonts/KaTeX_Size1-Regular.woff2': { data: require('./katex/fonts/KaTeX_Size1-Regular.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },

File diff suppressed because one or more lines are too long