2016-11-28 2 views
1

Я использовал getBoundingClientRect() в своем приложении, чтобы получить размеры элемента, когда пользователь перетаскивает элемент вокруг. Я использую это, и он работает хорошо; однако я начинаю получать серьезные проблемы с производительностью, пока этот расчет выполняется во время перемещения мыши. Это становится еще хуже, чем больше узел, который перемещается. Я использовал инструменты профилирования в Chrome и заметил, что эта функция, будучи обернутой в событие перемещения мыши, которое запускается во время перетаскивания пользователем, занимает много времени (31,4 мс на один звонок - масштаб, который называется каждым во время перемещения мыши.) Изучая проблему, я наткнулся на других, кто ее использовал, и заметил проблемы с производительностью (http://dcousineau.com/blog/2013/09/03/high-performance-js-tip/).Vanilla JS Альтернативы element.getBoundingClientRect()

Каковы мои альтернативы getBoundingClientRect() в ваниле Javascript (абсолютно нет jQuery)? Моя внешняя структура - AngularJS 1.5.8, и я разработал приложение, используя компоненты (смотря на то, чтобы в будущем перенести наше большое приложение на NG2). Благодаря!

+0

получить начальное положение элемента на начальном щелчке, нет необходимости пересчитывать его на каждом движении мышей –

+0

Не могли бы вы разместить минимальный код для игры? –

+2

Как сказал Карл в своем ответе, он не получает «больше» ванили. Конечно, если вам нужны только некоторые из значений, вы можете запросить отдельные свойства, которые их удерживают, но это вряд ли будет намного быстрее. Таким образом, ваш единственный способ повысить производительность может заключаться в том, чтобы запрашивать значения реже. Посмотрите на debouncing/throttling. https://css-tricks.com/the-difference-between-throttling-and-debouncing/, https://css-tricks.com/debouncing-throttling-explained-examples/ – CBroe

ответ

2

Element.getBoundingClientRect() «ваниль», хотя это часть спецификации working draft. Чтобы сделать ваш код более эффективным, ограничьте количество вызовов. Ссылка, на которую вы ссылались, которая упоминает аналогичную производительность, говорит только о том, что:

Все вызовы для получения любого вычисленного измерения из DOM следует кэшировать или избегать.

+0

Право. Поэтому мой вопрос: «Каковы альтернативы (есть альтернативы)» для использования getBoundingClientRect()? Я понимаю, что это ваниль, мой вопрос: «Каковы альтернативы IN vanilla»? Ключевая цитата из статьи, на которую я смотрю, будет такой: «Проблема заключается в том, что WebKit любит пересчитывать макет дома почти каждый раз, когда вы используете нечто похожее на getBoundingClientRect». Итак, что можно сделать, чтобы WebKit не пересчитал макет dom, пока gettin данные getBoundingClientRect предоставляет? – JRAnderson

+0

Вы можете использовать 'getBoundingClientRect()', и вы должны - если это применимо. Если бы вы могли предоставить некоторый пример кода, мы могли бы помочь вам в решении конкретных проблем с производительностью. –

0

!! После решения не работает в сочетании с CSS3 масштабом преобразования но это альтернатива:

function getPosition(elm) { 
    var xPos = 0, yPos = 0; 

    while(elm) { 
    xPos += (elm.offsetLeft - elm.scrollLeft + elm.clientLeft); 
    yPos += (elm.offsetTop - elm.scrollTop + elm.clientTop); 
    elm = elm.offsetParent; 
    } 

    return { x: xPos, y: yPos }; 
} 

Source

+1

Это не работает, если есть масштабное преобразование CSS3. –

+0

Спасибо @QuentinEngles, обновил свой ответ – tdhulster

+0

Я искал способ вернуться к getBoundingClientRect, но нет простого способа, который хорошо работает, чтобы увидеть, был ли элемент преобразован. Там getComputedStyle, но это так же медленно (возможно, медленнее), как getBoundingClientRect. Должно быть свойство 'element.transformed' или что-то еще. –