Knockout.js 视图中的复杂嵌套if/else导致性能问题

Knockout.js 视图中的复杂嵌套if/else导致性能问题,knockout.js,Knockout.js,我在foreach中的视图中有嵌套的if/else绑定,处理该绑定大约需要一秒钟。它在创建Dom时会阻止渲染。我计划在JavaScript中执行if/else条件,并将整个dom元素发送到预先准备好的视图中,以加快速度。然而,我是新手,所以不确定这是否是一个有效的方法,或者是否有更好的选择。下面的代码是有问题的代码,其中大部分数据被剥离以显示结构。在单独的a、li等中,是对DOM元素的单独绑定 <ul data-bind="foreach: categories; "> <!-

我在foreach中的视图中有嵌套的if/else绑定,处理该绑定大约需要一秒钟。它在创建Dom时会阻止渲染。我计划在JavaScript中执行if/else条件,并将整个dom元素发送到预先准备好的视图中,以加快速度。然而,我是新手,所以不确定这是否是一个有效的方法,或者是否有更好的选择。下面的代码是有问题的代码,其中大部分数据被剥离以显示结构。在单独的a、li等中,是对DOM元素的单独绑定

<ul data-bind="foreach: categories; ">
<!-- ko if: $data.childCategories -->

<!-- ko ifnot: $data.id == 'example' -->

<!-- ko if: $data.id == 'another-example' -->

<li data-bind="attr: {'data-children': childCategories}">
    <!-- ko if: $data.id.indexOf('link-') < 0 -->
        <!-- ko if: $data.childCategories -->
            <a>

            </a>
        <!-- /ko -->
        <!-- ko ifnot: $data.childCategories -->
            <a>

            </a>
        <!-- /ko -->
    <!-- /ko -->

    <!-- ko if: $data.id.indexOf('link-') >= 0 -->
        <!-- ko if: $data.longDescription.indexOf('http') >= 0 -->
            <!-- ko if: $data.childCategories -->
                <a></a>
            <!-- /ko -->
            <!-- ko ifnot: $data.childCategories -->
                <a></a>
            <!-- /ko -->
        <!-- /ko -->
        <!-- ko ifnot: $data.longDescription.indexOf('http') >= 0  -->
            <!-- ko if: $data.childCategories -->
                <a></a>
            <!-- /ko -->
            <!-- ko ifnot: $data.childCategories -->
                <a></a>
            <!-- /ko -->
        <!-- /ko -->
    <!-- /ko -->


    <ul data-bind="foreach: childCategories ">
        <li>
            <!-- ko if: $data.id.indexOf('link-') < 0 -->
                <a></a>
            <!-- /ko -->

            <!-- ko if: $data.id.indexOf('link-') >= 0 -->
                <!-- ko if: $data.longDescription.indexOf('http') >= 0 -->
                    <!-- ko if: $data.childCategories -->
                        <a></a>
                    <!-- /ko -->
                    <!-- ko ifnot: $data.childCategories -->
                        <a></a>
                    <!-- /ko -->
                <!-- /ko -->
                <!-- ko ifnot: $data.longDescription.indexOf('http') >= 0  -->
                    <!-- ko if: $data.childCategories -->
                        <a></a>
                    <!-- /ko -->
                    <!-- ko ifnot: $data.childCategories -->
                        <a></a>
                    <!-- /ko -->
                <!-- /ko -->
            <!-- /ko -->


            <!-- ko if: $data.childCategories -->
                <div>
                    <div>
                        <div>
                            <!-- ko if: $data.id.indexOf('link-') < 0 -->
                                <a></a>
                            <!-- /ko -->
                            <!-- ko if: $data.id.indexOf('link-') >= 0 -->
                                <!-- ko if: $data.longDescription.indexOf('http') >= 0 -->
                                    <a></a>
                                <!-- /ko -->
                                <!-- ko ifnot: $data.longDescription.indexOf('http') >= 0  -->
                                    <a></a>
                                <!-- /ko -->
                            <!-- /ko -->
                        </div>
                        <ul data-bind="foreach: $data.childCategories">
                            <li></li>
                        </ul>
                    </div>
                </div>
            <!-- /ko -->
        </li>
    </ul>
</li>
<!-- /ko -->

<!-- ko ifnot: $data.id == 'another-example' -->
<li data-bind="attr: {'data-children': childCategories}">
        <!-- ko if: $data.id.indexOf('link-') < 0 -->
            <!-- ko if: $data.childCategories -->
                <a>

                </a>
            <!-- /ko -->
            <!-- ko ifnot: $data.childCategories -->
                <a>

                </a>
            <!-- /ko -->
        <!-- /ko -->

        <!-- ko if: $data.id.indexOf('link-') >= 0 -->
            <!-- ko if: $data.longDescription.indexOf('http') >= 0 -->
                <!-- ko if: $data.childCategories -->
                    <a></a>
                <!-- /ko -->
                <!-- ko ifnot: $data.childCategories -->
                    <a></a>
                <!-- /ko -->
            <!-- /ko -->
            <!-- ko ifnot: $data.longDescription.indexOf('http') >= 0  -->
                <!-- ko if: $data.childCategories -->
                    <a></a>
                <!-- /ko -->
                <!-- ko ifnot: $data.childCategories -->
                    <a></a>
                <!-- /ko -->
            <!-- /ko -->
        <!-- /ko -->




            <!-- ko if: $data.childCategories -->
            <div>
                    <div>
                        <div>
                            <!-- ko if: $data.id.indexOf('link-') < 0 -->
                                <a></a>
                            <!-- /ko -->
                            <!-- ko if: $data.id.indexOf('link-') >= 0 -->
                                <!-- ko if: $data.longDescription.indexOf('http') >= 0 -->
                                    <a></a>
                                <!-- /ko -->
                                <!-- ko ifnot: $data.longDescription.indexOf('http') >= 0  -->
                                    <a></a>
                                <!-- /ko -->
                            <!-- /ko -->
                        </div>
                        <ul data-bind="foreach: $data.childCategories">
                            <li></li>
                        </ul>
                    </div>
                </div>
            <!-- /ko -->









    </li>
<!-- /ko -->


<!-- /ko -->




<!-- /ko -->


<!-- ko ifnot: $data.childCategories -->

    <!-- ko if: $data.id.indexOf('link-') < 0 -->
        <li>
            <a>
            </a>
        </li>
    <!-- /ko -->
    <!-- ko if: $data.id.indexOf('link-') >= 0 -->
        <li></li>
    <!-- /ko -->
<!-- /ko -->

您是否尝试在ObservalArray()上放置延迟更新扩展?通过这种方式,一切都是异步的,主要是在任何ui(重新)绘制之前

有关更多信息,请参阅:

或者,在准备数据时还有另一个小技巧,如果您已经在处理ObservalArray()并在更新绑定的子Observales时进行迭代,等等,有很多来回的通知,那么使用简单的js对象有时会更容易,然后把所有的变化一次推回到可观察的范围,就像这样

var items = ko.observableArray();
//do something with the items here
items.push.apply(items, [1, 2, 3, 4]);
这样做可能有助于将if-then-else检查设置为数组中每个项目的bool,在ui呈现将其排序并移动到代码中时提升检查。。只是一个建议。 无论哪种方式,knockout都应该能够处理很多if-then-else条件,而不必在ui中查看太多问题,大多数情况下,您可以通过重新考虑如何使用可观察对象(ab)来加快速度


我研究过一些控件,这些控件包含来自api和observableArray的20k+项,过滤出条件子集,并在几毫秒内将它们显示在网页上,带有模板和if-then条件。(是的,我知道正确使用有点过分,但这不是重点)

你目前的观点是什么?也许有更好的方法,但我们需要先看看你有什么。我无法发布代码,但我可以更详细地介绍它是如何构造的。我们检索一个JSON对象,该对象包含其他对象的数组,而这些对象又有更多嵌套数组,只有几层深。这定义了产品目录类别的结构。现在构建的视图在顶级对象上有一个foreach,并且有多个级别的if/else和数据绑定。渲染块,你可以看到多个布局/绘制发生。如果这没有帮助,我可以在这里发布一个精简版本来帮助说明问题。我已经添加了一个精简版本的结构看起来像什么。谢谢我昨天尝试了延迟的,对我来说没有明显的改进。我会尝试一下你建议的另一种方法。如果没有帮助的话,你应该试着把你想要实现的东西放在一个非常基本的JSF中间,如果不看你实际做的事情,我们可能完全不知道还有其他的东西。当然。今天下午我会把一些东西放在一起。我添加了一个结构外观的精简版本
var items = ko.observableArray();
//do something with the items here
items.push.apply(items, [1, 2, 3, 4]);