diff --git a/CHANGELOG.md b/CHANGELOG.md index acf81d48..c054a086 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ The release run heads these entries with the version and opens a fresh - Prose is no longer read as a csv. A separator that every field follows with a space, in fields long enough to be sentences, is punctuation; `a, b, c` with short values is still a csv. One record is a line, not a table. +- A large text file appears at once: sizing the line numbers laid the page out + once per line. A megabyte took 38s and now takes under a second. ## v6.7.1 - 2026-08-16 diff --git a/src/odr/internal/html/frontend.cpp b/src/odr/internal/html/frontend.cpp index 67ed2771..0f3063b0 100644 --- a/src/odr/internal/html/frontend.cpp +++ b/src/odr/internal/html/frontend.cpp @@ -800,12 +800,19 @@ constexpr std::string_view text_js = R"js( // The measured height is fractional; `offsetHeight` would round it per line // and the numbers would walk away from the lines they belong to. + // + // Every height is read before any is written: interleaving them makes each + // read force the layout the write before it invalidated, one per line. TextEditor.prototype.updateLineNumberHeight = function () { var nrCells = this.textNr.querySelectorAll("div"); var textCells = this.textBody.querySelectorAll("div"); - for (var i = 0; i < textCells.length && i < nrCells.length; ++i) { - nrCells[i].style.height = - textCells[i].getBoundingClientRect().height + "px"; + var count = Math.min(textCells.length, nrCells.length); + var heights = new Array(count); + for (var i = 0; i < count; ++i) { + heights[i] = textCells[i].getBoundingClientRect().height; + } + for (var j = 0; j < count; ++j) { + nrCells[j].style.height = heights[j] + "px"; } };