사용자가 가입 전에 글 하나를 작성하고 저장해볼 수 있는 체험 기능을 웹앱에 구현했습니다. 먼저 서비스를 경험한 뒤, 추가로 기록하고 싶을 때 가입하도록 유도하는 구조였습니다. 가입 전 기록은 브라우저의 localStorage에 보관하고, 가입할 때도 그 기록을 잃지 않고 이어갈 수 있도록 하고 싶었습니다. 그런데 저장할 수 있는 글이 하나라고 해서, 사용자가 탭도 하나만 열어두는 것은 아닙니다. 여러 탭에서 저장을 시도하더라도 기존 기록을 보호해야 했고, 한 탭의 저장 및 삭제 결과를 다른 탭의 화면에도 반영할 필요성이 따라왔습니다. 화면의 변경을 반영하는 데는 storage 이벤트를 사용하고, 저장 직전에는 현재 데이터를 다시 확인했습니다. 확인부터 쓰기까지의 작업 순서도 보호하기 위해 Web Loc..
최근 프로젝트를 진행하며 iOS Safari와 Chrome 환경에서 화면이 깜빡이거나 요소가 사라지는 기묘한 버그들을 마주했습니다. 원인을 파악해 보니 모두 WebKit 엔진의 GPU 컴포지팅(Layer Compositing) 처리 방식과 관련이 있었는데요. 문제를 해결하며 배운 과정을 공유해 봅니다. 사례 1: 잘 보이던 요소가 갑자기 사라지는 현상문제 상황바텀시트 내 콤보박스에서 검색을 두번 이상 반복했을 때, 선택된 항목이 화면에서 갑자기 사라지는 현상이 발생했습니다. 과정1. 로직 확인처음엔 선택된 항목들이 의도치않게 초기화되는 등의 문제가 있을 거라고 생각했지만, 로그를 찍어 확인한 결과 데이터는 멀쩡한 것을 확인했습니다. 2. DOM 검사선택한 데이터는 제대로 관리되고 있다는 것을 확인한 후,..
최근 scale 애니메이션이 적용된 컨테이너 내부에서 absolute 요소가 마운트 시점에 다시 그려지는 버그가 있었는데, 레이어 합성 타이밍 문제로 원인을 파악하면서 브라우저가 화면을 그리는 과정을 제대로 이해해보자는 생각이 들었다 이 글은 Parse부터 composite까지의 렌더링 파이프라인과 헷갈리는 개념이었던 Reflow/Repaint, 합성 레이어까지 이해하는 과정을 정리했다 브라우저 렌더링 파이프라인 1) Parse- 브라우저는 HTML 파일을 파싱해 DOM tree, CSS 파일을 파싱해 CSSOM tree를 생성한다 2) Layout- DOM + CSSOM 트리를 조합해 렌더 트리를 생성하고, 렌더트리를 활용해 레이아웃을 계산한다- 즉, 각 요소의 위치와 크기를 계산해 화면의 어디에 위치..
퀴즈를 제작하는 폼에서 선택지를 입력하는 컴포넌트를 개발하면서, 사용자가 입력하는 텍스트 길이에따라 input의 너비가 자동으로 조정되는 기능이 필요했습니다. 그 과정에대한 간단한 기록입니다! 시도 1 - css ch 단위 이용처음에는 단순히 CSS의 ch 단위를 활용했습니다. ch 단위는 현재 사용중인 폰트의 '0' 문자 너비를 기준으로 하는 단위로, 문자 개수에 비례한 너비를 설정하기위해 활용하고 현재 폼에 react-hook-form을 사용하고 있었기 때문에 watch를 사용해 입력된 값을 확인했습니다. const inputValue = watch(`problem.item`);// 텍스트 길이에 따라 너비 계산const inputWidth = Math.max(15, (inputValue?.lengt..
문제Next.js 14를 사용한 프로젝트에서 Github Actions로 빌드, 스토리북 테스트를 진행하고 있는데 Github Actions 빌드 환경에서 File을 찾을 수 없다는 에러가 발생했습니다. ReferenceError: File is not definedError: Failed to collect page data for /lectures/[lectureId]/question 로컬 개발 환경이나 빌드 상황에서는 정상적으로 동작하고, CI 환경에서만 발생하는 상황이었습니다. 시도 1 (해결 X)유일하게 prefetch를 하는 페이지였고, File을 서버컴포넌트에서 사용하려는게 문제가 됐나보다 추측하고 서버 환경에서 File을 정의하거나 CI 환경에서 prefetchQuery를 진행하지 않도록..