허생은 스타트업에 다녔다. 곧장 강남9출로 나오면, 낡은 공유 오피스가 하나 있고, 구석진 곳에 사무실 문이 하나 있는데, 좁디 좁은 4인실 오피스는 방음이 안되어 옆 사무실에서 뭘 만드는지 다 들릴 정도였다. 그러나 허생은 코딩만 좋아하고, 대표가 외주를 해서 긴히 자금을 조달했다.— ak 🌱🎗 📚 💻 (@_a6g_) December 4, 2022
[구글 엔지니어는 이렇게 일한다] 책을 읽고 가볍게 훑어볼 수 있도록 간략하게 요약했어요. 지난달 프론트엔드 챕터에 공유했었는데요, 외부에 열어도 좋을 것 같아서 공유합니다 :)https://t.co/jRgXp3vVsw— Jbee🐝 (@JbeeLjyhanll) August 1, 2022
원래는 성능테스트도 겸할 목적으로 route를 많이 만들었는데, 귀찮아서 라우트객체의 결과값만 비교했습니다. 때문에 스크린샷의 동그라미 친 부분만 보셔도 됩니다.
좌측이 case 2, 우측이 case 1 의 결과입니다.
원래 output에는 다른 Layer객체의 정보들도 들어있었지만, 보기 편하도록 regexp 필드만 잘라넣었습니다.
정말 코드에 정의하는 그대로 똑같이 들어가네요. 중복된 경로는 최소한으로 쓰는게 좋겠다는 결론을 얻었습니다.
테스트 2
프로젝트 설정 시, 흔히 route의 중간 경로별로 파일을 분리하곤 합니다. 예를들어 user와 관련한 API route들은 `/server/route/api/user.js` 에 두고, item 관련 API는 `/server/route/api/item.js` 에 만드는 식으로요.
이런 경우에, 각 route의 path를 모두 풀어 쓴 경우와, 단계별 공통된 route별로 분리해서 계층화 한 경우 `Router.stack`의 값에 차이가 생기는지도 궁금했습니다.
case 1. 풀어 쓴 경우
이 경우는 테스트 1의 case 1과 동일하므로 별도로 작성하지 않았습니다.
case 2. 계층화 한 경우
외부에 공통된 경로로 route를 설정하고,
별도의 파일에서 하위 경로의 route를 설정
결과:
마찬가지로 동그라미친 부분만 보시면 됩니다.
우측이 기존, 좌측이 case 2 의 결과입니다.
case 2의 결과에서는 로그가 두번 찍혔네요. (아래쪽 동그라미) 따라서 case 2와 같은 방식으로 구현하면 Layer가 계층화되어 저장되며, 재귀 탐색이 된다는 것을 알았습니다.
요청이 들어오면 매번 위에서부터 하나씩 정규식 비교가 실행 될 것이므로, 공통된 중간 경로를 가진 route가 많다면 위와같이 계층화 시켜 구현하는것이 더 효과적일것이라 생각합니다.
실제로도...?
정말 속도가 차이가 날까?
궁금해서 계층화 하지 않은 버전과 계층화 된 버전, 두가지의 마지막에 있는 api를 axios를 이용해서 각각 100,000번씩 호출 해 보았습니다. 실험은 각 6번씩 반복했습니다.
다만 위 샘플코드로 테스트해본건 아니며, 개발중이던 프로젝트를 조금 단순하게 수정한 후, 위 실험 2와 비슷한 조건으로 만들어서 테스트 했습니다.
신뢰할만한 실험이었는지는 장담할 수 없지만, 약간의 차이는 보였습니다. (단위: ms)
case 2에서 약 3.5% 정도의 빠른 응답속도가 나왔네요.
다만 유의미한 수치를 보려면 더 복잡한 구조의 프로젝트에서의 테스트가 필요할 것 같습니다.
결론 / TL;DR
1. express는 우리가 넣어둔 router path들을 모두 정규화 시켜서 저장한다.
2. 넣어둔 path들은 순서대로 배열에 쌓이며, 일치하는 값이 나올 때 까지 순서대로 정규식 검사가 실행된다.
3. router를 중간 경로가 같은 것 끼리 묶어서 계층화 시켜두면, 실제로 express도 우리가 넣은 구조 그대로 값을 저장한다.
4. router에 공통된 중간경로를 가지는 route가 많다면, 계층화 시켜서 최적화 할 수 있다. 다만 엄청 큰 규모가 아니라면 유의미한 수준의 성능개선은 어렵다.