i'm developing a project using typeScript and have adopted emotionjs to simplify styling. however, i am wondering if the following code is efficient.
// 1. using emotionjs
import { css } from '@emotion/css';
const common = css` color: #ccc; `;
const $div = document.createElement('div');
$div.classList.add(common);
// 2. using inline-style
const $div = document.createElement('div');
$div.innerHtml = `<div style="color: #ccc;">text</div>`
as far as I understand, when styles are created using emotionjs, it modifies the CSSOM — in other words, a <style>
tag is injected into the <head>
, which inevitably triggers a CSSOM update.
on the other hand, setting styles using inline styles does not affect the CSSOM, but it does cause reflow and repaint.
if what I understand about the process is correct, does that mean relying solely on emotionjs for styling could lead to performance issues?
since emotionjs updates the CSSOM when applying styles, i thought excessive fragmentation(like in the code above)would result in too many injected class names, which could negatively impact runtime performance.
Like in every performance question, the answer is it depends. You should test, measure and monitor the performance on your application, your use-case.
Performance-wise, inline styles have are pretty the much the same as classes, but only when classes are used 1:1. CSS has to be preprocessed by the browser, classes in stylesheet get processed when they are defined, and then they are easy to use/apply. While inline styles are processed when they are used.
Still in a world where every inline style would map to a class, for a 1:1 comparison: The page would take more time to be parsed at start for classes, while inline-style would take more time during the dom parsing and every dom changes that add inline styles.
So all in all, if the DOM evolves, there is good chances classes would win in the long term. But parsing classes that are not used yet (because they're gonna show on interaction later on) could degrade first paint time.
So as you can see, when having one class for every inline style the performance hit can differ depending on the type of application/website.
One key takeaway is that classes are reusable, and normally are better for performance because they are parsed once and applied many times, not like our 1:1 examples above.
Now, to get back to your more specific question about using emotionjs, basically what it does is take inline styles and create classes. Pretty close to our 1:1 discussion above. The difference MAY come from the fact classes are created during runtime when objects are created by javascript. This means the first parsing of the stylesheet may not be much since classes are not there yet. Since classes are added on the fly, the parsing takes place at runtime when needed, pretty much like inline styles. You'd need the benefit of re-using classes to make the classes win over inline styles.
Keeping all this in mind, we discussed purely about CSS here. But you'd need to consider the fact that these CSS rules will be created by Javascript, which is many times slower than pure CSS. Using it in SSR wouldn't impact much of it as it would create the stylesheets on the server once and then the client wouldn't use javascript for it.
So yes, this is a vague explanation of why this question cannot be answered at this point. There are many factors involved and the difference between those two approaches are likely to be so small that providing an accurate timing would be hard.
As a final thought, I'd greatly suggest that you use the most performant for you. By that I mean the tool best suited for your development performance. Get something up and running, worry about performance when it actually becomes a problem. There is no need to think about these small bits just now. Performance is only a problem when it makes the app too costly to run (because of scaling needs) or too janky to use. At this point, I suspect you have nothing to run, and nothing to use. So this subject shouldn't matter to you.