-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
really try insertRule #157
Conversation
Hey @mattkrick! Thanks for putting the effort into making these changes. Before trying to polish up the code, I have some broad feedback that I think will help us get this landed:
So, if you could strip this down to the smallest diff that still demostrates what using |
@xymostech oh wow, i didn't actually think this would get considered for master 😋. Yeah, it'll require a lot of rewriting of tests & jsdocs. Happy to do it if it's actually gonna get merged, but writing tests for rejected PRs is no good. Any feedback you can give me before then? PS, any chance KA might adopt an |
@mattkrick I just landed the pull request to add an eslintrc, |
@mattkrick As for advice, if this fixes the problems in #147 then I'm really interested in it. So, test to make sure it acutally solves that problem before putting in the effort? |
@xymostech it definitely solves it locally on firefox, chrome, and opera (we could even remove the 'o' prefix check, that hasn't been used by opera in...years?). Haven't tried IE since I don't have a windows box, but I'm pretty sure the |
@xymostech what's your secret for getting 100% branch coverage? 🙈 |
@xymostech ready for your 👀 . I added the 4-space indent rule so i didn't have to manually fix up my stuff, it found some pre-existing stuff that wasn't compliant, hence the touches to webpack configs. |
@mattkrick hopefully I have time to try this branch again today. |
I'm a little confused by this. Why would there be a flicker on initial load? We could make one tag per font. Presumably you won't be using enough fonts to hit the IE10 limit.
Is this an assumption or is there proof? I suspect the browser might lag a little, but it won't show you invalid results. I'm not certain either way though. |
@jlfwong The initial flicker would be caused by a switch from the fallback font to the downloaded font (assuming it doesn't get flushed immediately).If you can flush immediately, you shouldn't get a flash. I'd also be very interested to hear from the folks who still see a flash after removing the fonts if this branch makes the flash go away entirely. TBH I thought a font that was inlined in base64 would be loaded in sync & wouldn't cause a flash, but it's still treated as a (cached) network request. You'd think the browser would create a checksum of the fetched file & compare it with the current... |
const prefixedProperty = `${prefix}${capitalProp}`; | ||
if (validProperties[prefixedProperty]) { | ||
// learn which styles the browser likes | ||
validProperties[validatedProp] = prefixedProperty; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validatedProp
is falsy here (most likely undefined
). Don't you want validProperties[property] == ...
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
digging in now, will have an answer in an hour or so...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's assume you have a rule like boxReflect
.
It first checks to see if the browser can handle that by looking up boxReflect
(Line 213).
If that doesn't work, then it tries all the prefixes. MozBoxReflect, webkitBoxReflect
, ah, found it!
We know that the browser doesn't support boxReflect
but it does support webkitBoxReflect
.
So now we add that to the validatedProperties table: {boxReflect: 'webkitBoxReflect'}
.
So the next time you look up boxReflect
(Line 213) you grab the prefixed version immediately without having to set up the for loop.
The time savings is minimal, but aphrodite's target is IE10, so we can't use a Set
, so we might as well make use of the object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that. But following the control flow of the code, at this line (223), the value of validatedProp
is falsy (an empty string (""
), zero (0), false
, undefined
or null
). Doing simple substitution, we arrive at either one of the following lines of code:
validProperties[undefined] = prefixedProperty;
validProperties[""] = prefixedProperty;
validProperties[0] = prefixedProperty;
validProperties[false] = prefixedProperty;
Is that really what you intended to do?
@mattkrick testing this branch on our app now |
@mattkrick I've tried using the newest commit of this branch (https://github.com/mattkrick/aphrodite/tarball/d131a02923e6daa62df223e77b791eecaca9e067) and ran |
@chendo i don't think you're referencing the branched version correctly. This PR doesn't do anything to the exports. For your convenience, try installing |
@mattkrick got it to work! Significantly decreased the amount of unstyled flicker we see, but we still see it occasionally in some scenarios. Thanks! |
@chendo in what scenario do you see a flicker still? |
@mattkrick EARLY Reads. |
@abhiaiyer91 you mean you have both aphrodite & my fork of it installed? |
This is exciting! I guess it'll have to be rebased ontop of the latest extension changes. I noticed Aphrodite was just bumped to 1.0.0. Will that slow down merging this feature? |
Sorry I haven't put time into reviewing this again, I've had other things on my plate. :( @yanivtal No, I just released 1.0.0 because we aren't really in an experimental state any more (we haven't been for a while actually, but better late than never?). If it's slow to get reviewed, it's just cause I'm slow! |
Cool, no problem. Just making sure since it seems like this'll help a lot with perf. Just out of curiosity, is there any discussion about chunking across style tags for more perf? Seems we still have a big hit on every insert rule unless I'm missing something. @mattkrick says the multiple tags are harder to debug but I'm not familiar with that problem. |
@mattkrick was this just waiting for Khan approval? |
Yup |
@mattkrick @xymostech Are we going to get this into master anytime soon? |
¯_(ツ)_/¯ At this point, I doubt it. FWIW, I use aphrodite-local-styles in production and it works great. Since I made this PR, Aphrodite now supports mixing global and local styles. I think that's dangerous, so I have no desire to keep my fork up to date with master when my version is more performant and disallows anti patterns. In the future, I'll shrink the client payload for mine and insert rules in sync so you don't have to use setTimeout hacks. If you'd like to take over getting this merged, feel free, but I'll close for now as it looks like my goals are no longer aligned with the project. |
Features:
Fix Support inlined fonts #156 by generating short, unique font namesSee Dont use src for font injection key fix #156 #158RemoveSee dont add 'px' suffix for 0 values #159px
from0
_because every byte counts_™I'm betting this is gonna be a hard sell, so here's the pitch:
inline-styles-prefixer
from the client build, saving ~3KBasap
since injections are so insanely cheap. This would solve Styles are injected after componentDidUpdate. #76 in the best way possible.How it works:
The buffer used to store an big glob of text comprised of many rules. Now, the buffer stores an array of rules + for each rule a boolean called
isDangerous
. If a rule is dangerous, we use a try/catch block, which means V8 will bail on that function and never try to optimize it. That's fine because the calling function is externalized and the only things that trigger a dangerous flag are the vendor-proprietary things that they don't list in their computedStyles:::-moz-placeholder, ::-moz-focus-inner
or already prefixed globals that user is manually trying to inject. Otherwise, we inject with confidence.We could whitelist these things, but by not using a whitelist, we save a little space in the payload. More importantly, we don't have to update the package whenever a browser vendor adds something. Also worth noting that the call is memoized so we only make 1 call to
window.getComputedStyles
and that array learns browser prefixes, so aphrodite gets (negligibly) faster the more you use it.By avoiding
prefixAll
, we only generate rules that the client can understand. This is great because it is faster (less to generate = less to inject), gets rid of prefix problems (#100), and opens up the door to more helpful debugging.Happy to answer questions. I know it's a big change, but for large apps, it's a necessary one. I know there are a few other folks like @abhiaiyer91 with large apps who have been struggling with the same performance bottlenecks, so I wanted to provide an option to stay competitive with JSS.