깐부 프로젝트를 통해 특정 UI 컴포넌트를 만들던 중 공통적으로 다뤄야 했던 웹 페이지 초기 로딩 이슈가 가볍게 생각할만한 이슈가 아니라고 느꼈고 이를 잊지 않기 위해 시도했던 방법들, 정답이라고 단언할 수 없지만 나름의 해결책들을 정리하고자 이 글을 작성하게 되었습니다.
만약 특정 상태 값을 활용하여 페이지의 변경사항을 적용해야 할 때 변경사항이 transition
과 밀접한 관계가 있다면 transition
은 무조건 발생하기 때문에 transition
을 명시적으로 없애주지 않는 이상 해당 이슈는 존재할 수 밖에 없는 이슈였습니다.
/* 트랜지션 취소 */
.notransition {
transition: none !important;
}
이는 결국 어떻게 명시적으로 transition
을 삭제했다가 어느 시점에 다시 transition
을 살려줄 것인가를 해결하면 되었던 문제였기에 transition: none !important;
속성 값을 갖는 .notransition
클래스와 DOMContentLoaded
이벤트를 활용하여 DOM의 로드가 끝났을 때 transition
을 강제적으로 취소하고 DOM이 로드되고 리소스까지 로드되야 발생하는 load
이벤트에서 다시 transition
이 일어나도록 시점을 구분하여 해당 문제를 해결하였습니다.
setInterval
타이밍 함수는 두번째 인수로 delay
값을 전달 받는데 이를 초기에 제대로 파악하지 못하여 발생했던 이슈입니다.
movementTime(); // call immediatly
setInterval(movementTime, 1000);
때문에 setInerval
타이밍 함수에 전달되는 콜백함수를 초기에 한번 호출하여 해당 문제를 해결하였습니다.
테마를 적용하여 렌더링할 때 기존 테마가 변경되어 깜빡거리는 현상
페이지가 다시 로드 될 때 JS는 localStorage에서 선택 항목을 가져와 적용하는데 JavaScript는 종종 CSS 이후에 실행되기 때문에 "Flash Of Incorrect Theme"(FOIT)가 발생합니다.
페어와 프로그래밍을 진행하며 사용자가 저장한 다크모드값과 시스템을 모두 확인하는 컴포넌트를 만들고자 하였기에 LocalStorage
와 OS레벨의 다크모드를 감지할 수 있는 matchedMedia()
메서드 모두 사용해야 했는데 LocalStorage
를 사용하면 발생할 수 밖에 없는 FOIT
현상을 어떻게 해결할지가 난관이었습니다.
제시되는 해결책 중에 PHP를 통해 쿠키를 사용하여 서버측에서 해결하는 방법도 있다고 소개하지만 저희는 JS로 해결하고자 하였기에 해당 방법은 선택하지 않았습니다.
페어와 토의를 한 결과 DOM이 생성되고 Dark mode
를 관리하는class
가 추가되는 것이기에 렌더 시점을 파악하여 문제를 해결해야한다고 생각하여 DOM
이 완전히 생성되기 전을 관리하는 js
파일을 HTML
문서의 body
상단에 script
태그의 src
어트리뷰트에 적용하여 문제를 해결하였습니다.
위의 방식으로 해결하면서도 script
태그의 위치로 문제를 해결했다는 것이 정답은 아니라고 생각하여 타 페어들과 강사님에게 조언을 구해 다른 방식으로 해결하고자 하였고 렌더 시점을 조작하는 것이 아닌 rendering delay를 통해 해결해야 한다는 사실을 알게되어 다크 모드
가 적용되기 전까지 화면을 제공하지 않는 것으로 문제를 해결하였습니다.
해당 이슈는 레이아웃을 계산 할 때 상대적으로 늦게 로드되는 font
로 인한 이슈였는데 height
값으로 조정되는 아코디언이 CSS가 로딩되는 타이밍으로 인해 간헐적으로 height
값이 어긋나게 되었습니다.
초기에 아코디언을 열러있는 상태로 렌더링할 때 평소처럼 DOMCotentLoaded
이벤트를 사용하는 것이 아닌 CSS리소스까지 모두 받아온 후 발생하는 load
이벤트를 사용하여 height
의 어긋남을 해결하였습니다.