파크로그
article thumbnail

layout shift

 처음엔 List Item 의 width 가 바짝 차렷 하고있는 모습을 먼저 보였다.

어깨 펴 인마..

 

이를 해결하기 위해 Item 의 width 를 어떻게줄까.. 하다가 List 에 max-content 를 주니 해결이 되는 모습을 보았다.

그런데 문제가 생겼다.

 

Layout Shift?

 

처음엔 저게 왜 생겼지? top, left 를 지정해주다 생긴건가? 싶었는데 여러 테스트를 해보면서

width 가 max-content 로 동적으로 지정되니 생기는 문제인가.. 로 추측해보면서 Dropdown Item 의 width 를 지정해줘보았다.

 

const DropdownItem = (props) => {
  const { children } = props;
  return (
    <li
      css={css`
        width: 100px;
      `}
      {...props}
    >
      {children}
    </li>
  );
};

안보임

 

뭔가 list item 의 width 를 동적으로 계산해서 생기는 문제같긴 한데.. 명확한 이유를 몰랐다.

 

첫 번째 시도를 했던 list item 에 width 지정해주기 방법으로도 Layout Shift 가 사라졌었지만 다른 프로젝트를 할 때 텍스트 길이에 따라 변하는 요소에 의해 Layout Shift 가 발생했던 적이 없었다. 다른 UI 를 제공하는 라이브러리들의 demo 를 보아도 비슷한 증상은 없었다.

 

그리고 클릭을 할 때마다 깜빡거리는 증상과 움찔 하는 듯한 느낌이 있는 데, layout shift 를 해결하면 해결되지 않을까 해서 관련 증상을 찾아보았다.

 

1. FOUC 라는 키워드 - 증상은 같으나 현재 매우 가벼운 프로젝트에서 발생할 이유가 아니라고 생각했음, SSR 도 아님

2. network 탭을 확인해보니 클릭 이벤트시에 폰트를 다시 받아오는데, 이게 왜 다시 받아오는 건지 찾아보았다.

woff2 를 2개 사용하고 있는데, woff2 를 또 불러옴

결국 이유는 styled components 에서 새로운 컴포넌트가 특정 이벤트에 의해서 렌더링되면 새로운 클래스를 넣기 위해 style 태그를 변경하는데, styled components 에서 font 를 import 하면 해당 과정에서 폰트를 다시 불러오는 현상 때문이었다

 

 

 

createStaticStyle 이라는 것 만들어 주세요..
응 분리해서 써~

 

며칠 전 제로초님의 인프런 강의를 들으면서 결국 index.html 에서 처리하는게 생긴다~ 라고 하신 부분이 이런 부분일까 싶었다.

그래서 createGlobalStyle 내부에서 @font-face 를 만드는 로직을 별도로 분리하여 index.html 에 직접 넣었다.

폰트 관련 부분을 수정하니 반짝임도 사라지고, layout shift 도 없어졌다. (layout shift 도 원인이 폰트때문이었는 듯)

 

 

신기하네.. width 관련 문제를 해결했을 땐 layout shift 가 사라지기도 했지만

폰트 관련 문제를 해결하니 width 를 어떻게 쓰든 layout shift 가 없다. 

 

또 변경..

위 해결법이 배포시 문제가 된다는걸 다시 깨달았다.

build 를 하면 webpack 이 하나의 js 로 번들링 해주는데, 폰트를 public 폴더 하위에 존재하게 두면 배포를 위한 빌드에서 폰트를 포함시키는게 곤란했다.

여러모로 생각해보니 그냥 하나의 js 로 번들링 시키는게 낫겠다 싶어 app.css 를 만들어 import 하여 쓰는걸로 다시 변경했다.

 

@font-face {
  font-family: Roboto;
  font-style: normal;
  font-weight: 400;
  src: url('./assets/fonts/noto-sans-kr-regular.woff2') format('woff2');
}
@font-face {
  font-family: NotoSansKR;
  font-style: normal;
  font-weight: 400;
  src: url('./assets/fonts/roboto-regular.woff2') format('woff2');
}

 

import './app.css';
...

const App: React.FC = () => {

  return (
    <ThemeProvider theme={isDarkMode ? darkTheme : lightTheme}>
      <GlobalStyle />
      <Routes />
    </ThemeProvider>
  );
};

export default App;

 

결론

1. Box 가 생성되고 폰트가 새롭게 불러와짐 -> 폰트가 달라져서 layout 이 변경됨 (폰트 크기가 다르므로) -> layout shift

2. width 설정할 시 -> 폰트가 달라져도 layout 이 그 width 안에 존재함 -> layout shift 없을 수 있음

 

profile

파크로그

@파크park

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!