@compiled/react 0.10.2 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@compiled/react",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.3",
|
|
4
4
|
"description": "A familiar and performant compile time CSS-in-JS library for React.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"compiled",
|
|
@@ -76,8 +76,10 @@
|
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@compiled/benchmark": "^1.0.1",
|
|
79
|
-
"@testing-library/react": "^
|
|
79
|
+
"@testing-library/react": "^12.1.3",
|
|
80
|
+
"@types/jsdom": "^16.2.14",
|
|
80
81
|
"@types/react-dom": "^17.0.11",
|
|
82
|
+
"jsdom": "^19.0.0",
|
|
81
83
|
"react": "^17.0.2",
|
|
82
84
|
"react-dom": "^17.0.2"
|
|
83
85
|
},
|
|
@@ -1,111 +1,156 @@
|
|
|
1
1
|
import { runBenchmark } from '@compiled/benchmark';
|
|
2
|
+
import { JSDOM } from 'jsdom';
|
|
2
3
|
import * as React from 'react';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
import { render } from 'react-dom';
|
|
3
6
|
import { renderToString } from 'react-dom/server';
|
|
4
7
|
|
|
5
8
|
import { CC, CS } from '../index';
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
const MemoCS = memo(CS, () => true);
|
|
11
|
+
|
|
12
|
+
import { StyleBucketFromArray, StyleBucketFromString } from './utils/cs';
|
|
8
13
|
|
|
9
14
|
describe('CS benchmark', () => {
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
'
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
describe.each(['server', 'client'])('on the %s', (env) => {
|
|
16
|
+
const document = globalThis.document;
|
|
17
|
+
const window = globalThis.window;
|
|
18
|
+
|
|
19
|
+
beforeAll(() => {
|
|
20
|
+
if (env === 'server') {
|
|
21
|
+
// @ts-expect-error
|
|
22
|
+
delete globalThis.document;
|
|
23
|
+
// @ts-expect-error
|
|
24
|
+
delete globalThis.window;
|
|
25
|
+
} else {
|
|
26
|
+
const dom = new JSDOM('<div id="root"></div>');
|
|
27
|
+
globalThis.document = dom.window.document;
|
|
28
|
+
// @ts-expect-error
|
|
29
|
+
globalThis.window = dom.window;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
afterAll(() => {
|
|
34
|
+
globalThis.document = document;
|
|
35
|
+
globalThis.window = window;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const fastest =
|
|
39
|
+
env === 'server'
|
|
40
|
+
? ['StyleBucketFromArray', 'StyleBucketFromString']
|
|
41
|
+
: ['MemoCS (1 array element)', 'MemoCS (n array elements)'];
|
|
24
42
|
|
|
25
|
-
|
|
43
|
+
it(`completes with [${fastest.join(', ')}] as the fastest`, async () => {
|
|
44
|
+
const stylesArr = [
|
|
45
|
+
'._s7n4jp4b{vertical-align:top}',
|
|
46
|
+
'._1reo15vq{overflow-x:hidden}',
|
|
47
|
+
'._18m915vq{overflow-y:hidden}',
|
|
48
|
+
'._1bto1l2s{text-overflow:ellipsis}',
|
|
49
|
+
'._o5721q9c{white-space:nowrap}',
|
|
50
|
+
'._ca0qidpf{padding-top:0}',
|
|
51
|
+
'._u5f31y44{padding-right:4px}',
|
|
52
|
+
'._n3tdidpf{padding-bottom:0}',
|
|
53
|
+
'._19bv1y44{padding-left:4px}',
|
|
54
|
+
'._p12f12xx{max-width:100px}',
|
|
55
|
+
'._1bsb1osq{width:100%}',
|
|
56
|
+
];
|
|
26
57
|
|
|
27
|
-
|
|
28
|
-
'_bfhk1jys',
|
|
29
|
-
'_2rko1l7b',
|
|
30
|
-
'_vchhusvi',
|
|
31
|
-
'_syaz4rde',
|
|
32
|
-
'_1e0c1o8l',
|
|
33
|
-
'_1wyb1skh',
|
|
34
|
-
'_k48p1fw0',
|
|
35
|
-
'_vwz4kb7n',
|
|
36
|
-
'_p12f1osq',
|
|
37
|
-
'_ca0qyh40',
|
|
38
|
-
'_u5f3idpf',
|
|
39
|
-
'_n3td1l7b',
|
|
40
|
-
'_19bvidpf',
|
|
41
|
-
'_1p1dangw',
|
|
42
|
-
'_s7n41q9y',
|
|
43
|
-
].join(' ');
|
|
58
|
+
const stylesStr = stylesArr.join('');
|
|
44
59
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
'--_kmurgp': 'rgb(0, 102, 68)',
|
|
48
|
-
} as any;
|
|
60
|
+
const className = stylesArr.map((rule) => rule.slice(1, 10)).join(' ');
|
|
61
|
+
const nonce = 'k0Mp1lEd';
|
|
49
62
|
|
|
50
|
-
|
|
63
|
+
const renderJSX =
|
|
64
|
+
env === 'server'
|
|
65
|
+
? (jsx: (key: number) => JSX.Element) => {
|
|
66
|
+
renderToString(<>{Array.from({ length: 10 }).map((_, i) => jsx(i))}</>);
|
|
67
|
+
}
|
|
68
|
+
: (jsx: (key: number) => JSX.Element) => {
|
|
69
|
+
render(
|
|
70
|
+
<>{Array.from({ length: 10 }).map((_, i) => jsx(i))}</>,
|
|
71
|
+
globalThis.document.getElementById('root')
|
|
72
|
+
);
|
|
73
|
+
};
|
|
51
74
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
);
|
|
75
|
+
const tests = [
|
|
76
|
+
{
|
|
77
|
+
name: 'CS (1 array element)',
|
|
78
|
+
fn: () => {
|
|
79
|
+
renderJSX((key) => (
|
|
80
|
+
<CC key={`cs1-${key}`}>
|
|
81
|
+
<CS nonce={nonce}>{[stylesStr]}</CS>
|
|
82
|
+
<div className={className} />
|
|
83
|
+
</CC>
|
|
84
|
+
));
|
|
85
|
+
},
|
|
64
86
|
},
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
</CC>
|
|
76
|
-
);
|
|
87
|
+
{
|
|
88
|
+
name: 'CS (n array elements)',
|
|
89
|
+
fn: () => {
|
|
90
|
+
renderJSX((key) => (
|
|
91
|
+
<CC key={`csn-${key}`}>
|
|
92
|
+
<CS nonce={nonce}>{stylesArr}</CS>
|
|
93
|
+
<div className={className} />
|
|
94
|
+
</CC>
|
|
95
|
+
));
|
|
96
|
+
},
|
|
77
97
|
},
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
</CC>
|
|
89
|
-
);
|
|
98
|
+
{
|
|
99
|
+
name: 'MemoCS (1 array element)',
|
|
100
|
+
fn: () => {
|
|
101
|
+
renderJSX((key) => (
|
|
102
|
+
<CC key={`memo-cs1-${key}`}>
|
|
103
|
+
<MemoCS nonce={nonce}>{[stylesStr]}</MemoCS>
|
|
104
|
+
<div className={className} />
|
|
105
|
+
</CC>
|
|
106
|
+
));
|
|
107
|
+
},
|
|
90
108
|
},
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
</CC>
|
|
102
|
-
);
|
|
109
|
+
{
|
|
110
|
+
name: 'MemoCS (n array elements)',
|
|
111
|
+
fn: () => {
|
|
112
|
+
renderJSX((key) => (
|
|
113
|
+
<CC key={`memo-csn-${key}`}>
|
|
114
|
+
<MemoCS nonce={nonce}>{stylesArr}</MemoCS>
|
|
115
|
+
<div className={className} />
|
|
116
|
+
</CC>
|
|
117
|
+
));
|
|
118
|
+
},
|
|
103
119
|
},
|
|
104
|
-
|
|
105
|
-
|
|
120
|
+
...(env === 'server'
|
|
121
|
+
? [
|
|
122
|
+
{
|
|
123
|
+
name: 'StyleBucketFromArray',
|
|
124
|
+
fn: () => {
|
|
125
|
+
renderJSX((key) => (
|
|
126
|
+
<CC key={`sbfa-${key}`}>
|
|
127
|
+
<StyleBucketFromArray nonce={nonce}>{stylesArr}</StyleBucketFromArray>
|
|
128
|
+
<div className={className} />
|
|
129
|
+
</CC>
|
|
130
|
+
));
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'StyleBucketFromString',
|
|
135
|
+
fn: () => {
|
|
136
|
+
renderJSX((key) => (
|
|
137
|
+
<CC key={`sbfs-${key}`}>
|
|
138
|
+
<StyleBucketFromString nonce={nonce}>{stylesStr}</StyleBucketFromString>
|
|
139
|
+
<div className={className} />
|
|
140
|
+
</CC>
|
|
141
|
+
));
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
]
|
|
145
|
+
: []),
|
|
146
|
+
];
|
|
106
147
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
148
|
+
const benchmark = await runBenchmark('CS', tests);
|
|
149
|
+
|
|
150
|
+
const slowest = tests.map((t) => t.name).filter((n) => !fastest.includes(n));
|
|
151
|
+
for (const name of slowest) {
|
|
152
|
+
expect(benchmark.fastest).not.toContain(name);
|
|
153
|
+
}
|
|
154
|
+
}, 60000);
|
|
155
|
+
});
|
|
111
156
|
});
|
|
@@ -2,20 +2,17 @@ import React, { createContext, useContext } from 'react';
|
|
|
2
2
|
|
|
3
3
|
const Cache = createContext<Record<string, true> | null>(null);
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export type StyleStrProps = {
|
|
10
|
-
children: string;
|
|
5
|
+
export type StyleBucketFromArrayProps = {
|
|
6
|
+
children: string[];
|
|
11
7
|
nonce: string;
|
|
12
8
|
};
|
|
13
9
|
|
|
14
|
-
export function
|
|
15
|
-
|
|
10
|
+
export function StyleBucketFromArray({
|
|
11
|
+
children: sheets,
|
|
12
|
+
nonce,
|
|
13
|
+
}: StyleBucketFromArrayProps): JSX.Element | null {
|
|
14
|
+
const inserted = useContext(Cache) || {};
|
|
16
15
|
|
|
17
|
-
// The following code will not exist in the browser bundle.
|
|
18
|
-
const sheets = children.split('.');
|
|
19
16
|
let toInsert = '';
|
|
20
17
|
|
|
21
18
|
for (let i = 0; i < sheets.length; i++) {
|
|
@@ -33,15 +30,18 @@ export function StyleStr({ children, nonce }: StyleStrProps): JSX.Element | null
|
|
|
33
30
|
return <style nonce={nonce}>{toInsert}</style>;
|
|
34
31
|
}
|
|
35
32
|
|
|
36
|
-
export type
|
|
37
|
-
children: string
|
|
33
|
+
export type StyleBucketFromStringProps = {
|
|
34
|
+
children: string;
|
|
38
35
|
nonce: string;
|
|
39
36
|
};
|
|
40
37
|
|
|
41
|
-
export function
|
|
42
|
-
|
|
38
|
+
export function StyleBucketFromString({
|
|
39
|
+
children,
|
|
40
|
+
nonce,
|
|
41
|
+
}: StyleBucketFromStringProps): JSX.Element | null {
|
|
42
|
+
const inserted = useContext(Cache) || {};
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
const sheets = children.split('.');
|
|
45
45
|
let toInsert = '';
|
|
46
46
|
|
|
47
47
|
for (let i = 0; i < sheets.length; i++) {
|