읽어보았던
- 조금만 신경써서 초기 렌더링 빠르게 하기 (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픽셀이 찍힌다
- 여기서 픽셀은 물릭적인 디바이스가 표현할 수 있는 픽셀
- 디바이스가 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를 그리지 못하는 것...
- 20*20 픽셀로 그리라고 했는데 뚱땅뚱땅 계단으로 그려지는 것... (이렇게 계단으로 나온다고...)
- 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
깃헙 액션
- 파베 베포 라인을 만들기 위한 노력을 했는데
- 😭 그냥 circle이 보고 싶어지는 순간
- 참고: GitHub Actions와 Fastlane을 사용해서 React Native 앱 배포하기
-
- 단순 env 오타로 인한 액션 실패
-
- 그렇게 설치된 번들에서 오류가 발생
Your bundle only supports platforms ["x86_64-darwin-20"] but your local platform is x86_64-linux. Add the current platform to the lockfile with 'bundle lock --add-platform x86_64-linux' and try again.
- 단순하게 로컬에서 확인한
ruby -v > 2.6.3
버전이면 되지 않을까 생각했는데Gemfile.lockfile
다시 보니 오직x86_64-darwin20
🙈 - 에러 메세지 그대로 lockfile 수정 (동일한 이슈, lockfile이 해결)
- (+iOS 빌드에서도 동일한 이슈가 발생하였다... 이렇게 매번 추가해주어야한다고? 통용하는 값이 있지 않을까)
-
- 드디어 빌드로 넘어왔나 싶었더니 다시 발생한 에러 두가지 (fastlane plugin + google-service.json)
Error loading plugin 'fastlane-plugin-firebase_app_distribution': You don't have write permissions for the /var/lib/gems/2.7.0 directory.
bundle exec
로 실행하도록 하였는데, 그럼에도 계속 발생하는중- 왜지...
setup-ruby
에서bundler-cache
를 꺼버리니 된다 - 번들이 무언가 캐싱이 잘못되었나?
- google-service.json 을 올릴 수 없지 않나 > 시크릿으로 만들어버린다
-
- iOS 빌드만 올라가면 되는데
provisioning profile
이 없다
- iOS 빌드만 올라가면 되는데
- 그러나... 되지 않는다....
- 기존에 xcode에 던지던 mobileprovision으로는 빌드가 되지 않았다 왜지 ⁉️
~/Library/MobileDevice/Provisioning Profiles
에서 직접 빌드에 사용한 mobileprovision에서 뽑아가니 정상적으로 빌드 성공
viewport
100vh
로 잡아두었더니 모바일 주소창이 있어서 레이아웃이 맞지 않는다- 이거 무언가 설정 바꿔줘야겠다고 생각하고 시간이 흘러가는중
- 우연하게 보게된 뷰포트 관련 스레드
- 뷰포트 단위가 여러개 있는데 svh, dvh가 쓰고 싶다
- 언제쯤..!