레벨1 온보딩(1주차) 미션 회고

첫 번째 미션이 끝났다! Gemini API와 Canvas를 활용해서 앱을 만드는 미션이었는데, 요구사항이 “나에게 필요한 걸 만들어라”여서 처음엔 좀 자유롭겠다 싶었지. 뭐 일단 미션은 간단했고… 그것보다

이번에 8기부터 판교에서 신규 캠퍼스 생활을 하는데 시설이 진짜 만족스럽더라. 지금 눈이 높아져서 다른 시설이 눈에 들어올까 싶을 수준이다. 판교 캠퍼스가 8기부터가 시작이라 나는 꺼드럭 댈만한 썰이 벌써 생겼다. 크루, 코치분들이랑 다같이 책 옮겼는데, 내가 여기 책 옮겼다고!! ㅋㅋㅋㅋ

리뷰 피드백

리뷰어분 피드백 요약하면,

“이걸 써야만 한다는 동기가 약하게 느껴졌어요.”

각 앱별로 구체적인 개선 방향도 주셨는데,

  • 일반 가계부에서 카테고리만 카페로 바꾸면 동일하게 동작하는 거 아니냐. 차별점이 없다.
  • 대결이나 랭킹 같은 기능이 있으면 좋겠다.
  • 오답노트 같은 기능이 있으면 학습 앱으로서 완성도가 올라갈 것 같다.

솔직히

리뷰를 처음 받아봐서 그런가 처음엔 좀 억울(?)했다 ㅋㅋzzz

미션이 “나에게 필요한 걸 만들어라”였는데, 어째서 타인을 설득해야 하지? 오히려 일부러 기능 줄이면서 나름 최적화다 하면서, 결국 나한테 필요한 걸 만든 건데!! 심지어 크루들한테 만든 거 소개할 때도 최대한 대중적인 것들 골라서 말했는데!! 그래도 졸라 부끄러웠음 아

뭐 여튼 그래도 피드백 받고 하루내내 고민해보니까 결국 리뷰어분의 말이 맞긴 했다. 그래서 스스로 반성을 꽤나 했지.

소심한 카공족을 예시로 들면, 내가 해결하려는 문제가 “카페 지출을 모른다”였는데, 이건 그냥 가계부 앱으로도 해결된다. 내가 만든 앱이 그보다 나은 이유를 솔직히 나도 설명을 못하고있다. 카테고리가 카페로 고정되어 있다는 것 말고는. 물론 이걸 원한 거긴 한데… 여튼

문제를 찾았다고 생각했는데, 사실 문제를 찾지 못했던 것이다.

한 크루분은 본인이 사용할 저엉말 간단한 유틸앱을 만들었는데, 나까지도 설득당해서 바로 써보고 싶어졌다. 슬랙에도 배포된 다양한 게임 이런 건 솔직히 그렇구나..신기하다.. 하면서 보거든. 내 게임도 그렇고, Gemini로 만든 게임이 뭐.. 다 아이디어 싸움이지. 근데 나도 유틸앱을 발표해서그런가? 그 크루분의 유틸앱 소개는 색다르게 들렸다. 불편한 걸 진짜로 느끼고 만든 느낌이 바로 전해지더라고. 내가 너무 가볍게 미션을 대했나 싶었다.

결론적으로는 “나를 위한 미션”이라는 게 면죄부는 아니었던 셈이었다. 나를 위한 서비스라도, 진짜 내가 겪는 문제를 뾰족하게 해결하고 있는지는 별개의 얘기였다.

(리뷰어님 PR에 닉네임을 말 안해주셔서 누군지 github 아이디로만 기억하고 있겠습니다.. 다음엔 더 성장해서 돌아올게요)

CSS 프롬프팅

리뷰어분이 덤으로 좋은 얘기도 해주셨다. AI가 CSS에 약한 이유에 대해서.

CSS는 선언적이고 프로퍼티 간 조합이 암묵적이라서, 예를들면 display: none인 요소에 opacity 트랜지션을 걸면 왜 안 되는지 같은 건 브라우저 렌더링 파이프라인 지식이 필요한데 AI는 코드 텍스트만 보고 추론하기 어렵다고 하더라. 그래서 CSS 버그 프롬프팅할 때는 관련 속성 조합을 명시적으로 알려주고, 제약조건을 명확히 해서 AI의 추론 범위를 좁혀주는 게 효과적이라고 했다.

확실히 나도 “왜 안 되지? 개가튼 구글” 이런식으로만 던지다가 잘 안 풀렸던 경험이 있었다. 맥락을 더 줬어야 했다.

그래서 display: none + opacity 예시가 왜 안 되는지 찾아봤는데, 브라우저 렌더링 파이프라인을 알면 당연한 얘기였다. 브라우저는 HTML을 파싱해서 DOM을 만들고, CSS를 파싱해서 CSSOM을 만들고, 이 둘을 합쳐서 Render Tree를 만든다. 근데 display: none인 요소는 Render Tree에 아예 포함이 안 된다. 존재 자체가 없는 거라서, transition이 걸려있어도 중간 상태를 계산할 대상이 없으니 당연히 동작하지 않는 것이다.

Render Tree가 만들어지고 나면 Layout → Paint → Composite 순서로 화면에 그려진다. Layout은 각 요소의 위치와 크기를 계산하는 단계고, Paint는 실제로 픽셀을 채워넣는 단계, Composite는 레이어를 합쳐서 최종 화면을 만드는 단계다. CSS 속성마다 어느 단계를 건드리는지가 다르고, 이게 성능 차이로 이어진다.

페이드 인/아웃 구현할 때 display: none 대신 visibility: hidden이나 opacity: 0을 쓰면 transition이 동작하는데, 이 둘도 사실 차이가 있다. visibility: hidden은 공간은 차지하면서 안 보이는 것이고, opacity: 0은 완전히 투명한 것이다. 클릭 이벤트도 opacity: 0은 그대로 받는다. 그래서 opacity로 숨길 때는 pointer-events: none을 같이 써줘야 할 때가 많다.

성능 측면에서 opacitytransform은 Composite 단계만 건드리기 때문에 GPU에서 처리된다. Layout이나 Paint를 다시 하지 않아도 되니까 애니메이션이 훨씬 부드럽다. 반면 width, height, margin 같은 속성은 변경되면 Layout부터 다시 계산해야 해서 비용이 크다. 애니메이션 구현할 때 가능하면 transformopacity만 건드리라는 이유가 여기 있었다. 알고 나면 별거 아닌데, 그냥 “왜 안 되지?” 하고 AI한테 던지면 이 맥락을 AI가 모르니까 엉뚱한 답이 나올 수밖에 없는 거였다.

마무리

크루분들 보면서 느끼는 건데 다들 수준급 이상으로 잘하시더라. 내가 제일 못하는 것 같다는 생각이 드는데 (아니 맞아), 동기부여가 된거같다 (3학년 서울대 회로 전공 PTSD on). 그래도 주변이 잘하면 나도 자연스럽게 끌려올라가는 느낌이랄까. 지금은 JavaScript 공부 중인데 슬슬 TypeScript도 개념은 봐야 할 것 같고, 출퇴근할 때 CS50 강의 틀어두고 다니는 중이다. 영어 공부도 되고 일석이조라 나름 맘에 들더라.

첫 미션이었는데 만드는 건 재밌었다. 다음 미션에서는 “내가 쓰고 싶다”를 넘어서, “이게 없으면 불편하다”를 해결하는 방향으로 기획해봐야겠다. 문제를 먼저 명확히 정의하고 만들기 시작하는 것.

어렵네.

PREVIOUS레벨1 로또(2주차) 미션 회고
NEXT분명 바꿨는데 왜 state가 바뀌지 않는 걸까.