Как предотвратить / минимизировать перерасходы для этого примера d3? - PullRequest
2 голосов
/ 27 сентября 2019

У меня есть следующая логика d3 для рендеринга отдельных объектов:

svg.selectAll("path")
    .data(hugePathDataset)
    .enter().append("path")
    .attr("class", (d) => d.properties.cls )
    .attr("id", (d) => d.properties.name )
    .each(... canvas render logic ...)

По соображениям производительности, элемент svg выше установлен в display: none, реальный рендеринг происходит на холсте через d3Проекционная логика.Однако элемент svg по-прежнему необходим для более поздних обновлений холста (например, для изменения цвета каждого пути отдельно).

Мой набор данных содержит более 60000 путей, а выполнение кода выше занимает около 30 секунд.Тестируя его в профилировщике Chrome, я заметил, что 90% этого времени уходит на оплавление.Для меня это не имело никакого смысла, поскольку canvas не перекомпоновывается, а SVG с display: none не должен перекомпоновывать DOM.Продолжая изучать этот вопрос, я понял, что перекомпоновка запускается не путем добавления элементов к невидимым SVG, а путем установки атрибутов class и id для этих элементов.Конечно, если я уберу строки 4 и 5, замедление оплавления полностью исчезнет.Установка других атрибутов (т. Е. data-something) не вызывает замедления / перекомпоновки.

Проблема в том, что я не могу впоследствии управлять этими путями по отдельности, как описано выше.Мои вопросы:

  • Почему добавление class или id к элементу с родительским элементом, установленным в display: none, вызывает перекомпоновку?
  • Как обойти это?Как я могу получить эти свойства без замедления?

1 Ответ

2 голосов
/ 27 сентября 2019

Чтение документации D3 Я понял, что selection.append("path") эквивалентно selection.append(() => document.createElement("path")).Поскольку document.createElement еще не присоединяет элемент к DOM, можно безопасно устанавливать свойства для него без перекомпоновки.Я переписал вышеупомянутую логику по-другому, и проблема исчезла:

svg.selectAll("path")
    .data(hugePathDataset)
    .enter().append((d) => {
        let element = document.createElement("path");
        element.id = d.properties.name;
        element.className = d.properties.cls;
        return element;
    })
    .each(... canvas render logic ...)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...