Я знаю, что плохо хранить данные в DOM, но почему?
Я снова и снова слышал, что плохо использовать практику DOM в качестве базы данных.
В то время как я в основном согласен с этим настроем, этот вопрос больше касается менее черно-белых случаев. Помня о последних версиях методов jQuery .data()
и спецификации атрибутов данных HTML5, действительно ли так плохо хранить некоторые данные в DOM для удобства?
Например, недавно я реализовал функцию "живого" вычисления в таблице с полными вводами, выполнив что-то вроде этого:
<table>
<tr>
<td><input type="text"></td>
</tr>
<tr>
<td><input type="text"></td>
</tr>
</table>
JQuery
$('table').bind('calculate',function(){
var total = 0;
$(this).find('tr').each(function(){
total += $(this).data('value');
});
// display total
});
$('table input').bind('change keyup',function(){
$(this).closest('tr').data('value',$(this).val());
$(this).closest('table').trigger('calculate');
});
Это упрощённый пример, потому что я мог пропустить вызовы до .data()
и перейти прямо к входным значениям, но представьте себе более сложный сценарий, в котором элементы, отличные от входов, влияют на значения строк.
Неправильно ли использовать DOM для хранения простых данных в такой ситуации?
Ответы
Ответ 1
Прекрасно хранить данные в объектах DOM. И поскольку ваш вопрос специфичен для API данных jQuery, важно понять, как работает API data
. Я написал ответ , объясняющий его внутренние действия некоторое время назад. API данных только сохраняет ссылку на объекты DOM вместе с данными и не хранит ничего внутри самих объектов DOM. Все данные хранятся в простых старых JavaScript-объектах.
Вопрос о том, является ли это хорошим или плохим подходом, является вопросом личного вкуса. Джон Ресиг, создатель jQuery, рассказал о Tech4Africa в 2010 году, где рассказывает об этой точной проблеме, и предлагает отказаться от отдельной области хранения и связать все с DOM с помощью API данных. Вы можете поговорить на YouTube (благодаря @tine2k для предоставления ссылки). Если вы послушаете весь разговор, вы найдете несколько хороших примеров того, почему этот подход имеет смысл и делает вещи простыми.
Я считаю, что аналогичные аргументы могут быть сделаны для другого конца спектра - чтобы ваши данные аккуратно спрятали объекты и классы и были отделены от самого представления. Такое мышление происходит от традиционных архитектур, таких как MVC.
Я говорю, что нужно идти с любым подходом - используя DOM для хранения данных или с использованием классического подхода. Просто не смешивайте их, потому что повсюду посыпается модель приложения.
Ответ 2
Существуют некоторые фундаментальные аргументы против использования DOM для хранения данных:
-
Предполагается, что DOM является представлением данных. Свойства элементов DOM должны быть метаданные для самих элементов, а не данных из модели.
-
Вам не следует добавлять случайные свойства для размещения объектов, так как вы не представляете, что они могут с ними делать.
-
У вас есть такая же проблема, как и глобальные переменные. Если это станет обычной практикой, вам придется принять схему, чтобы избежать столкновений имен.
Существует также аргумент, что DOM - довольно обычное хранилище данных, и что структура объекта с индексами будет намного более эффективной для чего угодно, кроме как тривиальных данных.
Если у вас есть только небольшие объемы данных и у вас есть полный контроль над вашими страницами, тогда перейдите и поместите данные в атрибуты и свойства данных. Но не храните большие куски или сложные структуры.
О, и я не думаю, что есть какие-либо проблемы с производительностью - доступ к элементу и его свойствам в DOM, вероятно, не быстрее или медленнее, чем доступ к какой-либо части структуры объекта, хотя я уверен, что есть быстрее и более медленные способы выполнения обоих.
Ответ 3
Я не думаю, что что-то не так с хранением данных в DOM, но я думаю, что проблема заключается в хранении большого количества данных в DOM. Браузеру приходится путаться через DOM, чтобы выводить страницы, которые мы видим, и чем больше данных в нем больше, тем больше он должен разбираться.
Я уверен, что есть и другие причины, это всего лишь мой вывод.
Ответ 4
Разработав несколько одностраничных приложений для устройств CE, которые имеют ограниченную мощность браузера, я принял несколько дополнительных личных стандартов об этих вещах. Главное, что только потому, что JQuery поддерживает сканирование через DOM, что не предполагает его как подход к работе. Если мне нужно знать, какой из LI имеет фокус, я мог бы использовать .index() или .find() или даже .each(), но сохранение этого значения в отдельном объекте модели лучше по следующим причинам:
- MVC - это настоящая вещь, несмотря на безудержное злоупотребление, делая такие вещи, как использование DOM в качестве государственного держателя. Сохранение состояния в модели, как правило, делает MVC понятным.
- Сканирование через теги LI более дорогое, чем использование listItems.focussed в коде.
- DOM занят манипуляцией, и ваши запросы на него могут задерживаться или вызывать задержки.
Согласно Matt @https://github.com/Matt-Esch/virtual-dom,
"Чтение некоторых свойств DOM node даже вызывает побочные эффекты". Я склонен согласиться с этим моментом, но я признаю, что нахожусь в поиске дополнительных доказательств в этот момент, поскольку парень, которого преследуют наши самые большие проблемы с производительностью приложений, которые я лично убежден, в основном связаны с DOM-зависимым кодом.