문제해결

[bfcache] - vanila + vite 환경에서 공용으로 쓰는 header html을 재사용

hyeeoooook 2026. 1. 22. 19:07

원인

 

 

header.html을 제작하고 이를 fetch 함수를 통해서 가져오려고 하였다.

그냥 정적인 html이라면 상관이 없지만 내가 제작한 header는 각종 버튼에 기능까지 추가가되어 JS코드가 꼭 필요한 컴포넌트중 하나였다.

 

때문에 header에 넣되 각 페이지마다 필요한 JS 코드의 순서와 DOM의 실행순서를 지켜서 제작을 해야하는 어려움이 있었다.

 

모두 완료가 되었을때 한가지 간과한것이 bfcache 이녀석이다.

 

사용자가 페이지를 뒤로가거나 앞으로 넘길때 페이지에서 동작하는 JS코드나 랜더링 등등을 잠시 멈춰두고 다시 돌아왔을때, 멈춘 위치에서부터 다시 시작하는것이 문제였다.

 

 


과정

 

생각해본 방법

  • JS 파일을 다시 모듈화 하여 진행한다.
  • 직접 bfcache를 조작한다.
  • Timeset을 써서 직접 조작한다.
  • 서버를 개설해서 서버사이드 랜더링을 통해 HTML을 불러온다.
  • map을 통해 직접 구현한다.
  • vite 환경이므로 raw를 사용해본다.

 

물론, 이 생각을 하기까지 정말 무수히 많은 코드를 지웠다, 만들었다를 반복했다.

나는 현실적으로 vite 환경임을 고려하여 가장 빠른 길을 선택했다.

 

1. JS 코드를 다시 모듈화 하는것은 시간이 걸릴 뿐더러 기존에 잘 작동하던 내용들을 다시 손봐야하는 단점이 있었다.

구조 설계도 매우 어려울뿐아니라 이건 정말 잘못되면 시간이 얼마나 뺏길지 모르는 상황이라고 생각했고, 처음 구조 설계를 했던 이유가 있기 때문에 굳이 선택하고 싶지 않았다.

 

2. bfcache를 직접 조작하는 행위는 어떻게보면 가장 직관적이고 간단하지만 코드위에 코드를 덮어씌우는 행동이라고 생각했다.

설계에 문제가 있다면 그 설계를 바라보는것이 개발자라고 생각하기 때문에 결코 선택하지 않았을 선택지다.

 

3. Timeset도 마찬가지이다. 지금 상황에서 사용을 하게 된다면 나중에 데이터가 커졌을때, 걷잡을수 없을정도로 유지보수가 어려워질 수 있음을 생각해보았다.

 

4. 서버를 개설해서 서버사이드 랜더링은 사실 어떻게보면 가장 현명한 선택일 수 있다고 생각하지만 이건 어디까지나 개인 블로그 및 나라는 사람을 보여주기위한 프로젝트라고 정의를 했기 때문에 선택하지 않았다.

 

5. map을 통해 직접 구현하는건 하드코딩과 다를게 없다. 이건 그냥 이런 생각이 흘러갔다 라는 과정중에 일부이다.

 

마지막으로 vite환경의 장점을 살리고자 raw를 사용한 방법이다.

 


결과

 

결과적으로 매우 짧은 코드로 완성했다.

import headerHtml from "../../pages/header.html?raw";

document.body.insertAdjacentHTML("afterbegin", headerHtml);

 

여기서 raw 코드는 vite에서 지원해주는 html을 문자열로 치환하여 가져오는 API중 하나이다.

 

기존 JS 코드에서 가져오려면 fetch를 사용해 .then..어쩌고 저쩌고 하면서 함께 포함할 동적 스크립트 코드또한 import 해야하는 번거로움 뿐만아니라 이건 말그대로 HTML 단계가 아닌 JS 단계이므로 렌더링에서 후순위를 가지고 있는 반면 vite API는 DOM이 생성되기 전에 먼저 html에 랜더링 하는것을 알았다.

 

때문에 먼저 랜더링 되어있는 header의 요소들을 잘 찾아서 JS 코드로 동작이 가능하다는 설계와 동시에 해결을 할 수 있었다.

 

이렇게 하나 하나 모든것을 컴포넌트화 하고 싶었지만, 이럴거면 React를 쓰고 말지... 라는 생각과 동시에 나는 vanila의 영역에서 개발을 진행중이니까 최대한 모던하게 진행하는것에 의미를 두자라는 생각이 들었다 ㅎㅎ