@@ -19,8 +19,14 @@ import { isServerSide } from 'utils/isomorphy';
19
19
20
20
import ContentWrapper from './ContentWrapper' ;
21
21
22
+ /* Specifies the maximal number of unused CSS stylesheets to be kept in memory.
23
+ */
24
+ const MAX_UNUSED_STYLESHEETS = 10 ;
25
+
22
26
const TMP_CHUNK_PREFIX = 'community-app-assets' ;
23
27
28
+ let unusedCssStamp = 0 ;
29
+
24
30
export default class SplitRoute extends React . Component {
25
31
constructor ( props ) {
26
32
super ( props ) ;
@@ -32,15 +38,12 @@ export default class SplitRoute extends React.Component {
32
38
}
33
39
34
40
reset ( ) {
35
- /* Removing chunk's stylesheet from the DOM. */
36
- /* NOTE: It look like caching CSS makes no sense, as it starts conflicting
37
- * with other stylesheets. */
38
- // if (!this.props.cacheCss) {
41
+ /* Marking chunk's stylesheet as unused.
42
+ * This works properly only when styling does not depend on the ordering
43
+ * of loaded stylesheets, which is how our CSS should be written. */
39
44
const link = document . querySelector (
40
45
`link[data-chunk="${ TMP_CHUNK_PREFIX } /${ this . props . chunkName } "]` ) ;
41
- const head = document . getElementsByTagName ( 'head' ) [ 0 ] ;
42
- head . removeChild ( link ) ;
43
- // }
46
+ link . setAttribute ( 'data-chunk-unused' , unusedCssStamp += 1 ) ;
44
47
45
48
/* Reset to the initial state. */
46
49
this . setState ( { component : null } ) ;
@@ -144,21 +147,31 @@ export default class SplitRoute extends React.Component {
144
147
let link =
145
148
document . querySelector ( `link[data-chunk="${ TMP_CHUNK_PREFIX } /${ chunkName } "]` ) ;
146
149
if ( link ) {
147
- /* Even if the stylesheet is already loaded, we should move it
148
- * to the end of the head, to ensure that it gets priority over
149
- * anything else.
150
- * On the other hand, if we drop cacheCss option, this should not
151
- * be a problem, and can be more efficient.
152
- */
153
- // const head = document.getElementsByTagName('head')[0];
154
- // head.appendChild(link);
150
+ /* Marking the chunk being used again. */
151
+ link . removeAttribute ( 'data-chunk-unused' ) ;
155
152
} else {
156
153
link = document . createElement ( 'link' ) ;
157
154
link . setAttribute ( 'data-chunk' , `${ TMP_CHUNK_PREFIX } /${ chunkName } ` ) ;
158
155
link . setAttribute ( 'href' , `/${ TMP_CHUNK_PREFIX } /${ chunkName } .css` ) ;
159
156
link . setAttribute ( 'rel' , 'stylesheet' ) ;
160
157
const head = document . getElementsByTagName ( 'head' ) [ 0 ] ;
161
158
head . appendChild ( link ) ;
159
+
160
+ /* Unloads unused CSS stylesheets, if too many of them are
161
+ * loaded. */
162
+ const unused = head . querySelectorAll ( 'link[data-chunk-unused]' ) ;
163
+ if ( unused . length > MAX_UNUSED_STYLESHEETS ) {
164
+ const arr = [ ] ;
165
+ unused . forEach ( ( x ) => {
166
+ /* eslint-disable no-param-reassign */
167
+ x . chunkOrder = Number ( x . getAttribute ( 'data-chunk-unused' ) ) ;
168
+ /* eslint-enable no-param-reassign */
169
+ arr . push ( x ) ;
170
+ } ) ;
171
+ arr . sort ( ( a , b ) => a . chunkOrder - b . chunkOrder ) ;
172
+ arr . slice ( 0 , unused . length - MAX_UNUSED_STYLESHEETS )
173
+ . forEach ( x => head . removeChild ( x ) ) ;
174
+ }
162
175
}
163
176
164
177
/* Checking, whether we need to trigger async rendering process,
0 commit comments