JIGGAG

4월 한달동안 로그

2023년 5월 6일

4월 한달동안

  • 아쉬운점
    • 선택과 집중을 했음에도 불안해했던 것에 반성
  • 잘한점
    • 시간을 작게 사용해보았다
      • 그랬더니 실행하는 것도 작아졌다!
      • 오잉 이건 단점인걸까 (작은 시간만큼 작은 사이즈의 무언가를 할 수 있다)
    • 이번달에 집중하고 싶었던 것이 있었다
      • 집중에 성공했다
      • 얻고 싶은 결과를 얻지는 못했지만 그럼에도 잘한점으로 두고 싶다
  • 개선할점
    • 컨디셔닝도 필요하다는 것
    • 크게 뭉쳐서 월간 계획 보다 주간 계획으로 가는게 좋겠다
      • 너무 세밀할 필요는 없지만 너무 크게 보고 있는듯하여

요즘

  • 노는거니
  • 그렇다면 최선으로 놀아야지

리액트 실험실

  • [번역] 리액트 실험실: 그동안의 작업 - 2023년 3월
  • 아무래도 관심이 이끌리는 것들 React Optimizing Compiler, Offscreen Rendering
  • 어디선가 스레드에선가... 본 적이 있는 앞으로 리액트 자체가 메모이제이션을 신경 안써도 되는 것을 해준대!
  • 그것이 바로 이 컴파일러 React Forget 였다
  • 상태 변화에 따른 리렌더링 하는 리액트의 반응성은 너무 섬세했다
  • 그래서 직접 메모이제이션을 통해 최적화를 진행하였는데, 객체 비교 연산을 위해 더 위에서 이 객체 자체를 메모이제이션 해야하는 작업들이 추가로 필요하다
  • React Forget이 하려는 것은 이러한 추가 작업 없이 리액트 자체가 유의미한 변화에만 반응하도록 하는 것이다
    • 🥳
  • 그 다음 관심이 가는 오프스크린에서 렌더링 시키는 것
    • 백그라운드에서 렌더링 하되 컴포넌트 이펙트는 기존 코드 방식과 동일하게 동작해야한다
  • 예를 들면
    • 탭을 자주 이동하는 경우를 대비에 미리 다른 탭의 화면을 렌더링 시켜둔다던지
    • 현재 띄워져있는 모달 백그라운드에 포커스 되어있지 않은 화면에서의 이벤트를 비활성화한다던지
    • 지금은 미리 렌더링 시키기 위해 일부만 마운트 시키도록 강제로 호출한다던지
    • 포커스 되어있는 상태에만 진행하도록 조건이 추가되어있다던지
  • 여기서 좋았던 부분은 직접 오프스크린 API를 사용하는 것이 아닌 route/navigation API에서 사용하게 한다는 점
    • 지금과 동일하게 신경 쓸 것은 없는데
    • 갑자기 신경쓰고 싶은 부분
    • 오프스크린에서 전혀~ prerender 하고 싶지 않은 경우에는 이 옵션을 끈다던지 할 수 있을까?
  • 기존에 동작하는 리액트 사이클을 깨뜨리지 않고 미리 렌더링만 시키거나 이벤트를 비활성화 하는 것을 구현하는게 가능하려면?
    • 리액트 내부에 새로운 이펙트가 생기는건 아닐까...?

OCR

  • 한참 전에.. 만들었던 OCR 기능이 있었다
  • 잊고 지냈는데 오픈API가 종료 되기 직전이다...
  • 첫 사용자 리뷰를 받았던 좋은 추억이 있는 친구인데
  • 우선 구현이라도 변경해두어야하나...
  • 그러나 이제 이 서비스는 개인/법인 사업자만 이용할 수 있나보당 🥺

useMemo를 언제 쓰면 좋을까

  • 참고: (번역) useMemo를 사용하는 것을 당장 멈추세요!
  • useMemo를 언제 써야하는지에 대한 아티클이 많이 보인다
    • 항상 많았지만 그냥 필요할때 보이는 것...!
  • 원시값을 제외하고는 대부분 useMemo로 처리하고 있다
  • 그러면 항상 돌아보는 한마디
    • 성급한 최적화
  • useMemo를 왜 사용할까?
    • 복잡한 계산을 캐싱해두기 위함이다
  • useMemo는 렌더링 단계에서만 값을 제공한다는 것
    • 초기 렌더링 시점에는 아무것도 캐싱되어 있지 않다는 것이다
    • useMemo를 쓰던 안쓰던 최소 1회의 연산은 무조건 필요로 한다
  • 계산이 복잡한지 어떻게 알 수 있을까?
    • 위에서 이야기한 원시값을 제외하고는 useMemo를 쓰고 있는데, 이 계산이 복잡한게 맞는지 검증해보지는 않았다
    • 이미 컨테이너/컴포넌트 단계에서 복잡한 뎁스를 갖고 있고 그 안에서 일어나는 사소한 연산도 비용이 되리라 생각했기 때문이다
  • 컨테이너/컴포넌트가 잘 memo 되어있었다면 고민하지 않아도 될 포인트 아닌가?
    • 컴포넌트 자체가 리렌더 되지 않는데, 그 아무리 복잡한 연산이더라도 useMemo를 쓸 필요가 없다
    • 최초 1번은 무조건 연산을 해야하니 그 이후로 useMemo로 캐싱하는 것을 불필요한 메모리 점유이다
  • 이 내용들과 반대로 아무리 최적화를 해도 항상 리렌더 되어야만 하는 컴포넌트가 있을 수 있다
    • 또는 수많은 의존성을 갖고 있어 항상 새로운 값을 계산해야만 하는 경우
    • useMemo로 연산을 저장하고 있어도 다시 새로 계산해야하므로 이전 값을 불필요하게 저장하고 있는 것이다
    • 이러한 경우에도 useMemo 효과를 얻지 못한다
  • useMemo를 쓰지 않아도 되는 경우를 다시 정리해보면
    • 너무나 연산이 간단한 경우
    • 절대 다시 연산이 될 일이 없는 경우
    • 항상 새로운 연산을 필요로 하는 경우
  • 이러한 내용은 전에도 돌아본 것 같은데, 또 다시 돌아본다
    • 다음에 또 돌아보겠지 🥺

리액트 훅 대신 시그널

  • 참고: React 훅은 실수일까요?
  • 클래스 컴포넌트에는 마운트된 컴포넌트당 하나의 인스턴스가 있지만 함수 컴포넌트에는 렌더당 여러 개의 인스턴스가 있다
  • 이 문제를 해결하기 위해, 함수 컴포넌트에서 여러 인스턴스 간 데이터 공유를 위해 useRef를 제공한다
    • 클래스 컴포넌트에서는 문제가 되지 않았던 것들이 함수 컴포넌트에서는 문제가 되고 있다는 것
    • 그러나 이 useRef는 렌더링에 영향을 주지 않기 때문에 온전히 함수 컴포넌트의 문제를 해결하고 클래스 컴포넌트처럼 동작할 수 없었다
  • 그리고 나오는 시그널
  • const FunctionComponent = memo(() => {
    	const [count, setCount] = createSignal(0);
    	return <Text>{count()}</Text>
    });
    
  • ref로는 함수 컴포넌트에서 렌더 타임에 생성된 모든 인스턴스에서 데이터를 공유할 수 있지만, 화면에 업데이트를 할 수 없다는 단점이 있었는데
  • 이를 해결하는 시그널은 count() 함수를 호출하면 ref처럼 최신 값을 가져오고 반영한다
    • ref + state 완전체 🤔
  • 매번 새로운 함수를 호출하고 그에 대한 결과를 반영하기는 하지만
    • 렌더링 자체가 다시 되지 않고 그냥 참조된 값을 보여주기만 하는 것인데
    • 이 값이 어떤게 될지 어떻게 안전하게 쓸 수 있을까?
  • 참고: 추가로 읽어보는 리액트와 시그널
    • ref + state 완전체라고 생각했던 것이 이미지로 정리되어있는데
    • ref + state + useMemo - rerender
    • 이것만 봤을때 시그널은 완벽해보인다
    • 항상 문제가 되는 리렌더 이슈도 없을 것이고 최적화는 물론이고 상태 공유까지 자유롭다면 더 고민해봐야할까?

로컬 우선 소프트웨어

  • 참고: 로컬 우선 소프트웨어가 있다면 어떨까요?
  • 처음 이 글을 접했을때에는 눈에 잘 들어오지 않았다
  • 그리고 이번에 다시 보게 된 이유는
    • 지금 내가 로컬을 우선하는 작업을 하고 있기 때문이다 🙈
    • 무엇이든 겪어야 이해한다는 슬픈 사실
  • 로컬을 우선한다니
  • 3G는 지나가고 4G가 5G를 넘어가는 이 시간에 왜 로컬을 우선해야할까?
  • 이런 생각을 하고 있었다
  • 모든 사용자는 빠르고 풍족한 네트워크를 사용하고 있지 않다
    • 가까이에 있다...
  • 여유가 되는 상황에서 저장해두고 언제든 이용할 수 있는 소프트웨어
  • 실시간으로 협업을 해야하는 경우가 아니라면 대부분 로컬 기반으로 동작하게 할 수 있겠다
  • 특히 개인화된 서비스인 경우 실시간으로 동기화를 해야할 필요는 없으니?
  • 예외 케이스로 다중 기기를 사용하는 사용자가 있는데
    • 요즘은 흔한 케이스라고 생각하며 이를 어떻게 대응할까...
  • 생각안난다!
    • 모든 사용자가 git 방식을 이해하리라 기대할 수 있을까
  • 결국 네트워크는 필요하다
  • 다만 최소화하는게 어떨까~ 하는 의견으로 읽어본다

자바스크립트 메모리 관리

  • 참고: 자바스크립트 메모리 관리
  • 관리해야겠다는 생각은 해보지 못했다
  • 알아서 잘 해주고 있겠지 하는 믿음으로
  • 그렇지만 WeakMap, WeakSet으로 대체할 수 있다면 써보고 싶다는 생각만 해보고
    • 아직 해보지 못한건 언제나 그렇듯~
  • 참고: useEffect에서 promise에 참조된 경우
    • 언마운트된 컴포넌트에서 setState 하면 경고가 뜨는 것은 본 적 있다
    • 그렇다면 언마운트된 컴포넌트에너 프로미스가 살아있다면?
    • 이것도 리스너와 같은 느낌으로 프로미스를 끊어줘야겠는걸