ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React Styled-Components Font Reloading
    IT 지식 2020. 5. 4. 15:41
    Tech stack
    
    FrameWork
    - React
    
    Language
    - Typescript
    
    State Management
    - MobX
    
    UI Library
    - Styled-Components

     

    사건의 발단

    작업을 하는 도중, 버튼 이벤트 발생 시 화면이 깜빡 거리는 현상을 발견하게 되었다.

    대수롭지 않게 생각하기에는 나름 유저가 느낄 불편함이 크다고 판단하여, 원인을 파악해보자 다짐했다.

     

    [첫 번째 접근] Code Review

    불행인지, 다행인지 간헐적으로 발생하지 않았고 꾸준히 발생하는 문제였다..

    내가 볼 코드는 Button Component 부분이였다.

    styled-components를 이용한 스타일 코드에 삼항 연산자들이 많았다.
    프로젝트에 Default 스타일들이 존재 할 것이고, 추후 이벤트에 대한 상호작용이 필요한 것을 대비한 코드였다.
    이 부분을 수정하니, 끊김은 발생되지 않았다.

     

    첫 번째 단서

    새로운 스타일이 입혀질 때, 다시 Render 되면서 끊김이 발생한다.

     

    하지만, 이런 코드가 문제 되는 것이 이상했고 이전 styled-components 를 활용한 프로젝트에서는 경험하지 못 했던 상황이였다.
    분명, 이전 프로젝트에서도 이런 코드가 종종 존재 했다.

     

    [두 번째 접근] Styled-Components Research

    처음 보는 문제를 해결하려고 할 때, 가장 큰 어려움은 키워드이다.
    styled-components / dynamic style / flicker / button click 등 다양한 키워드로 검색해보았지만, 딱히 해결책을 찾지 못하였다.

    그래서 CTO님께 도움을 청하였다.

    많은 중간 과정들이 있었지만, CTO님께서 내게 주신 키워드는 FOUC(Flash Of Unstyled Content)였다.

    FOUC에 대해서는 정리 된 블로그들이 많기 때문에 자세한 설명은 생략하고, 간단하게 요약하면 CSS가 입혀지기 전의 상태가 먼저 나타난 후, 스타일이 적용되는 현상을 말한다.

    뭐.. 이런거?

    FOUC의 해결책에는 <head> 요소 안에 css를 링크 작성하거나, 선언 위치를 변경 해주는 등의 방법이 있다. 하지만, FOUC를 의심하기에는 우리의 문제는 종종 나타나지 않았고, styled-components는 스타일을 만들어 head 태그 안에 링크해주었으며, 아직 우리 프로젝트는 무겁지도 않고, 앞으로도 무거워질 생각이 없었다.

     

    두 번째 단서

    아.. FOUC 라는 것도 있구나. 근데 이 문제는 아니구나..

     

    [세 번째 접근] 실험

    나는 사실 첫 번째 접근 때부터 의미 없지만, 의미가 있을 수도 있는 여러가지 테스트를 진행 했다.

    • 스타일 코드에 있는 삼항연산자 모두 제거
    • 태그별로 나누어진 Item List들 첫 생성시 모두 렌더 후, 감추기
    • CheckBox 구현에 대하여 리서치 후, 구조 변경

    이런 테스트들을 하면서 한 번 이 문제가 해결은 됬지만, 마음 속으로 '이런 임시방편은 추후 분명 다시 문제가 생길 것이다.' 라고 생각했는데. 그 다음 날 바로 다시 문제가 터졌던 것이다. ㅎㅎ

    그리고, CTO님이 내게 다시 "Font 관련 이슈가 아닐까?" 하는 말씀을 해주셨다.

    폰트를 제거하니, 이 문제는 마법처럼 해결 되었다. 하지만, 깜빡임 문제로 폰트를 사용하지 않을 수 없으니. 이 문제에 대한 원인과 해결책을 알아보아야했다.

     

    세 번째 단서

    폰트, 내가 폰트를 입힌 방법 (styled-components global style)

     

    원인

    Styled-Components를 사용하면서, 전역 스타일과 폰트를 적용하기 위하여 createGlobalStyle을 사용하였다.
    여기서 문제가 발생 된 것이다.

    위 html 코드 처럼 Styled-Components는 스타일이 Render 될 때 마다, head 태그의 style 태그를 변경한다. 그런데 하나의 style 태그 안에 Font 관련 스타일 코드가 함께 존재하여, 새로운 스타일이 등장할 때마다 폰트를 재요청하는 현상이 나타난 것이다.

     

    실제 깜빡임이 발생 되었을 때, style 태그의 변화

    새로 Render 된 style이 추가 된 모습이다.

    클릭이 된 후, <head> 태그안에 존재하는 <style> 태그의 내용이 추가 되었다.

     

    • Status Code 304 (변경사항이 없음)

    우리의 프로젝트는 새로운 스타일이 등장하여, head 태그안에 style 태그가 변경 될 때마다, 폰트가 재요청 되었고 다른 웹사이트들에서는 이런 현상이 없었다. 또, 아래의 Github Issue가 해당 문제에 대한 토론의 장이다.

     

    Dynamic style change causes custom fonts to be re-requested from the server · Issue #1593 · styled-components/styled-component

    I couldn't tell if this has anything to do with #1576, but it seems like potentially its own issue. I don't have @media rules, but I do have @font-face rules. System: OS: macOS High Sierra ...

    github.com

    • styled-components createGlobalStyle을 통하여 style 초기화, font를 정의한다.
    • styled-components는 새로운 스타일이 render 될 때마다, <style>태그를 변경 한다.
    • <style> 태그안에 폰트 정의가 함께 있어 새로운 스타일이 등장할 때마다, font를 재요청한다.
    • 이 재요청 문제로 깜빡거리는 문제가 발생 되고, 유저들은 font style 정의를 분리해달라고 요청했다.
    • 하지만, 개발자는 바빴고, 해당 문제는 그렇게 해결 되지 않은채 약 2년이 흘렀다.

     

    해결책

    (1) css-loader를 이용하여, font 부분만 정의 하기

    (2) 폰트 링크 넣어주기

    <style>
    @import url(//fonts.googleapis.com/earlyaccess/nanumgothic.css);
    </style>

    (3) 폰트를 쓰지 말기

    (4) styled-components 쓰지 말기

     

    styled-components로 해결 하고 싶었지만, 아무리 찾아봐도 해결책은 없었다.
    css-loader를 붙이거나, 폰트 링크를 붙여야겠다..

     

     

    'IT 지식' 카테고리의 다른 글

    DOM과 Virtual DOM  (2) 2020.06.24
    SmartContract 개발에 유의해야할 점 (2/2)  (2) 2019.05.10
    SmartContract 개발에 유의해야할 점 (1/2)  (1) 2019.04.25

    댓글

Developer RyuK