Binding.scala: стратегия, позволяющая избежать слишком большого количества обновлений доменного дерева

В моем проекте scala-адаптеры я отображаю записи журнала, которые отправляются через веб-сокет.

Поскольку я не контролирую, сколько записей отправлено, я ищу стратегию, чтобы экран не зависал.

Я создал ScalaFiddle для имитации этого: https://scalafiddle.io/sf/kzr28tq/2

Эта функция с этими параметрами отлично работает:

setInterval(1000) { // note the absence of () =>
  entries.value += (0 to 100).map(_.toString).mkString("")
}

Если интервал становится меньше, а строка длиннее - экран зависает, например, с помощью:

setInterval(100) { // note the absence of () =>
  entries.value += (0 to 10000).map(_.toString).mkString("")
}

Есть ли решение, чтобы решить это на стороне клиента - или я должен решить это на стороне сервера?

1 ответ

Решение

Ты можешь попробовать:

@dom
def render = {
  <div>
  {
    for (entry <- entries) yield {
      entryDiv(entry).bind
    }
  }
  </div>
}

Проблема в том, что вы связываете записи слишком рано. Binding.scala делает свое волшебство с помощью преобразования CPS, каждый .bind вызывает переоценку всего кода после, поэтому вам следует связать переменную как можно позже.

И для Vars, используйте для понимания вместо связывания напрямую, чтобы избежать обновления всего списка. Когда вы используете += изменить содержание Vars, Binding.scala "исправляет" список внутренне, но если вы делаете .bind на Vars Например, чтобы получить весь список, фреймворк не может выполнить какую-либо оптимизацию для вас.

Вот обновленная ScalaFiddle: https://scalafiddle.io/sf/kzr28tq/3

Другие вопросы по тегам