Conversation
src/exports.js
Outdated
| return [key, { | ||
| // TODO(gil): Further minify the -O_o--combined hashes | ||
| _name: process.env.NODE_ENV === 'production' ? | ||
| `_${hashObject(val)}` : `${key}_${hashObject(val)}`, |
There was a problem hiding this comment.
Since this is going to be joined and hashed again, we can probably remove the leading underscore here now, right?
|
ping @lencioni addressed your comment and added other improvements |
|
ping @xymostech |
xymostech
left a comment
There was a problem hiding this comment.
Like @jlfwong mentioned in this comment: #246 (comment) we maybe want to be generating longer hashes now that we're combining class names, since we're increasing the risk of collisions. Unfortunately, it looks like the library we're using for hashing doesn't support generating longer hashes... Hmm. Does anyone have insight into how we might do that in a good way?
src/util.js
Outdated
| // can probably depend on this too. | ||
| export const hashObject = (object /* : ObjectMap */) /* : string */ => stringHash(JSON.stringify(object)).toString(36); | ||
|
|
||
| export const hashString = (string /* : string */) /* string */ => stringHash(string).toString(36); |
There was a problem hiding this comment.
Could you maybe add a quick docstring here, and maybe use this function inside of hashObject so it's clear that they're supposed to be using the same hash algorithm?
|
If you need more than 32 bits of hash, you're kinda stuck, since js doesn't provide 64-bit integer types. You could go back to using a google hash: https://github.com/lovell/farmhash e.g. It has fingerprint64() which gives you a 64-bit hash (as a string), and is platform independent. I don't know how fast it is, though. Your only other solution would be to generate two separate 32-bit hashes and concatenate them. The most straightforward way to do this, if you're always hashing the same kind of object, is to add a 'salt' field to the object, and hash it once with salt=1 and a second time with salt=2 (or whatever). Of course, this will double your hashing time. farmhash is probably faster. :-) |
|
(Blah, maybe not possible -- it looks like farmhash is node-specific, and just a wrapper around some C code.) |
src/inject.js
Outdated
| if (process.env.NODE_ENV === 'production') { | ||
| className = processedStyleDefinitions.classNameBits.length === 1 ? | ||
| `_${processedStyleDefinitions.classNameBits[0]}` : | ||
| `_${hashString(processedStyleDefinitions.classNameBits.join())}`; |
There was a problem hiding this comment.
What if we append processedStyleDefinitions.classNameBits.length? That would help reduce the likelihood of collisions.
…ngthHash to add extra hash bit in prod
|
ping @xymostech @lencioni |
lencioni
left a comment
There was a problem hiding this comment.
This seems good to me, but it looks like CI is red.
@xymostech what do you think?
| }; | ||
|
|
||
| // Sum up the lengths of the stringified style definitions (which was saved as _len property) | ||
| // and use modulus to return a single byte hash value. |
There was a problem hiding this comment.
This comment would be 💯 if it explained why we are adding the length to the hash.
| let className; | ||
| if (process.env.NODE_ENV === 'production') { | ||
| className = processedStyleDefinitions.classNameBits.length === 1 ? | ||
| `_${processedStyleDefinitions.classNameBits[0]}` : |
There was a problem hiding this comment.
should we maybe be adding the length of the style definitions when there's only one class name, too? If only to make the hashes the same size/consistent?
There was a problem hiding this comment.
I'm not sure what the advantage of that would be. Also, before this PR the hashes were different lengths--for example, from our homepage:
image_ay4wjb-o_O-background_1h6n1zu-o_O-fadeIn_3jddj2-o_O-backgroundSize_cover_176vplr
--so I imagine they still won't be the same size.
There was a problem hiding this comment.
oh, the other thing is that we'd be hashing a hash unnecessarily. is the additional expense justified?
There was a problem hiding this comment.
We wouldn't be hashing anything new, just adding the extra length char on, right? You're right though, this probably isn't important. :)
There was a problem hiding this comment.
oh, you're right double-hashing shouldn't be a thing
|
I think the travis failing was a fluke, I restarted it |
|
Okay, I'm gonna merge this! Sorry for the delay! Maybe once this lands, @lencioni or I could try updating aphrodite on our sites and see if anything breaks and how much smaller the styles get. |
|
That sounds good. I actually work with @gilbox so I'll let him do the honors on our site and report back here with anything interesting. 💃 |
|
Oh ha, I didn't realize! Sounds wonderful :) |
|
@xymostech could we get a release please 🙏 |
|
@gilbox Did you test things out on your site? I can make a release but I'd love for someone to do some real testing to make sure this doesn't horribly break things... |
|
ah ok I didn't realize that's what you meant. I'll give it a whirl |
Fixes regression introduced by Khan#248
|
I tested with #263, should be good to publish a new version |
|
ping @xymostech for the new version |
Hashes the combined class name to create a minified combined class name.
@lencioni
@xymostech
@jlfwong