Knockout.js использует слишком много памяти - PullRequest
5 голосов
/ 28 июня 2011

Я держу Process Explorer открытым и проверяю столбец «Private Bytes» процесса firefox.exe. После нажатия кнопки «Добавить» в этом примере:

<script id="tmplComment" type="text/x-jquery-tmpl">
    <div>
        <span>Comment:&nbsp;</span>
        <span data-bind="text: $data"></span>
    </div>
</script>    

<input type="button" id="btnAdd" value="Add"/>
<div id="Content" data-bind="template: {name: 'tmplComment', foreach: Comments}">        
</div>

С этим кодом:

var vm = {Comments: ko.observableArray(["a", "b"])};
ko.applyBindings(vm);
$("#btnAdd").click(function()
{
    for(var i = 0; i<500; i++)
        vm.Comments.push(i.toString());
});

(также см. this jsfiddle )

Я обнаружил, что объем приватных байтов, занятых Firefox, увеличился примерно на 50-100 МБайт.

Время выполнения также довольно велико, когда я сравниваю его с реализациями, в которых отсутствует отслеживание зависимостей, учитывая следующий пример:

<script id="tmplComment" type="text/x-jquery-tmpl">
    <div>
        <span>Comment:&nbsp;</span>
        <span data-bind="text: $data"></span>
    </div>
</script>    

<input type="button" id="btnAdd" value="Add"/>
<div id="Content" data-bind="template: {name: 'tmplComment', foreach: Comments}">        
</div>

С этим кодом:

var vm = {Comments: ko.observableArray(["a", "b"])};
ko.applyBindings(vm);
$("#btnAdd").click(function()
{
    for(var i = 0; i<500; i++)
        vm.Comments.push(i.toString());
});

(см. Также this jsfiddle )

Мой вопрос: при использовании Knockout.js присуща низкая производительность или я что-то не так делаю?

Ответы [ 2 ]

7 голосов
/ 28 июня 2011

Если на мгновение оставить проблему с памятью, большую часть времени в вашем текущем примере будет потрачено в опции foreach привязки шаблона.Он проделал довольно большую работу, чтобы определить, какие элементы в массиве были изменены, чтобы определить, как эффективно добавлять / удалять элементы из DOM.В вашем случае эта работа выполняется 500 раз.

Вы можете повысить производительность, написав ее следующим образом:

$("#btnAdd").click(function()
{
    var items = vm.Comments();
    for(var i = 0; i<500; i++) {
         items.push(i.toString());
    }

    vm.Comments.valueHasMutated();
});

Это просто помещает элементы в базовый массив, не уведомляя подписчиков.до конца (вызов push для observableArray приведет к перемещению элемента в базовый массив и вызову valueHasMutated).

Использование памяти в исходном образце кажется необычно высоким.Я думаю, что в логике foreach могут быть некоторые возможные оптимизации, которые могли бы помочь, но это потребует / потребует немного больше исследований.

0 голосов
/ 22 марта 2012

RP правильно.посмотрите: http://jsfiddle.net/uLkDP/32/

Другой и очень похожий подход:

$("#btnAdd").click(function()
{
    var a = ["a", "b"];
    for(var i = 0; i<500; i++)
        a.push(i);

    vm.Comments(a);
});

пример работы: http://jsfiddle.net/uLkDP/30/

О, еще одна вещь, яиспользовал процесс хакера и следил за использованием памяти в Google Chrome.Подход RP добавил примерно 4 МБ, в то время как другой прибавил примерно 8 МБ.это имеет смысл, поскольку второй подход использует два массива.

...