1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Desktop: Resolves #6736: Significantly improve performance when displaying large tables in Rich Text editor

This commit is contained in:
Laurent Cozic 2023-09-24 15:35:00 +01:00
parent 28384ddfd9
commit cd1e1cdf94
2 changed files with 38 additions and 7 deletions

View File

@ -5,6 +5,11 @@ var alignMap = { left: ':---', right: '---:', center: ':---:' };
let isCodeBlock_ = null;
// We need to cache the result of tableShouldBeSkipped() as it is expensive.
// Caching it means we went from about 9000 ms for rendering down to 90 ms.
// Fixes https://github.com/laurent22/joplin/issues/6736
const tableShouldBeSkippedCache_ = new Map();
function getAlignment(node) {
return node ? (node.getAttribute('align') || node.style.textAlign || '').toLowerCase() : '';
}
@ -188,11 +193,20 @@ const tableShouldBeHtml = (tableNode) => {
// Various conditions under which a table should be skipped - i.e. each cell
// will be rendered one after the other as if they were paragraphs.
function tableShouldBeSkipped(tableNode) {
if (!tableNode) return true;
if (!tableNode.rows) return true;
if (tableNode.rows.length === 1 && tableNode.rows[0].childNodes.length <= 1) return true; // Table with only one cell
if (nodeContainsTable(tableNode)) return true;
return false;
const cached = tableShouldBeSkippedCache_.get(tableNode);
if (cached !== undefined) return cached;
const process = () => {
if (!tableNode) return true;
if (!tableNode.rows) return true;
if (tableNode.rows.length === 1 && tableNode.rows[0].childNodes.length <= 1) return true; // Table with only one cell
if (nodeContainsTable(tableNode)) return true;
return false;
}
const result = process();
tableShouldBeSkippedCache_.set(tableNode, result);
return result;
}
function nodeParentTable(node) {

View File

@ -1,5 +1,22 @@
/* eslint-disable import/prefer-default-export */
export const msleep = (ms: number) => {
return new Promise(resolve => setTimeout(resolve, ms));
};
// Use the utility functions below to easily measure performance of a block or
// line of code.
interface PerfTimer {
name: string;
startTime: number;
}
const perfTimers_: PerfTimer[] = [];
export function timerPush(name: string) {
perfTimers_.push({ name, startTime: Date.now() });
}
export function timerPop() {
const t = perfTimers_.pop() as PerfTimer;
// eslint-disable-next-line no-console
console.info(`Time: ${t.name}: ${Date.now() - t.startTime}`);
}