DEV Community

Geoffrey Kim
Geoffrey Kim

Posted on

Improving CSS Loading in React Applications: Avoiding `@import` in `createGlobalStyle`

When working with React and styled-components, you might encounter performance and compatibility issues if you use @import within createGlobalStyle. This blog post will explain why this happens and how to resolve it by embedding the stylesheet link directly in your index.html file.

The Problem with @import in createGlobalStyle

Using @import in createGlobalStyle can lead to several issues:

  1. CSSOM API Limitations: The CSS Object Model (CSSOM) API, which allows for programmatic manipulation of CSS, has limitations when handling @import rules in dynamically created stylesheets. This can cause unexpected behavior or failures in applying styles.

  2. Performance Issues: @import can cause stylesheets to load sequentially, which slows down the page load time. In contrast, using <link> tags allows stylesheets to load in parallel, improving performance.

  3. Predictable Load Order: <link> tags ensure that stylesheets are loaded in the order they appear in the HTML, making the application of styles more predictable and easier to manage.

Solution: Using <link> in index.html

To avoid these issues, you can move the font import to the index.html file. Here’s how you can do it:

Step 1: Update index.html

Add the following <link> tag inside the <head> section of your public/index.html file:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="Web site created using create-react-app" />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link
      href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900&display=swap"
      rel="stylesheet"
    />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Step 2: Update GlobalStyles.ts

Remove the @import statement from your GlobalStyles.ts file:

import { createGlobalStyle } from 'styled-components';

const GlobalStyle = createGlobalStyle`
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}
* {
  box-sizing: border-box;
}
body {
  font-family: "Noto Sans KR", "Roboto", sans-serif;
  background-color: ${(props) => props.theme.bgColor};
  color: ${(props) => props.theme.textColor};
  line-height: 1.2;
}
a {
  text-decoration: none;
  color:inherit;
}
`;

export default GlobalStyle;
Enter fullscreen mode Exit fullscreen mode

Why This Works

CSSOM API

The CSSOM API allows for programmatic manipulation of CSS stylesheets. However, it has limitations when dealing with @import rules in dynamically created stylesheets. By using <link> tags, you avoid these limitations and ensure that styles are applied correctly.

Performance

Using <link> tags allows the browser to load stylesheets in parallel, which can significantly improve page load times. This is especially important for web applications that rely on multiple stylesheets.

Predictable Load Order

With <link> tags, stylesheets are loaded in the order they appear in the HTML. This makes it easier to manage and predict the application of styles, reducing the risk of style conflicts and ensuring a more consistent user experience.

Conclusion

By moving the font import to the index.html file and using <link> tags instead of @import in createGlobalStyle, you can avoid compatibility issues with the CSSOM API, improve performance, and ensure a more predictable load order for your stylesheets. This simple change can lead to a more robust and performant React application.

Top comments (0)