# 2021년 7월, Monthly I Learned

# 7/16

# SWC

https://swc.rs/docs/installation/

  • ts/js 컴파일러. 브라우저가 읽을 수 있는 js로 바꿔준다.
  • 싱글스레드에선 바벨보다 20배 빠르고, 쿼드코어에선 70배 빠르다.
  • 트리셰이킹 됨
  • .swcrc 파일로 configure함

# Browserslist

  • 브라우저를 선택하는 옵션 기능만 뽑아둔 도구.
    • 명시적으로 버전 특정할 수도 있고, 최신 버전 2개를 선택할수도, 전세계 점유율 5% 이상인 브라우저만 선택도 가능(정적 데이터에서 뽑아옴)
  • .browserslistrc 파일로 정의

# 7/19

# React 18 (alpha)

https://medium.com/naver-place-dev/react-18%EC%9D%84-%EC%A4%80%EB%B9%84%ED%95%98%EC%84%B8%EC%9A%94-8603c36ddb25

17 이후 8개월만에 메이저 업데이트(알파)

# 자동 배치

  • 배치: 여러개의 상태 업데이트를 하나의 리렌더링으로 묶는 작업 (성능업을 위함)
function handleClick() {
  setCount((c) => c + 1); // 리렌더X
  setFlag((f) => !f); // 리렌더X
  // 두개를 모아서 리렌더링 1번 함
}

function handleClick2() {
  fetchSth().then(() => {
    // 리액트 17이하에선 이 코드는 이벤트핸들러 밖에 있어서 매번 리렌더됨 (배치수행X) but 18부터는 자동배치 해줌. 다만 ReactDOM.render대신 ReactDOM.createRoot함수 써야함
    setCount((c) => c + 1); // 리렌더O
    setFlag((f) => !f); // 리렌더O
  });
}

# Concurrent 기능

  • 리액트 차기 핵심 기능인 Concurrent mode의 일부가 추가
  • 상태 업데이트의 분류
    1. 긴급(Urgent) 업데이트: 타이핑, 스크롤링 등 직접적인 상호작용. 즉시 안나타나면 이상
    2. 전환(Transition) 업데이트: 하나의 뷰에서 다른 뷰로 UI 전환. 즉시 안나타나도 기다림 가능
    • e.g. 구글에 '헬로' 검색시 헬로가 즉각 보여야하는건 긴급, 자동완성이 한 발짝 늦게 보이는건 전환.
    • 전환 업데이트 때문에 긴급이 방해되면 안됨.
      • but 17까지는 긴급/전환 개념차이 X
      • 그래서 setTimeout, throttle, debounce등 테크닉으로 긴급 업뎃을 우회(모두 긴급이었으니...)
  • startTransition API: 느린 렌더링이나 느린 네트워크가 기대될때 사용 가능
const [isPending, startTransition] = useTransition();

function handleChange(e) {
  setValue(e.target.value); // 긴급
  startTransition(() => {
    setAutocomplete(e.target.value); // 전환
  });
}

# Suspense를 지원하는 SSR 아키텍쳐

  • 기존 SSR 아키텍쳐
    1. 서버에서 전체 앱 데이터 받음(Data fetching)
    2. 서버에서 전체 앱 HTML로 렌더링해서 response로 전송
    3. 클라에서 전체 앱 JS로드
    4. HTML과 JS로직 연결 (Hydration)
    • 앱 전체를 대상으로 순차 진행되어 성능이 구렸다.
    • SSR의 목적은 근본적인 앱 로딩을 빠르게 하는것이라기보단, JS로딩 끝날때까지 빈화면 보여주는게 아니고 서버에서 렌더링한 HTML을 먼저 보여줘서 로딩 더 빠른것처럼 느껴지게 하는거임! (+ SEO)
  • 뉴 SSR 아키텍쳐
    • 앱에서 렌더링 비용이 많이 드는 서브 컴포넌트 트리를 Suspense로 감싸서 전체 앱의 Hydration을 방해하지 않고 별도로 Hydration진행
    • renderToString 대신 pipeToNodeWritable로 HTML 스트리밍.
    • React.lazy와 Suspense 모두 SSR에서 사용할 수 있게 됨
    • 이용자 친화적 Hydration
      • 레이지하게 Hydration되는중 사용자가 다른 Hydration안된 컴포넌트 클릭하면 그 컴포넌트로 Hydration우선순위 옮기고, 유저가 했던 클릭액션 기록했다가 Hydration끝나면 이벤트 바로 실행해줌

# 7/28

# React context대신 CSS Variables쓰기

https://epicreact.dev/css-variables/

  1. React context(e.g. emotion의 <ThemeProvider/>)
    • pros: 퓨어 자바스크립트라서 자유롭게 다룰 수 있음. React context써서 prop 다 내려보내지 않아도 다 접근 가능, typesafe함
    • cons: 테마 바꾸면 모든 emotion component가 리렌더링해야함ㅠㅠ
  2. CSS variable (e.g. var(--red500), getComputedStype(el).getPropertyValue('--red500'))
    • pros: styled.div등 만들 때 안에 익명함수 안만들어도됨. 걍 static하게 변수이름 박아넣기. typesafe하게 하려면 변수이름들을 따로 object로 관리하던가~.
      • body스타일 하나만 바꿔서 브라우저가 paint과정만 거침
body[data-theme="light"] {
  --colors-primary: deeppink;
  --colors-background: white;
}
body[data-theme="dark"] {
  --colors-primary: lightpink;
  --colors-background: black;
}
import "./css-vars.css";

const PrimaryText = styled.div({
  color: "var(--colors-primary)",
});

function ThemeToggler() {
  useEffect(() => {
    const [theme, setTheme] = React.useState("light");
    document.body.dataset.theme = theme;
  }, [theme]);

  return (
    <Button
      onClick={() => setTheme((prev) => (prev === "light" ? "dark" : "light"))}
    />
  );
}