Skip to content

Commit 7613321

Browse files
committed
Add Demo3, illustrating extra memory use from inlined CSS-as-JS-string
1 parent 9693025 commit 7613321

File tree

8 files changed

+9096
-1
lines changed

8 files changed

+9096
-1
lines changed

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ In the `fetch()` version of the custom element, the JSON file isn't fetched unti
8282
### [CSS modules vs `<link>` elements in shadow roots](https://dandclark.github.io/json-css-module-notes/demo2/index.html)
8383
[https://dandclark.github.io/json-css-module-notes/demo2/index.html](https://dandclark.github.io/json-css-module-notes/demo2/index.html)
8484

85-
(There is no general CSS modules browser support as of this writing; that part of the demo was developed on a custom Chromium build).
85+
(There is no general CSS modules browser support as of this writing; that part of the demo was created and tested using a custom Chromium build).
8686

8787
This demo compares two similar custom elements written as a JavaScript module, each of which loads its styles from a separate `styles.css` file. The first custom element applies its styles by adding the styles via a `<link rel="stylesheet">` in the custom element shadow root. The second loads its styles via a CSS module.
8888

@@ -97,3 +97,20 @@ Using CSS modules, styles.css is fetched as part of processing the module graph,
9797
![With CSSmodule](demo2Module.PNG)
9898

9999
If `styles.css` was slow to arrive over the network, or was large enough to take a nontrivial amount of time to parse, front-loading the work could result in a user-percievable difference in how early the styles are applied to the page.
100+
101+
102+
## Demo 3
103+
### [CSS/JSON modules have a lower memory footprint than inlining the CSS/JSON as a JavaScript string](https://dandclark.github.io/json-css-module-notes/demo3/index.html)
104+
[https://dandclark.github.io/json-css-module-notes/demo3/index.html](https://dandclark.github.io/json-css-module-notes/demo3/index.html)
105+
106+
(There is no general CSS modules browser support as of this writing; that part of the demo was created and tested a custom Chromium build).
107+
108+
An alternative non-module approach for packaging CSS/JSON in a custom element is to inline the content as a JavaScript string rather than `fetch()`ing it dynamically.
109+
This eliminates any concerns about a a delay in the `fetch()` as outlined above. However, in addition to the clunky developer ergonimics
110+
of a bunch of inlined JavaScript string content in one's custom element JS logic, this approach has a quantifiable memory cost. This is due to the fact that the original JS string lives on alongside the CSSStyleSheet or JSON object that it is eventually parsed into. Whereas with CSS/JSON modules, nothing persists but the CSSStylesheet or JSON object.
111+
112+
[Demo3](https://dandclark.github.io/json-css-module-notes/demo3/index.html) linked above illustrates this difference. Both the no-module and the module case load a custom element that pulls in ~30MB of CSS. The no-module case imports inlines it in the JS file defining the custom element, in the style of some of the [existing Chromium layered API elements](https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/script/resources/layered_api/elements/). The module case imports the same CSS as a CSS module. After reaching steady-state, the memory difference is around the same ~30MB as the raw CSS text:
113+
114+
![Memory savings with CSS modules versus inlined CSS-as-JS-string](demo3SteadyState.PNG)
115+
116+
This steady state is reached after leaving both tabs in the background for ~60 seconds. Before this final garbage collection, the difference is even more stark; in my observations the inline CSS case hovers around ~95MB for the first 60 seconds, whereas the CSS modules tab goes down to ~38MB within the first few seconds.

demo3/big_styles.css

Lines changed: 4500 additions & 0 deletions
Large diffs are not rendered by default.

demo3/cssModuleCatElement.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import sheet from "./big_styles.css";
2+
3+
class CSSModuleCatElement extends HTMLElement {
4+
constructor() {
5+
super();
6+
this.shadow = this.attachShadow({mode: "closed"});
7+
this.shadow.adoptedStyleSheets = [sheet];
8+
9+
this.shadow.innerHTML = `
10+
<div class="cat10"></div>
11+
`;
12+
}
13+
}
14+
export {CSSModuleCatElement};

demo3/index.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<h2>Demo 1: Fetching of JSON and CSS modules starts before script execution</h2>
2+
<br>
3+
<ul>
4+
<li><a href="./noModule.html">Styles inlined in module with Constructed StyleSheet (supported in Chromium-based browsers)</a></li>
5+
<li><a href="./module.html">With CSS Module</a> (no browser support yet...)</li>
6+
</ul>
7+
<a href="../">[Back to main page]</a>

demo3/inlineCSSCatElement.js

Lines changed: 4529 additions & 0 deletions
Large diffs are not rendered by default.

demo3/module.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>CSS module custom element</title>
5+
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
6+
<script type="module">
7+
import {CSSModuleCatElement} from "./cssModuleCatElement.js";
8+
window.customElements.define("cat-element", CSSModuleCatElement);
9+
</script>
10+
</head>
11+
<body>
12+
<cat-element></cat-element>
13+
</body>
14+
</html>

demo3/noModule.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>Inline CSS custom element</title>
5+
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
6+
<script type="module">
7+
import {InlineCSSCatElement} from "./inlineCSSCatElement.js";
8+
window.customElements.define("cat-element", InlineCSSCatElement);
9+
</script>
10+
</head>
11+
<body>
12+
<cat-element></cat-element>
13+
</body>
14+
</html>

demo3SteadyState.PNG

17.7 KB
Loading

0 commit comments

Comments
 (0)