패스트캠퍼스X야놀자 프론트엔드 개발 부트캠프_JavaScript 과제 리팩토링
과제를 진행하며 느낀점
지난 HTML/CSS 과제가 우리가 눈으로 보는 페이지 디자인 자체를 만들어내는 것이 목적이었다면 이번
JavaScript 과제는 기능들을 동작하도록 하는 것이 중점이었다. 가장 크게 느꼈던 점은 기능이 동작하도록 하는 것에 있어서
수많은 방법들이 있다는 것이었다. 뿐만아니라 같은 기능이라도 유저의 입장에서 고민한다면 더욱 나은 방향으로 구현하는 것 또한
가능했다. 따라서 단지 실제 사이트와 같은 모습만을 만들면 되는 지난 과제보다 훨씬 어렵게 다가왔던 것 같다.
1) Firebase을 처음으로 사용하면서
이번 과제의 필수 요건 중 하나는 데이터를 따로 저장하여 관리할 수 있는 서비스인 AWS S3나 Firebase같은 기능을 이용하는 것이었다.
커리큘럼 내 강의에서 접해보지 못한 부분이었기 때문에 관련 정보들을 검색하고 공식 문서를 사용해 하나하나 익혀가면서 기능을 구현했다.
이 과정에서 두 가지의 긍정적인 경험을 할 수 있었다.
첫 째, 내가 처음 접하는 기술이라도 공식 문서를 통해 익혀가면서 문제들을 해결해나갈 수 있다는 자신감을 얻게 되었다. 강의로 배운 내용들이
아닌 내가 스스로 문서를 읽고 시행착오를 겪어가며 마주치는 문제들을 해결하다보니 이제는 어떻게 새로 기술들을 배울 때 문서들을 참고해야할지
경험할 수 있었고, 공식 문서의 내용이 내 생각 이상으로 자세하고 친절하다는 것을 깨달았다. 새로운 것을 배울 때 유튜브와 인프런 등의
강의들을 뒤지며 어떻게 배워나가야할까 고민하던 내가 이번 경험으로 강의만이 정답이 아니라는 것을 알았고, 문서를 통해 학습하는 것 또한
빠르게 기능을 구현할 수 있는 방법이라는 것을 알게되었다.
둘 째, 데이터를 어떤 방식으로 저장할지 어떻게 사용할지를 고민하게 되면서 그간 프론트엔드에서 경험할 수 없던 것들을 직접 경험할 수 있었다.
프론트엔드 과정의 특성 상 실제 유저들이 접하는 페이지와 UI들에 대해 고민하게 되는 경우는 많아도 실제로 어떻게 데이터를 줄 것인지, 어떻게
저장할 것인지 생각해볼 기회가 없었다. 하지만 이번에 과제에서는 그러한 것들을 직접 해봄으로써 실제 사이트들이 어떻게 돌아가고 있는지에 대한
감을 익힐 수 있었다.
2) 동작에만 집중하는 코드는 목표한 기능에 불필요한 동작을 추가시킬 수 있다.
구현하고자 하는 기능에 대해 정확히 뭐가 필요한지 그것을 해내려면 무엇을 알아야 할지 파악하고 그것을 바탕으로 작업을 해야된다는 것을 느꼈다.
자바스크립트는 자유로운 언어다. 그만큼 내가 원하는 것들을 다양한 방법으로 구현할 수 있고, 그 과정에서 꼭 필요하지 않은 작업을 하는 경우가 있었다.
멘토님께서 지적해주신 placeholder에 관한 부분이었는데, html의 input요소의 특성상 placeholder 속성에 값을 부여해주면 blur처리 될 때 input value에 따라 자동으로 placeholder를 다시 보여준다. 하지만 나는 ‘그렇게 동작해야지’ 라는 생각에만 사로잡혀 이미 그렇게 구현되어있는 기능들까지
하나하나 자바스크립트를 통해 동작을 제어하였다. 동작만에 생각이 매몰되어 정작 전체적인 그림을 보지 못했던 것이었다. 단순히 이런 동작을 하게
해야지에 집중하는 것이 아니라 전체적인 기능에 있어 내가 무엇을 제어해야되고, 어떤 것이 필요한지를 제대로 생각하고 코드를 작성해야겠다고
생각했다.
3) 여러 방법들 중에 선택한 이유가 있어야 한다.
멘토님의 멘토링 과정에서 지속적인 함수호출에 관련하여 debounce라는 기능에 대해 설명을 들었고, 이번 과제에서 활용해보고자 하였다. 로그인 기능에서
이메일, 패스워드 입력값을 받아 validation 할 때, 매 input값의 변경마다 validation을 하는 것이 비효율적이라 느껴서 적용한 것이었는데 과연
내가 그 동작을 하도록 하는 방법에 대해 고민했는가를 생각해보았다. 분명 비슷한 동작을 하는 다른 방법들이 있었을 것이다. 그러나 고민이 없었기에
그저 사용하여 기능을 구현하고 만족했다.
리팩토링을 하면서 이에 대해 생각하면서 debounce를 고민할 때에는 비슷한 동작을 하는 throttle도 함께 고민했어야 한다고 생각했다. 결과적으로는
throttle보다 debounce를 통해 구현하는 것이 원래 목적에 맞았지만, 그저 결과적으로 옳은 방법을 선택한 것과 둘을 고민해서 왜 그게 옳은 것인지를
확인하고 넘어가는 것에는 큰 차이가 있다. 이제는 동작에 대해 고민할 때 가능한 여러 방법들을 생각하고 타당한 이유와 함께 선택하여 코드를 작성해야겠다.
멘토님의 코드리뷰
1) 비동기 코드에 대한 전반적인 이해와 예외처리의 부족
분명 이론적으로 학습할 때에는 알고있다고 생각한 내용들이었지만 실제 과제에서 적용하면서 왜 이것들이 필요한지, 어떤 방식으로 사용해야 하는지에 대해
깊게 생각하지 않고, 이걸 적용해야 기능이 동작하네!라는 것에만 초점을 맞췄던 것 같다. 그러다보니 불필요한 async/await 사용과 예외처리 부분에서
아쉬운 코드가 되었던 것 같다.
1 | const $list = document.getElementById('member-list'); |
async/await의 경우 비동기 함수를 마치 동기처럼 코드 내에서 처리하기 위한 방법이다. 따라서 비동기 코드들의 순서에 의존하는 코드들이 아니라면
굳이 사용할 필요가 없었다.
1 | // 기존 코드 |
위 코드를 보면 비동기 코드가 많은 것을 확인할 수 있다. 개발 시 에러가 발생했을 때 어떤 함수에서 문제가 있었는지를 수월하게 파악하기 위해서 try/catch를 통해 예외처리 하는 것을 습관해야한다고 멘토님께서 말씀해 주셨다.
1 | // 리팩토링 코드 |
2) apikey를 환경변수로 관리
로컬에서 개발할 때와 서버에 배포할 때 DB연결, 포트 설정 등 관련된 부분을 매번 수정해서 배포하는 것은 쉽지 않다. 또한 유출되면 안되는 secret key
는 public으로 배포하면 안된다는 것을 다시 한번 상기하게 되었다. firebase를 사용하면서 내 데이터베이스에 접근할 수 있는 key들을 그대로 오픈해놨는데
지금처럼 학습용으로 작은 사이트를 만들 때에는 상관이 없더라도 기업에서 일을 할 때 매우 크게 잘못될 수 있으니 이러한 것들을 환경변수로 관리하는 것을
습관하해야겠다.
1 | // 기존 firebase.js 안에 apikey를 노출 |
1 | // dotenv를 활용하여 환경변수로 관리 |
1 | require('dotenv/config'); |
3) 성능을 생각하여 코드를 구성
1 | window.addEventListener('DOMContentLoaded', async e => { |
위 코드에서 페이지에 적용되는 render함수는 getAllMembers함수가 반드시 실행된 이후에 동작하게 된다. 처음 이렇게 코드를 구성한 이유는
데이터를 추가/삭제 할 때 데이터베이스에 먼저 반영하고 그 데이터를 토대로 페이지에 렌더하려는 것이 목적이었다. 그러나 리스트를 삭제하고
추가할 때마다 데이터베이스를 먼저 거치고 페이지에 반영하는 것은 사용자 입장에서 더 느린 응답을 받는 결과로 이어진다는 것을 생각하지 못했다.
최초 데이터를 불러올 때에만 getAllMembers를 먼저 실행하여 페이지에 반영하고 그 이후에는 자바스크립트에서 미리 객체를 선언해서 동시에 관리하면
훨씬 빠른 응답을 줄 수 있을 것이라 생각하였다. 객체를 수정하여 먼저 페이지에 반영한 뒤에 그 결과를 데이터베이스에 전달하는 것이 사용자 경험에서
효율적일 것이라 생각했다.