catamphetamine / virtual-scroller

A component for efficiently rendering large lists of variable height items

Home Page:https://catamphetamine.gitlab.io/virtual-scroller/?dynamic=%E2%9C%93

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Chrome error: "maximum call stack size exceeded" when making large jumps

kulogix opened this issue · comments

When grabbing scrollbar and directly scrolling to far position in large list (e.g., skipping ~ 40k single-line records), getting "maximum call stack size exceeded". Doesn't happen if done in smaller batches (~ 30k), and doesn't happen if smaller batches are first pre-loaded, then skip to top and all the way back to bottom.

Tested on Chrome / macOS M3 Max (128GB). When tested on Safari, it runs much slower but doesn't error out (eventually completes successfully).

See below for example code (based on AlpineJS).

<div x-data="{
    files: [],
    virtualScroller: undefined,
    priorLastRenderedNumber: 0,
    currentRenderedNumber: 0,
    renderFile(file) {
        NProgress.start();
        currentRenderedNumber = file.number;
        //console.log(`Rendering ${currentRenderedNumber}`);
        const root = document.createElement('article');
        const anchor = document.createElement('a');
        anchor.setAttribute('href', `/assets/${file.id}`);
        anchor.textContent = `${file.number}: ${file.id}`;
        root.appendChild(anchor);
        $dispatch('stop-progress');
        return root;
    }
 }"
     x-init="files = Array.from({ length: 100000 }, (_, index) => ({ id: crypto.randomUUID(), number: index + 1 }));"
     @stop-progress.debounce.800ms="
        NProgress.done();
        console.log(`Rendered ${this.priorLastRenderedNumber || 1} to ${this.currentRenderedNumber} (${this.currentRenderedNumber - (this.priorLastRenderedNumber || 1)})`);
        this.priorLastRenderedNumber = this.currentRenderedNumber;
    "
>
    <div x-show="files.length == 0">No files exist yet.</div>
    <div x-show="files.length != 0" x-text="`${files.length} files displayed`"></div>
    <button @click="virtualScroller = new VirtualScroller(
        document.getElementById('filesList'),
        files,
        renderFile
    );">List Files</button>
    <div id="filesList"></div>
</div>

<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.13.5/dist/cdn.min.js" integrity="sha256-ygV4Me+b49juR+FAeAif0jgdx4ILS7f724WkkPW49ow=" crossorigin="anonymous" defer></script>
<script src="https://cdn.jsdelivr.net/npm/virtual-scroller@1.12.4/bundle/virtual-scroller-dom.js" integrity="sha256-PzCKtRkxJKa72wqNvsdCDH63njGgFkmQhepPWPUI7tk=" crossorigin="anonymous"></script>
<script src="https://unpkg.com/nprogress@0.2.0/nprogress.js"></script>
<link rel="stylesheet" href="https://unpkg.com/nprogress@0.2.0/nprogress.css">

Hmm. Ok.

Maybe there is such an error. When writing this component, I didn't really have a use case of tens of thousands of rows. The datasets I used were about 1k records max. So maybe that's why the error didn't manifest.

As for your use case, I won't look at the issue because I really don't have any intention of further developing this library. It seems to be stable for my particular use case — https://anychans.github.io/4chan/a — and that suffices. Anything beyond that is out of scope for me personally.