Каков наилучший (эффективный) способ получить хэш или уникальный ключ для набора свойств и значений в JavaScript?

#javascript #optimization

Вопрос:

Я хочу сгенерировать имя класса элемента DOM на основе статически определенных стилей, которые он имеет (в моей среде). В принципе, допустим, есть 10 000 виртуальных элементов. Каждый виртуальный элемент имеет 10 «статических» атрибутов стиля CSS, а также 5-10 «динамических» атрибутов стиля. Под «статическим» я подразумеваю, что оно жестко запрограммировано для фиксированного, неизменяемого значения, а под динамическим я подразумеваю, что значение может измениться, например, из-за привязки к значению некоторой переменной.

Теперь, с точки зрения оптимизации / теории, статические атрибуты стиля CSS не нужно записывать в style объект собственного (невиртуального) элемента, вместо этого все они могут быть сгруппированы и помещены в класс CSS. Таким образом, мы можем просто присвоить элементу класс, и стили будут применены автоматически. Но динамические атрибуты стиля CSS должны быть установлены непосредственно для элемента like el.style[name] = value .

Итак, все, что нам нужно сделать, чтобы это произошло, это взять все статически определенные атрибуты CSS и сгенерировать для него уникальное имя класса. Один из наивных способов сделать это — просто сделать это:

 let hashId = 1
const stylesCache = {}

console.log(generateHash({ color: 'red' }))
console.log(generateHash({ color: 'red' }))
console.log(generateHash({ color: 'blue', fontFamily: 'Arial' }))
console.log(generateHash({ color: 'blue' }))

function generateHash(staticStyleAttributes) {
  const array = []
  Object.keys(staticStyleAttributes).sort().forEach(name => {
    const value = staticStyleAttributes[name]
    array.push(`${name}=${value}`)
  })
  const string = array.join(';')
  const id = stylesCache[string] = stylesCache[string] || hashId  
  return `myClassName-${id}`
} 

Но я не уверен, что это лучшее использование объекта в качестве хэш-таблицы, потому что строки атрибутов стиля могут быть потенциально довольно длинными (более 500 символов).). Есть ли лучший способ добиться этого? Возможно, что-то более элегантное? Или хитрый, но эффективный?

Можно ли использовать сгенерированный стиль string и запустить над ним какую-либо хеш-функцию, которая была бы эффективной и простой? Таким образом, он дает уникальные значения в зависимости от ввода, а также работает быстро? Это не обязательно должно быть безопасным.

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

Комментарии:

1. Строка из 500 символов — это ничто. Кроме того, он по-прежнему линейно масштабируется в зависимости от размера сгенерированных правил CSS, так что беспокоиться не о чем. Но если вы не хотите использовать карту (или объект) и счетчик, конечно, просто примените к нему какую-нибудь строковую хэш-функцию.

2. @Bergi как насчет столкновений ? Я никогда не хочу сталкиваться с конфликтами. Например, я выбираю MD5, но, похоже, существует вероятность коллизий. Можете ли вы порекомендовать что-то, что работает? В идеале простой, быстрый, небольшой объем кода, но не обязательно все это.

3. Столкновения MD5 очень маловероятны. Любой хэш всегда будет иметь коллизии.