바닐라 자바스크립트로 프로젝트 해봐야지... 해봐야지 생각만 하고 미루던 걸, 드디어 이번 기회에 해보았습니다. HTML도 최소화하고(body 태그 안에 단 10줄!), 온전히 자바스크립트 문법만 활용해서 개발했습니다. 많은 추가 기능 구현보다는 코드의 가독성에 가장 중점을 두고 작성하였고, 단일 책임 원칙(Single Responsibility Principle)도 지키려 노력했습니다(그런데 작게 안 나눠지더라고요 ㅠㅠ 더 노력해야겠습니다). 작게는 변수명부터 크게는 함수를 선언하는 위치와 코드를 읽는 시선까지 고민해 봄으로써 유익한 공부가 된 것 같습니다.
※ 개인 미니 프로젝트_영화 검색 사이트(Vanilla JS)
구현 목표 예시 사이트가 있고 꼭 사용해야 하는 '필수 요구사항'과 개인적으로 추가하는 '선택 요구사항'이 있었습니다. 다양한 추가 기능이 떠올랐고, 적용해보려 했지만 코로나 + 예비군으로 인해 늦게 프로젝트를 시작하게 되면서 원하는 기능을 모두 구현하진 못했습니다.
📌 필수 요구사항
- 바닐라 자바스크립트만 사용
- TMDB API 사용
- 영화정보 카드 리스트 UI → 클릭 시 영화 id가 alert
- 영화 검색 기능
- 지정된 JS 문법 및 DOM 조작 활용
📂 폴더 구조
🛠️ 추가 기능구현
- 웹사이트 랜딩 또는 새로고침 후 검색 입력란에 커서 자동 위치
- 대소문자 관계없이 검색 가능
- 카드 animation 추가 → 카드 mouse hover시 '평점'과 '영화 설명' 보이도록 구성
- header logo 클릭 시 '메인 화면으로 돌아가기' 및 '페이지 맨 위로' 기능(단일 페이지 기준)
- 반응형 ui로 구성
⌨️ 주요 코드 구조
1. index.html
- 헤더까지 js로 구현하기엔 조금 무거워지는 듯하여 HTML로 작성
2. main.js
2-1. window.onload()를 통해 DOM이 모두 그려진 다음 input 입력창에 커서를 자동 위치
2-2. 헤더에 위치한 로고에 새로고침과 맨 위로 이동하는 기능을 추가해, (단일 페이지에서) 메인 페이지로 이동하는 효과
2-3. search 기능을 또 다른 js로 기능을 나누어 작성할 경우 최초 렌더링 시간이 3초를 초과해 main에 작성함.
3. getApi.js
- api를 호출하는 부분은 초기 코드를 읽을 때 '아, 이 부분에서 api 호출하는구나' 정도로 가볍게 읽고 넘어가기 때문에, 다른 코드와 섞여 있으면 가독성을 해칠 거라 생각해 따로 페이지를 구분함.
4. store.js
- 초기 기획 단계에서 페이지네이션 기능을 넣기 위해, 전역으로 값을 관리하면 좋을 것 같아 만들었으나, 계획이 취소되어 지금은 깔끔한 데이터 전처리를 위해 사용됨.
5. movie.js
- 영화 정보를 받아 카드 UI를 구성하는 페이지.
- <ul> 안에 <li>를 추가하는 형태. 카드 클릭 시 id값을 alert로 표시
🔎 프로젝트를 진행하며 알게 된 점
1. fetch 이후 응답으로 사용되는 response는 왜 json()을 붙여 재가공 한 뒤 사용할까?
=> response는 Fetch API에서 반환되는 객체로, 응답의 상태, 헤더, 본문의 정보가 담겨있다. 이 중 우리가 원하는 데이터는 body에 담겨있는데 body는 ReadableStream으로 비동기적으로 데이터를 읽을 수 있는 스트림 형태로 제공된다. 네트워크에서 비동기적으로 데이터를 읽는 작업은 전체 데이터가 한 번에 메모리에 로드되지 않고, 데이터가 사용 가능할 때마다 조금씩 전달되어 필요한 만큼만 메모리에 유지된다. 이렇게 관리하면 메모리 사용 최적화에 도움이 되며, 조각조각 데이터가 전달됨으로 데이터에 크기에 상관없이 효율적으로 처리할 수 있다는 장점이 있다. 때문에 stream 형태를 읽기 위해서 JSON 형태로 변환하여 처리하는 것이다.
2. DocumentFragment 사용해 보기
2-1. api로 받아온 영화 정보를 순회하며 20개의 card를 만드는 과정에서, DOM에 매번 접근하는 것이 성능적으로 좋지 않다고 생각했다. DOM API를 통한 노드가 추가되면 화면의 레이아웃을 재계산하는 reflow가 발생하기 때문이다. 그렇기에 최소한으로 DOM 접근을 하기 위한 방법을 찾았는데, Fragment가 구글링 중 눈에 띄었다.
2-2. Fragment는 DOM 트리와 별개의 구조로 이루어져 있다. 때문에 여러 element들을 묶어 서브트리를 조립한 뒤 DOM에 삽입하기 위한 용도로 사용된다. DOM에 불필요한 노드를 추가하지 않기에 reflow를 최소화할 수 있고, 성능적인 향상을 기대할 수 있다.
이러한 근거로 Fragment를 사용해 보았는데 과연 그 결과는 어땠을까?
코드상으로 큰 변화는 없다. createDocumentFragment()로 fragment를 생성하고 forEach 순회 동안 생성된 movieCard를 fragment에 모두 추가한 뒤, 순회가 끝나고 <ul> 태그인 cardContainer에 한 번에 요소들을 추가하였다. 과연 효과가 있었을까?
야심 차게 성능향상을 꿈꿨으나, 규모가 작은 미니 프로젝트이기에 효과가 없었다. 여러 번 리렌더링을 거쳐 값을 확인했으나 위의 사진과 큰 차이가 나지 않을 정도의 변화만 있을 뿐이었다. 0.1s라도 빨리 지길 기대했는데 어림도 없는 소리였다. 어찌 되었든 Fragment를 사용하는 것이 사용하지 않는 것보다 유용한 것은 맞으나, 현재 프로젝트를 냉정히 보면 굳이 필요하지 않았으며 오히려 코드 가독성을 해치기에 결국 사용하지 않기로 결정하였다. 그래도 새로운 개념을 익혔고, 공부해 봤다는 것에 의의를 두려 한다.
💡 구현하려고 했던 기능 및 구조
1. 가져오는 데이터에 평점이 있어 Ranking 구현
2. fetch api url을 보면 language 변수가 있어, 한국어 ↔ 영어 언어 전환 기능 구현
3. 평점별로, 출시 연도별로 등 필터 기능
4. 페이지네이션 기능
5. CSS variable 변수 사용(색상 일관화)
=> 이 외에도 욕심나는 기능들이 있었으나, 바로 내일부터 팀 프로젝트가 시작되기 때문에 더 재밌는 기능들을 마주할 수 있을 것 같아 여기까지만 구현하기로 하였다.
어디 딱히 나간 적도 많지 않은데 하필 코로나에 걸려 막상 프로젝트는 짧은 기간 동안에 구현되었다. 이 점이 아쉬우면서도, 배울 점이 많았던 프로젝트였습니다. 그리고 모던 자바스크립트 딥 다이브 스터디도 모집 중에 있는데, '한 두 분만 관심 있어하면 어쩌지..?'라는 걱정과 달리 스터디에 많은 관심을 주셔서 감사할 따름입니다...! 같이 재밌게 만들어나가 봐요🌱
'TIL' 카테고리의 다른 글
[2024.05.02] 웹 폰트 최적화(가볍게 정리만) (1) | 2024.05.02 |
---|---|
[2024.05.01] 새로운 팀 프로젝트 시작 (1) | 2024.05.01 |
[2024.04.29] JS 딥다이브 스터디 모집 시작 + 개인 과제 해설 (0) | 2024.04.29 |
[2024.04.28] 바닐라 자바스크립트로 웹 컴포넌트 만들기_state 기준 (0) | 2024.04.28 |
[2024.04.27] TMDB API 사용해보기 (0) | 2024.04.27 |