# 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의 일부가 추가
- 상태 업데이트의 분류
- 긴급(Urgent) 업데이트: 타이핑, 스크롤링 등 직접적인 상호작용. 즉시 안나타나면 이상
- 전환(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 아키텍쳐
- 서버에서 전체 앱 데이터 받음(Data fetching)
- 서버에서 전체 앱 HTML로 렌더링해서 response로 전송
- 클라에서 전체 앱 JS로드
- 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/
- React context(e.g. emotion의
<ThemeProvider/>
)- pros: 퓨어 자바스크립트라서 자유롭게 다룰 수 있음. React context써서 prop 다 내려보내지 않아도 다 접근 가능, typesafe함
- cons: 테마 바꾸면 모든 emotion component가 리렌더링해야함ㅠㅠ
- CSS variable (e.g.
var(--red500)
,getComputedStype(el).getPropertyValue('--red500')
)- pros:
styled.div
등 만들 때 안에 익명함수 안만들어도됨. 걍 static하게 변수이름 박아넣기. typesafe하게 하려면 변수이름들을 따로 object로 관리하던가~.- body스타일 하나만 바꿔서 브라우저가 paint과정만 거침
- pros:
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"))}
/>
);
}