#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 очень маловероятны. Любой хэш всегда будет иметь коллизии.