【问题标题】:Backbone (client-side) filter performance problems within collection集合中的骨干(客户端)过滤器性能问题
【发布时间】:2013-03-19 10:04:14
【问题描述】:

我正在从服务器的主干集合中加载一些初始数据。 我设置了一个搜索输入,该输入会触发对服务器的 AJAX 调用,并在每次键入时返回解析的 JSON。

我希望仅在客户端进行搜索。到目前为止,我已经设置了这段代码(该函数发生在 #search 输入中的 keyup 上):

tod​​os 是一个骨干.marionette 集合

$('.content-search').on('keyup', '#search', function(e){
    e.preventDefault();
    var search = $('#search').val().toLowerCase();
    todos.update(initialData.todos);
    var json = todos.toJSON();
    var filteredJSON = filterJSON(json, search);
    dcis.update(filteredJSON);
}

function filterJSON(arr, part) {
    return arr.filter(function(obj) {
        return Object.keys(obj)
            .some(function(k) {
                console.log(obj[k]);
                if(typeof(obj[k]) == 'string'){
                    return obj[k].toLowerCase().indexOf(part) !== -1;
                }
            });
    });
};

速度太慢了。使用 AJAX 调用调用服务器实际上比使用过滤客户端更快!

任何想法为什么我的代码这么慢? JSON 相当大(500 多个条目)

【问题讨论】:

  • 我会尝试不使用任何下划线功能进行过滤和循环,因为每个功能都需要调用函数(只需使用 for 循环)。您可能需要通过将文本小写一次而不是每次需要搜索来优化文本搜索。
  • 您可能只是将console.log 包含在您自己的测试中,但如果大量调用它会降低整体性能。此外,使用不区分大小写的 RegEx 可能比循环中的 toLowerCasing() 和索引检查更快。

标签: json backbone.js filtering marionette


【解决方案1】:

即使有 500 个条目,我也保证大部分工作都不是过滤 JSON。它在浏览器的渲染/绘制周期中,除非您手动更新 DOM 而不是使用主干渲染功能。

尝试首先在调用 filterJSON 的行上方设置 console.time('filterMyCollection')。之后是console.timeEnd('filterMyCollection')

然后做同样的事情,但在主干渲染函数的第一行和 timeEnd 作为最后一行。

如果您要销毁和重新创建一个占用大量内存、CPU 和垃圾收集时间的模板。如果你需要帮助来显示很多元素,你应该看看它是如何在 PerfView (https://github.com/puppybits/BackboneJS-PerfView) 中完成的。它能够以 120FPS 的速度在 Chrome 中滚动浏览 1,000,000 个模型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多