reuse line index cache for posFromIndex
100ms -> 50ms rendering time in updateInvisible() for "RU AdList CSS Fixes" style
300ms -> 50ms is the final speedup with the widget height cache in 3fd4343c
This commit is contained in:
parent
5dbd2249dd
commit
170bd0ccb1
|
@ -217,25 +217,40 @@ function createAppliesToLineWidget(cm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// decide search range
|
// decide search range
|
||||||
const fromIndex = widgets[i] ? cm.indexFromPos({line: widgets[i].line.lineNo(), ch: 0}) : 0;
|
const fromPos = {line: widgets[i] ? widgets[i].line.lineNo() : 0, ch: 0};
|
||||||
const toIndex = cm.indexFromPos({line: widgets[j] ? widgets[j].line.lineNo() : toLine + 1, ch: 0});
|
const toPos = {line: widgets[j] ? widgets[j].line.lineNo() : toLine + 1, ch: 0};
|
||||||
|
|
||||||
|
// calc index->pos lookup table
|
||||||
|
let line = 0;
|
||||||
|
let index = 0;
|
||||||
|
let fromIndex, toIndex;
|
||||||
|
const lineIndexes = [index];
|
||||||
|
cm.doc.iter(({text}) => {
|
||||||
|
fromIndex = line === fromPos.line ? index : fromIndex;
|
||||||
|
lineIndexes.push((index += text.length + 1));
|
||||||
|
line++;
|
||||||
|
toIndex = line >= toPos.line ? index : toIndex;
|
||||||
|
return toIndex;
|
||||||
|
});
|
||||||
|
|
||||||
// splice
|
// splice
|
||||||
i = Math.max(0, i);
|
i = Math.max(0, i);
|
||||||
widgets.splice(i, 0, ...createWidgets(fromIndex, toIndex, widgets.splice(i, j - i)));
|
widgets.splice(i, 0, ...createWidgets(fromIndex, toIndex, widgets.splice(i, j - i), lineIndexes));
|
||||||
|
|
||||||
fromLine = null;
|
fromLine = null;
|
||||||
toLine = null;
|
toLine = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function *createWidgets(start, end, removed) {
|
function *createWidgets(start, end, removed, lineIndexes) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
let itemHeight;
|
let itemHeight;
|
||||||
for (const section of findAppliesTo(start, end)) {
|
for (const section of findAppliesTo(start, end)) {
|
||||||
while (removed[i] && removed[i].line.lineNo() < section.pos.line) {
|
while (removed[i] && removed[i].line.lineNo() < section.pos.line) {
|
||||||
clearWidget(removed[i++]);
|
clearWidget(removed[i++]);
|
||||||
}
|
}
|
||||||
setupMarkers(section);
|
for (const a of section.applies) {
|
||||||
|
setupApplyMarkers(a, lineIndexes);
|
||||||
|
}
|
||||||
if (removed[i] && removed[i].line.lineNo() === section.pos.line) {
|
if (removed[i] && removed[i].line.lineNo() === section.pos.line) {
|
||||||
// reuse old widget
|
// reuse old widget
|
||||||
removed[i].section.applies.forEach(apply => {
|
removed[i].section.applies.forEach(apply => {
|
||||||
|
@ -278,28 +293,49 @@ function createAppliesToLineWidget(cm) {
|
||||||
apply.mark.clear();
|
apply.mark.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupMarkers({applies}) {
|
function setupApplyMarkers(apply, lineIndexes) {
|
||||||
applies.forEach(setupApplyMarkers);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupApplyMarkers(apply) {
|
|
||||||
apply.type.mark = cm.markText(
|
apply.type.mark = cm.markText(
|
||||||
cm.posFromIndex(apply.type.start),
|
posFromIndex(cm, apply.type.start, lineIndexes),
|
||||||
cm.posFromIndex(apply.type.end),
|
posFromIndex(cm, apply.type.end, lineIndexes),
|
||||||
{clearWhenEmpty: false}
|
{clearWhenEmpty: false}
|
||||||
);
|
);
|
||||||
apply.value.mark = cm.markText(
|
apply.value.mark = cm.markText(
|
||||||
cm.posFromIndex(apply.value.start),
|
posFromIndex(cm, apply.value.start, lineIndexes),
|
||||||
cm.posFromIndex(apply.value.end),
|
posFromIndex(cm, apply.value.end, lineIndexes),
|
||||||
{clearWhenEmpty: false}
|
{clearWhenEmpty: false}
|
||||||
);
|
);
|
||||||
apply.mark = cm.markText(
|
apply.mark = cm.markText(
|
||||||
cm.posFromIndex(apply.start),
|
posFromIndex(cm, apply.start, lineIndexes),
|
||||||
cm.posFromIndex(apply.end),
|
posFromIndex(cm, apply.end, lineIndexes),
|
||||||
{clearWhenEmpty: false}
|
{clearWhenEmpty: false}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function posFromIndex(cm, index, lineIndexes) {
|
||||||
|
if (!lineIndexes) {
|
||||||
|
return cm.posFromIndex(index);
|
||||||
|
}
|
||||||
|
let line = lineIndexes.prev || 0;
|
||||||
|
const prev = lineIndexes[line];
|
||||||
|
const next = lineIndexes[line + 1];
|
||||||
|
if (prev <= index && index < next) {
|
||||||
|
return {line, ch: index - prev};
|
||||||
|
}
|
||||||
|
let a = index < prev ? 0 : line;
|
||||||
|
let b = index < next ? line + 1 : lineIndexes.length - 1;
|
||||||
|
while (a < b - 1) {
|
||||||
|
const mid = (a + b) >> 1;
|
||||||
|
if (lineIndexes[mid] < index) {
|
||||||
|
a = mid;
|
||||||
|
} else {
|
||||||
|
b = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line = lineIndexes[b] > index ? a : b;
|
||||||
|
Object.defineProperty(lineIndexes, 'prev', {value: line, configurable: true});
|
||||||
|
return {line, ch: index - lineIndexes[line]};
|
||||||
|
}
|
||||||
|
|
||||||
function buildElement({applies}) {
|
function buildElement({applies}) {
|
||||||
const el = template.clone('container');
|
const el = template.clone('container');
|
||||||
const appliesToList = $('.applies-to-list', el);
|
const appliesToList = $('.applies-to-list', el);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user