【问题标题】:How to create a snappy User Interface with lots of local data?如何创建具有大量本地数据的快速用户界面?
【发布时间】:2020-09-02 14:58:45
【问题描述】:

我有一个包含 15000 多个项目的 JSON 文件。我的 JSON 文件大约有 7MB。我想在表格中显示所有结果(没有分页)并添加一些复选框以在某些条件下显示或隐藏项目。为了尽可能简化,假设我有一个复选框来仅显示来自巴黎的项目:

问题是UI不流畅。单击复选框大约需要一秒钟来刷新表格。这是不可接受的。

我正在使用fetch() 下载 JSON 数据,然后将其保存在本地。当用户点击复选框时,这就是我所做的:

document.getElementById('paris-only').addEventListener('click', updateTable);

function updateTable() {
    const parisOnly = document.getElementById('paris-only').checked;

    items.forEach(item => item.visible = !parisOnly || item.city === 'Paris');

    refreshTable();
}

function refreshTable() {
    [...document.getElementById('items-table').children].forEach((tr, index) => {
        tr.classList.toggle('hidden', !items[index].visible);
    });
}
.hidden {
    display: none;
}

我尝试与setTimeout(_, 0) 一起玩,但没有多大帮助。它减少了 UI 冻结,但刷新表格仍然需要很多时间。

是否有任何策略可以使这样的界面变得活泼?我的一个想法是考虑<canvas>,它可以快速绘制许多元素,但对于这项任务来说似乎不是很自然。

另一种选择是在滚动时使用fetch() 加载数据,但如果可能的话,我希望所有数据只加载一次。

我还应该考虑什么?

【问题讨论】:

  • 不是遍历 dom 节点的完整列表,而是过滤 item 中的位置并直接按索引修改那些 dom 节点。适用于您给出的示例,因为您只是在处理 Paris 条目。有很多无限滚动表库,使用起来非常简单,它们通常内置过滤和排序。有 15000 多个条目,无论您做什么,它都可能会很慢。
  • @user120242 我仍然很好奇这是否可以顺利更新 DOM。 21 世纪不能立即更新数千个简单的 DOM 节点,这有点令人失望。

标签: javascript css performance user-interface event-loop


【解决方案1】:

我建议使用类来表示是否应该显示或隐藏给定节点(例如,带有name !== 'Paris' 的每个节点都在notparis 类中。您可以使用javascript 来初始化这些类别(How do I add a class to a given element?)您获取 JSON 表,然后显示/隐藏可以使用 for (tr of document.getElementsByClassName('notparis')) tr.visible = !parisOnly。如果这些类别重叠(即您想要 notparis 和 notcoldweather),您可能会记录当前可见或隐藏的类并使用 document.getElementsByClassName('notparis notcoldweather')(这可能是有点复杂,但应该保持性能)。

此外,直接更改项目而不是使用中间列表可能会更高效。

【讨论】:

  • 我已经在使用 hidden 类并且直接使用 DOM 而不是纯数组实际上更慢。
  • @RoboRobok 这通常是正确的,但我认为在这种情况下,您可能使用与直接执行相同数量的 DOM 操作,但看看这个问题经过更多测试后,似乎没有办法避免暂停近一秒钟,因为您仍然必须隐藏/显示数千个元素,这可能在渲染层而不是底层数据操作处中断
  • 数据操作真的很快,15k的数组也不算大。瓶颈是 DOM 本身,操作起来超级慢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-17
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 1970-01-01
相关资源
最近更新 更多