JIGGAG

3월 한달동안 로그

2022년 4월 7일

읽어보았던

  • 조금만 신경써서 초기 렌더링 빠르게 하기 (https://toss.tech)
    • 렌더링 개선해야하는데 잘 안되고 있다
    • 그러다 흘러들어간 포스팅
    • 웹 어플리케이션을 타켓으로 설명하고 있지만 혹시 도움을 얻을만한 것이 있을까하며
    • 초기 렌더타임에 그려줄 수 있는 것을 그려주는 것이 포인트라고 생각한다
    • 이것을 이미 스켈레톤으로 보여주고 있는데, 애초에 너무 많은 것을 담으려고 하고 있어 퍼포먼스 자체가 나오지 않는다...
    • 대응할 수 없어서 슬픈 이야기
  • 타입스크립트 never (https://ui.toast.com)
    • 실제로는 써본적이 없는데 타입챌린지 하면서 가장 많이 쓰게 된 never
    • 타입스크립트에서 never 타입은 값의 공집합이다. > 집합에 어떤 값도 없기 때문에, never 타입은 any 타입의 값을 포함해 어떤 값도 가질 수 없다
    • 남아있는 것은 never이다 -> 엄격하게... 조건 처리
    • 절대 도달하지 못하는 곳은 never
    • 그 외에 유니온, 키값으로 never 타입을 사용해 없애버릴 수 있다는 것이 유용했다
    • 문제의 never는 never
    • never를 할당하려하면 그건 never라서 never가 나온다 🙈

3/27 ~ 3/31

  • 처음 긴 휴가
  • 이것저것 해보고 싶었는데 맘에 드는 날씨가 3분의 1 정도 있었다
  • 그건 핑계일까
  • 그냥 쉬었다 쉬고 쉬고
  • 휴가를 휴가답게 휴식 휴식 휴식 했으니 끌어올려야지

fabric

  • 0.68.0-rc.4 도입해보려고 했더니 바로 0.68.0 이 나와버렸네
  • c++로 동작하는데 RNStarter는 코틀린, 스위프트...
  • 특히나 스위프트 AppDelegate에 적용하는게 까다롭겠는데
  • 브릿지를 새로 만들어야하려나
  • 참고

표현식

  • falsy && jsx 표현식
  • 이러면 앱이 죽는다!!!
  • 0 && <Comp />는 문제가 될 수 있으니 항상 불리언으로 처리해주어야하는데
  • 조건 ? <Comp /> : null 은 명확하게 보이기는 하는데 개인적으로 좋아하지 않는다.. 🤔

3/20 ~ 3/26

타입

  • typechallenge 하다보니 다시 찾아보게 되는 타입
  • key in (End & string)
    type TupleToNestedObject<T, U, R = U> = T extends [...infer Start, infer End] ? End extends string ? TupleToNestedObject<Start, U, {
      [key in End]: R
    }> : R : R
    
    =>
    
    type TupleToNestedObject<T, U, R = U> = T extends [...infer Start, infer End] ? TupleToNestedObject<Start, U, {
    	[key in (End & string)]: R
    }> : R
    
    • End 의 유니온 키값으로 뽑아낸 key 가 string 타입이라고 보장해주었다
    • key in End 만 했을때, key가 어떤 타입인지 알 수 없는데 이 값을 키값으로 사용하려고 하면 타입 오류가 발생하니깐
  • K in keyof T as T[K] extends U ? K : never
    type PickByType<T, U> = {
      [K in keyof T as T[K] extends U ? K : never]: T[K]
    }
    
    =>
    
    type PickByType<T extends Record<string, unknown>, U> = {
      [K in (keyof T & string) as (T[K] extends U ? K : never)]: T[K]
    }
    
    • K in keyof T로 뽑아낸 키를 T[K] extends U ? K : never 타입으로 assertion 해준 것
      • 키값을 never가 들어가면 해당 키는 없는 맵이다
      • 제네릭 타입을 정의했더니 위의 타입 케이스와 유사하게 만들 수 있었다

3/13 ~ 3/19

픽셀

  • 문제의 0.5px
    • 디바이스가 400ppi 라면 1인치에 400픽셀이 찍히지만 600ppi 라면 1인치에 600픽셀이 찍힌다
      • 여기서 픽셀은 물릭적인 디바이스가 표현할 수 있는 픽셀
  • 픽셀의 밀도가 다르다
  • 그래서 같은 40px을 그리더라도 디바이스마다 밀도가 다르기 때문에 깨져보이게 된다
    • 픽셀 밀도가 높을수록 더 세밀하게 표현할 수 있기 때문에
  • 이미지를 @x1,2,3으로 뽑아내는 이유가 여기 있다
    • 이미지를 각각 해상도에 맞춰서 배수로 뽑아낸다
    • 디바이스 밀도에 따라 이미지 사이즈가 100100, 200200, 300*300 각각 적용
    • 실제 화면에 보여지는 크기는 똑같지만 디바이스의 물리적인 픽셀이 다르게 적용되는 것이다
  • SVG는 벡터로 그려지기 때문에 밀도에 영향을 받지 않는다
    • 벡터를 렌더링하기 위해 픽셀로 변환하는 작업을 래스터화
  • RN에서는 px을 입력 받아 안드로이드 > dp, iOS > pt 각각 변환하게 된다
    • 0.5px을 입력했을때, 각각 디바이스 해상도에 따라 변환된 값으로 그려내게 된다
    • 하지만 해상도가 낮은 디바이스에서 입력된 0.5px을 실제로 디바이스가 표현해낼 수 있는 dp 보다 낮은 값이 되어버린다면 최소값으로 들어가게 되겠지?!
    • 그럼 아무리 0.5를 입력해도 0.5를 그리지 못하는 것...
  • device pixel ratio
    • 0.5px을 그리라고 입력했다
    • 디바이스는 1배수, 3배수 두가지로 테스트하였다
    • 1배수 디바이스에서는 0.5px을 그리기 위해 물리적으로 픽셀을 0.5만큼 그렸다
    • 3배수 디바이스에서는 0.5px을 그리기 위해 물리적으로 0.5 * 3 = 1.5만큼 그렸다
    • 원이 수많은 점을 이어서 표현하는 것처럼 3개의 픽셀이 1개의 픽셀로 표현한 것보다 부드럽다

React Docs: Hooks

  • 아래 useRef 보다가 참고 리액트 문서를 따라 들어갔고 그러다 훅을 한번 더 보고 있었는데
  • 요즘 부딪히고 있는 문제들을 해결할 수 있는 무언가 찾을 수 있을까하며
  • 궁금해서 해보고 싶은 것들을 찾아보았다
  • onLayout을 ref로 대체할 수 있을까?
  • initialState에 고비용 계산식이 들어간다면?
    • 렌더타임마다 매번 계산하고 있다
    • state 업데이트는 되는게 아니라 리렌더를 유발하지는 않겠지만
    • 불필요하다
  • 메모이제이션 햇으나 결국 매번 리렌더 타는 경우 해결법
    • useCallback을 했으나 디펜던시 때문에 매번 리렌더 되는 상황
    • 무적의 ref
    • 그러다 갑자기 떠오른 useImperativeHandle에 디펜던시 설정을 안해줬으니 리렌더가 계속 되고 있었지..
  • [useEffect vs useLayoutEffect]
    • 시점 문제로 useLayoutEffect를 사용하는 경우가 있다
    • 렌더링 되기 전에 미리 계산 되어야하는 것을 처리하도록 했는데
    • 동기적으로 !?? 😱
    • 먹통이 되어보이는 문제는 여기일까?
    • 아 아닌데
    • useLayoutEffet에서 화면 자체를 막고 고비용 계산을 동기적으로 처리
    • 그리고나서 렌더링 되고 useffect가 실행되는데
    • useEffect 조차도 무거운 계산이라면???

useRef

  • useRef 사용하다보면 타입이 맞지 않는 경우가 있다
  • 관련해서 제대로 이해할 수 있도록 도와준 블로그
  • 초기화를 해준 경우 MutableRefObject 타입을 갖고 초기화를 하지 않고 사용한 경우에는 RefObject 타입을 갖는다
  • 이 차이는 ref를 사용하려는 목적 을 생각해보니 이해할 수 있었다
  • 일반적으로 DOM을 제어하기 위해 ref를 사용한다 (const ref = useRef(null);)
  • 이후에 값을 의도적으로 변경하려는 목적이 아니라 판단할 수 있으므로 이 경우 타입은 RefObject 이다
    • ref.current 자체는 변경할 수 없다
    • ref.current.* 하위 객체는 변경할 수 있다
    • const와 let처럼
  • 반대로 DOM 제어가 아닌 리렌더를 유발하지 않는 변수로써 ref를 사용한다면 (const ref = useRef<number>(0);)
  • ref가 담고 있는 타입과 초기값을 설정하게 되고 MutableRefObject 타입을 갖는다
    • ref.current 자체를 변경할 수 있다
  • 그렇다면 내가 겪은 타입 에러의 원인은 어떤 부분을 잘못 사용했던 것일까
  • DOM ref로 사용하려고 하였다 (const ref = useRef();)
    • 이렇게 사용하는 것을 조심하는게 어떨까
  • 하지만 DOM의 타입은 RefObject 인데 내가 전달하고 있는 ref의 타입은 MutableRefObject 였다

3/6 ~ 3/12

BFF

  • 지난 1월에 BFF 라는 모델을 처음 봤었는데 (1월 한달동안 - Backends For Frontend)
  • 당시 MSA API > BFF > APP 백엔드에서 구성해주면 좋겠다고 생각했다
  • 쉽게 가려고 했다 🙈
  • 그러나 이번에 카카오페이지는 BFF(Backend For Frontend)를 어떻게 적용했을까? 를 보고 나니
  • 클라이언트에서 필요한 모양으로 직접 프론트엔드 개발자가 구현하는 것이 이상적인 형태가 될 수 있겠다
  • 그런 꿈과 같은 희망과 짧은 시간이 흐르고 nextjs + graphql 조합을 보았다
  • 아 이게 BFF 였는데, 멀리서 찾아보려고 하고 있었네

SVG

  • 그냥 피그마에서 꺼내다 쓰려고 했는데
  • 사알짝 필요한 포인트가 다른다
  • 요청하면 되겠지만 어느정도 커스텀 할 줄 알면 좋을듯하여
  • 그래서 전에 읽었던 글이 떠올라 다시 찾아갔다
  • width, height는 정말 딱 SVG 도형이 그려지는 캔버스 사이즈이고 viewBox캔버스 내부 좌표계이다
  • 만약 width="300" height="300" viewBox="0 0 100 100" 라면
  • 실제 우리 눈에 보이는 이 SVG 박스의 크기는 300300 이지만 내부적으로는 100100 좌표계로 동작한다 (참고: 포스팅)
  • 캔버스 안에 그려진 도형 (Path, Circle) 등은 viewBox 좌표를 기준으로 잡혀있는 것이다
  • 따라서 SVG width, height를 변경하면 도형의 모양 자체는 유지되지만 좌표 기준이 달라지게 되면서 viewport 바깥으로 사라져버릴 수 있다
  • 그럼 사이즈를 줄임과 동시에 viewBox 내부 좌표계를 이동시키면 어떨까?
  • 사이즈와 좌표 비율을 잘 계산한다면 벡터를 위로 올리고 사이즈를 최소화하는 것도 가능할 것 같은데...
  • Path 값을 전부 바꿔야한다고 🙈
  • 생각하다보니 정확한 값을 위하여 다시 요청하는게 좋겠다

3/1 ~ 3/5

깃헙 액션

viewport