-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
implement implicit element folding, "as" polymorphic prop #1962
Conversation
This is basically a reimplementation of the extend API, but implicitly. Folds attrs, styles, and target up so only one component is mounted but all the styles are preserved.
This eliminates the need for the withComponent API by allowing the underlying component that is mounted to be switched out dynamically at runtime, with no changes to the attributed styles.
src/models/StyledComponent.js
Outdated
@@ -219,6 +219,8 @@ export default (ComponentStyle: Function) => { | |||
options: Object, | |||
rules: RuleSet | |||
) { | |||
const targetIsSC = isStyledComponent(target) |
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.
nit: Shall we improve the variable name here? e.g. isTargetStyledComp
or sth?
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.
Yeah makes sense
src/models/StyledComponent.js
Outdated
|
||
// fold the underlying StyledComponent attrs up (implicit extend) | ||
// $FlowFixMe | ||
if (targetIsSC && target.attrs) finalAttrs = { ...target.attrs, ...attrs } |
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'm starting to think it'd make sense to abstract attrs
into a shareable set of utilities or sth... Maybe a future thing.
nit: Btw, I don't think having the let
s here makes sense since a ternary would also do the trick and would imply that it won't change later in this fn
src/models/StyledComponent.js
Outdated
targetIsSC | ||
? // fold the underlying StyledComponent rules up (implicit extend) | ||
// $FlowFixMe | ||
target.componentStyle.rules.concat(rules) |
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.
Should this be moved to the ComponentStyle
constructor itself? i.e.
new ComponentStyle(rules, attrs, id, child)
where the child is another ComponentStyle
; This would also move the attrs
merging, I guess? Not quite sure why we don't move the bulk of buildExecutionContext
there anyway.
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.
Could go either way. Currently ComponentStyle isn't concerned with folding which I think is probably a good thing to separate concerns?
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.
Yea, I was thinking of a "combined" refactor of StyledComponent and ComponentStyle, but that can certainly wait 👍
@@ -271,6 +293,7 @@ export default (ComponentStyle: Function) => { | |||
|
|||
const newOptions = { |
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 think we might not need this anymore, i.e. we can avoid options
altogether.
attrs
is called before the StyledComponent is created (tagged template literal call) and never againwithConfig
is called before as wellextend
will gowithComponent
will go
So any "cloning" is gone
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 wait to refactor this out for v5 when withComponent is gone?
Hi! In v3 I can optimize heavy components by extracting dynamic styles to a separated styled``.
In the current version |
The main change in v4 is the styles of |
@probablyup it will be applied, but also all styles will be reapplied and it can be extremely slow in comparison with current v3 behavior. |
It all happens in one go. It’s not slow, we test thoroughly.
…On Thu, Sep 6, 2018 at 9:04 AM Anton ***@***.***> wrote:
@probablyup <https://github.com/probablyup> it will be applied, but also
all styles will be reapplied and it can be extremely slow in comparison
with current v3 behavior.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1962 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAiy1kM4eQ258kMCFXA-JBgXX-P8zib9ks5uYSt5gaJpZM4WVna5>
.
|
@probablyup what happens in one go? I don't mean an initial render, I speak about dynamic styles. If I later change |
No, |
@mxstbr but all it styles will be recomputed. After changing just one prop you need to process all styles of DynamicStyledLink and StaticStyledLink, instead of processing just DynamicStyledLink styles. |
No we don't since we know |
@mxstbr for |
Yeah, |
@mxstbr but now it's possible to reduce the number of styles which will be recomputed by splitting component into two (or more) components: one with static styles (and it will be never recomputed after initial render) and one with interpolated styles. v4, on the other hand, will optimize this two components by merging into one. |
@Anber now I understand what you're saying, and I'm happy to say you're way overthinking this: it doesn't matter. Here's what conceptually happened before before: // This CSS is static and will never be recomputed
const staticLinkStyles = css`
color: blue;
background: red;
`
// This CSS is recomputed every render
const dynamicLinkStyles = css`
color: ${props => props.color};
`; Here's what conceptually happens after: // This CSS is static and will never be recomputed
const staticLinkStyles = css`
color: blue;
background: red;
`
// This CSS is recomputed every render
const dynamicLinkStyles = css`
color: blue;
background: red;
color: ${props => props.color};
`; Sure, a couple extra rules are re-parsed on every render but our parser is so fast it basically doesn't matter. If you're parsing anyway, parsing 5 extra lines is ~0 overhead. |
@mxstbr if the new parser in v4 is as fast as you say it will be great, but in v3 the trick with component splitting makes sense because render of a complex component with hundred lines of styles takes a noticeable period of time. |
@Anber do you have a benchmark showing the parser to be the bottleneck? I'd be very interested in seeing that. /cc @thysultan |
No description provided.