나는 지금 재직하고 있는 회사가 처음 시작할 때부터 몸담고 있는 멤버다.
MVP 개발을 하기 위해 Flutter를 프론트엔드 프레임워크로, 백엔드는 Firebase에서 제공하는 다양한 솔루션을 사용했다.
빠르게 개발해서 굴려보기 위한 목적으로 속도감 있게 개발할 수 있는 것으로 프레임워크 등을 선택해야 했기 때문에 Flutter를 사용했던 것으로 기억한다. 정말 웹을 위한 기술을 사용했다면 CSS처럼 손 많이 가는 것들이 많을텐데 Flutter는 Material이나 Cupertino에서 제공하는 기본적인 스타일 정도는 지원을 했으니까.
Flutter는 좋은 프레임워크이다. 스마트폰이라는 하드웨어에서 제공하는 블루투스 같은 것을 직접 제어할 상황이 아니라면 말이다. 단순한 CRUD만 일어나는 환경에서는 Flutter라는게 초심자 입장에서 입문하기 좋다고 생각한다. 여전히 변함 없는 생각이다.
MVP 개발이 끝나고 운영을 직접 하면서 수개월이 흘렀을 때 크게 두가지의 문제점을 발견하게 되었다.
1. 난개발을 하게 되어 코드 유지보수가 되지 않고 있다.
2. Flutter 웹의 성능 이슈
첫번째 문제는 MVP 개발이 완전히 끝난 이후 요구사항이 계속 추가되기도 하고, 그걸 단시간에 처리해야 해서 날림으로 개발하여 발생한 문제다. 스타트업 특성상 BM이 계속 바뀌거나 요구사항이 추가되는건 충분히 이해 가능한 영역이다. 그러나 시스템 안에서 그것을 어떻게 반영해 줄지 어느정도 검토할 시간이 꼭 필요하다. 무지성으로 추가/변경되는 요구사항을 계속 쳐내다보니 어느새 정신차렸을 때는 걷잡을 수 없이 스파게티 코드가 되어 있었다. 이곳을 수정하면 저곳이 망가지는 그런 현상.
하나의 스크린에서 위젯을 분리 설계 했어야 하는데, 그것을 고민할 순간조차 없었기 때문에 아무 생각없이 코드를 써내려갔고 그것은 100줄 200줄씩 채워져가기 시작했다. 또 다른 수정사항이 발생하면 어딜 고쳐야 하는지 헷갈릴 정도였으니 꼭 분리설계를 해야겠다는 다짐을 이때 한 것이다.
나중에 백엔드 개발자가 퇴사하고나서 잠시동안 내가 백엔드도 인수인계 받아 잠시 관리했었는데 백엔드 쪽도 가관이었다. Firebase Functions를 사용했었는데, 충분히 검토할 타이밍 없이 요구사항을 계속 반영하다보니 함수 자체의 개수는 기하급수적으로 늘어났으며, index.js 파일은 3만줄을 넘기 시작했다. VSCode가 버벅거릴 정도였다.
두번째 문제는 Flutter를 웹으로 빌드하여 사용했을 때 문제였다. 물론 최적화에 신경 못 쓴 내 잘못이 전적으로 크지만 주변에 있는 선배 Flutter 개발자 분들의 고견을 여쭈었을 때 당시 Flutter의 웹 생태계는 좋은 평가를 받지 못하였다. 가장 큰 문제는 초기 렌더링 속도가 너무 느렸다. 4초 정도가 걸렸으니 말 다했다. 이후에 Flutter에 WASM(웹 어셈블리) 등이 도입되어 속도 개선에 힘을 많이 쏟았다고 하지만, 버전을 올려야 했고, 패키지 충돌 등 리스크가 많았기 때문에 과감하게 도전하진 못했다.
속도가 느리기 때문에 시스템을 직접 운영하는 영업파트 등 다른 팀에서 불편하다는 의견이 있었고, 나름대로 개선해보려고 했으나 앞서 언급한 것처럼 Flutter 버전 업데이트에 따른 후속 이슈가 우려되었다. 아예 갈아 엎어야 겠다는 생각을 여기서도 하게됐다.
그래서 새로운 개발자 채용과 동시에 웹에서 할 수 있는 영역, 모바일에서 할 수 있는 영역을 나누었고 각각의 위치에서 최선을 다 해줄 수 있는 기술스택을 정하기로 생각했다. 그 결과가 웹은 Next.js였고, 앱은 Flutter였다.
MVP를 걷어내고 새로운 시스템을 개발하는 만큼 기획파트와 치열하게 회의했고, 디자인 파트와 계속 소통하면서 어떻게 화면을 그려나갈지 논의했다. 요구사항 정의가 끝나고 기능을 정의하고 있는 과정에서 요구사항이 계속 추가되어 무척 힘들었다. 테이블 설계가 끝났는데 다른 컬럼이 또 추가되고, 심지어 그 컬럼이 다른 테이블과 관계를 맺어야 하는 상황도 오게 되었다. 그럴 때마다 좋게 생각하고 이해해야 하는데 스트레스를 무척 많이 받을 때라 네거티브가 심했다. '그러지 말아야지'라는 생각은 의식중에 계속 하고 있지만 갑작스레 무의식의 세계로 빠져서 반박을 쏟아낼때가 있는데, 그런 때를 생각하면 협업을 하는 다른 팀원 분들께는 미안한 마음 뿐이다.
각설하고 새로운 시스템 개발에는 프론트엔드 영역에서 Next.js와 Flutter, 백엔드 영역에서는 Nest.js를 도입하기로 결정하였고, 그렇게 개발을 착수하였다. Firebase도 걷어내고 AWS를 도입하였고, EC2에 리눅스 컴퓨터를 만들어서 Nginx도 설치하고 PM2도 설치하고 웹앱을 직접 띄워 운영하는 방식으로 결정하였고, CI/CD 환경도 직접 다 구축했다.
원래 9월부터 기획을 시작해서 1월말에 개발을 끝내는 것으로 계획을 잡았었는데, 기획쪽에서 다른 우선순위가 높은 업무때문에 타이밍이 조금 엇나가서 9월 중순 ~ 말부터 기획을 시작하였고, 우리 개발자들은 시간에 쫒기며 개발을 할 수 밖에 없었다. 그래도 내가 원래 하던 거라 재미있게 개발할 수 있었다.
Flutter 웹보다 훨씬 빠른 렌더링 속도를 보장하면서, 시스템을 직접 운영하는 팀에서 긍정의 반응이 쏟아질 즈음 몇가지 수정사항이 들어왔고 그걸 또 고쳐가며 배포에 배포를 거듭했다.
수정사항은 여전히 계속 발생중이다. 그 수정사항이라는게 기존의 설계를 흔드는 것들이 많아서 또 스트레스를 받을 수 밖에 없다. 백엔드 쪽에서는 테이블간 관계를 맺은 것들도 관계를 끊어주고 있는 것 같고, 무결성 검증은 개나 줘버리게 되는 것이다. 나는 또 새로운 컴포넌트를 어떻게 만들 것인지, 기존에 있던 페이지에 새로 추가되는 것들을 어떻게 반영시켜줄지 기획, 디자인 파트와 끝없이 협의하며 불같이 일해야 한다.
"스타트업이라는 환경이 원래 이러한가?"라는 물음을 끊임 없이 던지고 있다. 대표님께서 그리고 있는 마일스톤이 있을 것이고, 실무자들은 최대한 그 마일스톤을 실현할 수 있게 서포트하면서 간언해주는 역할을 해야한다. 그 마일스톤에 반기를 들거나 의구심을 갖게 되면 퇴사하는 것 같다. 여태까지 지켜본 퇴사자들이 그랬다. 사람이 사고하는 과정에서 "비판적 수용"은 필요한 자세이다. 그것이 무제한으로 비판하는 행위나 비판 그 자체만을 가리키는 것은 아니다. 발화를 하는 주체가 놓치고 있거나 허점을 보이고 있는 것을 짚어주고, "나라면 어떻게 했을까"라고 끊임없이 반문하며 발화를 하는 주체에게 나의 인지를 일깨워 주는 일련의 과정이라고 생각한다.
내가 신입이었을 때는 신입이기 때문에 누군가의 결정에 토를 달지는 않았다. 머리가 커질수록 나는 비판적 수용이라는 것을 할 수 밖에 없게 되었다. 그렇게 하지 않았을 때 나는 혼자서 시름하며 무한 긍정만 할 뿐이었다. 정신적으로 좋은 행동이 아니라고 생각했기 때문에 나의 의견도 적극적으로 피력하면서, 씨레벨이나 다른 실무자가 말하는 의견도 경청하는 태도를 가져야겠다고 어느 순간 자각했다.
어찌되었든 새로운 시스템을 개발하면서 기술적인 부분에서의 문제를 극복하고, 다른 팀과 긴밀한 협의를 거치면서 많은 것을 배웠다. 나는 개발자로서 내 입장에서만 생각했던 것들을 영업파트에서, 기획이나 디자인파트에서 어떻게 생각하는지 알아가는 시간이었고, 내가 그 파트에 있는 사람이었으면 어떻게 생각할까라는 물음을 더욱 던져볼 수 있었다.
새로 추가되거나 수정되는 사항들은 긍정적인 마음가짐으로, 개발자 입장에서 방어만 할 것이 아니라, 다른 팀의 팀원 입장에서 생각해보고 고민해보는 그런 계기가 되었다고 자신한다.