I want to generate a DOM element class name based on the statically defined styles it has (in my framework). Basically, let's say there are 10,000 virtual elements. Each virtual element has 10 "static" CSS style attributes, as well as 5-10 "dynamic" style attributes. By "static" I mean that it is hardcoded to a fixed, unchanging value, and by dynamic I mean the value could change by being bound to the value of some variable, for example.
Now, in terms of optimization/theory, static CSS style attributes don't need to be written onto the style object of a native (non-virtual) element, they can instead all be grouped and put under a CSS class. This way we can just give the element a class and the styles get automatically applied. But the dynamic CSS style attributes must be set directly on the element like el.style[name] = value.
So all we need to do to make this happen is take all the statically defined CSS attributes and generate a unique class name for it. One naive way to do that is just do this:
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}`
}
But I'm not sure this is the best use of the object as a hash table, because the strings of the style attributes can get potentially pretty long (over 500 characters). Is there any better way to accomplish this? Something more elegant perhaps? Or tricky yet efficient?
Is it possible to take the generated style string, and run a hash function of some sort over it that is both efficient and simple? So it gives unique values depending on input, and also is fast? It doesn't need to be secure.
Using a hash function, too, we wouldn't need to store potentially hundreds of long key strings in a hash table, it would just be computed on the fly. So we skimp a little on memory too.