Skip to content

Commit c223c46

Browse files
committed
Implement getSeparatedStyles to reduce creation of unnecessary static rules classes/rules
1 parent f08e3ab commit c223c46

6 files changed

Lines changed: 140 additions & 40 deletions

File tree

src/styled.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
import filterProps from './utils/filterProps'
88
import composeClasses from './utils/composeClasses'
99
import generateTagName from './utils/generateTagName'
10+
import getSeparatedStyles from './utils/getSeparatedStyles'
1011

1112
import type {
1213
JssSheet,
@@ -21,8 +22,8 @@ type StyledArgs = {
2122
}
2223

2324
const styled = ({tagName, elementStyle, mountSheet}: StyledArgs) => {
24-
const dynamicStyle = getDynamicStyles(elementStyle)
25-
const staticTagName = generateTagName(tagName)
25+
const {dynamicStyle, staticStyle} = getSeparatedStyles(elementStyle)
26+
const staticTagName = staticStyle && generateTagName(tagName)
2627

2728
const availableDynamicTagNames = []
2829
const classMap = {}
@@ -51,8 +52,8 @@ const styled = ({tagName, elementStyle, mountSheet}: StyledArgs) => {
5152

5253
const rulesTotal = this.rulesIndex.length
5354

54-
if (!this.sheet.getRule(staticTagName)) {
55-
this.sheet.addRule(staticTagName, elementStyle)
55+
if (staticStyle && !this.sheet.getRule(staticTagName)) {
56+
this.sheet.addRule(staticTagName, staticStyle)
5657
}
5758

5859
if (!dynamicStyle) return

src/tests/__snapshots__/index.spec.jsx.snap

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
exports[`base rendering tests renders correctly App with default Styled 1`] = `
22
<div
3-
className="div-9-0-9">
3+
className="div-8-0-8">
44
<header
5-
className="header-10-0-10">
5+
className="header-9-0-9">
66
<h1
7-
className="h1-13-0-11">
7+
className="h1-12-0-10">
88
Title
99
</h1>
1010
</header>
1111
<section
12-
className="section-11-0-12"
12+
className="section-10-0-11"
1313
data-name="content">
1414
<button
15-
className="button-14-0-13 button-15-0-14">
15+
className="button-13-0-12">
1616
primitive test
1717
</button>
1818
<button
19-
className="button-14-0-13 button-16-0-15">
19+
className="button-14-0-13">
2020
dynamic primitive test
2121
</button>
2222
</section>
2323
<section
24-
className="section-12-0-16">
24+
className="section-11-0-14">
2525
Another section
2626
</section>
2727
</div>
@@ -41,47 +41,47 @@ exports[`base rendering tests renders correctly App with default styled 1`] = `
4141
className="section-3-0-3"
4242
data-name="content">
4343
<button
44-
className="button-6-0-4 button-7-0-5">
44+
className="button-6-0-4">
4545
primitive test
4646
</button>
4747
<button
48-
className="button-6-0-4 button-8-0-6">
48+
className="button-7-0-5">
4949
dynamic primitive test
5050
</button>
5151
</section>
5252
<section
53-
className="section-4-0-7">
53+
className="section-4-0-6">
5454
Another section
5555
</section>
5656
</div>
5757
`;
5858

5959
exports[`base rendering tests renders correctly App with injectStyled 1`] = `
6060
<div
61-
className="root-0-17">
61+
className="root-0-15">
6262
<div
63-
className="div-17-0-19">
63+
className="div-15-0-17">
6464
<header
65-
className="header-18-0-20">
65+
className="header-16-0-18">
6666
<h1
67-
className="h1-21-0-21">
67+
className="h1-19-0-19">
6868
Title
6969
</h1>
7070
</header>
7171
<section
72-
className="section-19-0-22"
72+
className="section-17-0-20"
7373
data-name="content">
7474
<button
75-
className="button-22-0-23 button-23-0-24">
75+
className="button-20-0-21">
7676
primitive test
7777
</button>
7878
<button
79-
className="button-22-0-23 button-24-0-25">
79+
className="button-21-0-22">
8080
dynamic primitive test
8181
</button>
8282
</section>
8383
<section
84-
className="section-20-0-26">
84+
className="section-18-0-23">
8585
Another section
8686
</section>
8787
</div>

src/tests/functional.spec.jsx

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,9 @@ describe('functional tests', () => {
6262
margin: 0;
6363
}
6464
.button-7-6 {
65-
margin: 0;
66-
}
67-
.button-8-7 {
6865
margin: 10px;
6966
}
70-
.section-4-8 {
67+
.section-4-7 {
7168
color: yellow;
7269
}
7370
`)
@@ -91,12 +88,9 @@ describe('functional tests', () => {
9188
margin: 0;
9289
}
9390
.button-7-6 {
94-
margin: 0;
95-
}
96-
.button-8-7 {
9791
margin: 20px;
9892
}
99-
.section-4-8 {
93+
.section-4-7 {
10094
color: yellow;
10195
}
10296
`)
@@ -145,13 +139,10 @@ describe('functional tests', () => {
145139
.div-1-2 {
146140
padding: 15px;
147141
}
148-
.div-1-2:hover .button-1 {
142+
.div-3-3:hover .button-1 {
149143
color: green;
150144
}
151-
.div-3-5:hover .button-1 {
152-
color: green;
153-
}
154-
.div-4-9:hover .button-1 {
145+
.div-4-7:hover .button-1 {
155146
color: red;
156147
}
157148
`)
@@ -167,13 +158,10 @@ describe('functional tests', () => {
167158
.div-1-2 {
168159
padding: 15px;
169160
}
170-
.div-1-2:hover .button-1 {
171-
color: red;
172-
}
173-
.div-3-5:hover .button-1 {
161+
.div-3-3:hover .button-1 {
174162
color: red;
175163
}
176-
.div-4-9:hover .button-1 {
164+
.div-4-7:hover .button-1 {
177165
color: green;
178166
}
179167
`)

src/tests/utils.spec.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import getSeparatedStyles from '../utils/getSeparatedStyles'
2+
3+
describe('unit tests for utils', () => {
4+
it('should extract separated styles', () => {
5+
const color = data => data.color
6+
const styles = {
7+
button: {
8+
float: 'left',
9+
margin: [5, 10],
10+
color,
11+
'@media screen': {
12+
width: null,
13+
},
14+
'@media print': {
15+
width: undefined,
16+
color
17+
},
18+
'& a': {
19+
color: 'red',
20+
'& b': {
21+
color
22+
}
23+
},
24+
},
25+
'@media': {
26+
button: {
27+
width: 2,
28+
color
29+
}
30+
},
31+
nested: {
32+
'& a': {
33+
color: 'red'
34+
}
35+
}
36+
}
37+
38+
expect(getSeparatedStyles(styles)).toEqual({
39+
dynamicStyle: {
40+
button: {
41+
color,
42+
'@media print': {
43+
color
44+
},
45+
'& a': {
46+
'& b': {
47+
color
48+
}
49+
}
50+
},
51+
'@media': {
52+
button: {
53+
color
54+
}
55+
}
56+
},
57+
staticStyle: {
58+
button: {
59+
float: 'left',
60+
margin: [5, 10],
61+
'@media screen': {
62+
width: null,
63+
},
64+
'@media print': {
65+
width: undefined,
66+
},
67+
'& a': {
68+
color: 'red',
69+
}
70+
},
71+
'@media': {
72+
button: {
73+
width: 2,
74+
}
75+
},
76+
nested: {
77+
'& a': {
78+
color: 'red'
79+
}
80+
}
81+
}
82+
})
83+
})
84+
})

src/utils/getSeparatedStyles.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const isObject = value =>
2+
typeof value === 'object' && value !== null && !Array.isArray(value)
3+
4+
/**
5+
* Extracts static and dynamic styles objects separately
6+
*/
7+
const getSeparatedStyles = (styles: Object) => {
8+
const result = {}
9+
10+
for (const key in styles) {
11+
const value = styles[key]
12+
const itemStyles = {}
13+
14+
if (typeof value === 'function') itemStyles.dynamicStyle = value
15+
else if (isObject(value)) Object.assign(itemStyles, getSeparatedStyles(value))
16+
else itemStyles.staticStyle = value
17+
18+
for (const styleType in itemStyles) {
19+
result[styleType] = result[styleType] || {}
20+
result[styleType][key] = itemStyles[styleType]
21+
}
22+
}
23+
24+
return result
25+
}
26+
27+
export default getSeparatedStyles

0 commit comments

Comments
 (0)