[실전 성능 02] 무엇을 재는가

지난 편에서 성능은 감이 아니라 숫자로 판단해야 한다고 했다. 그러면 대체 어떤 숫자를 봐야 할까. 지표는 세상에 수백 가지가 있어서, 처음엔 무엇을 봐야 할지 몰라 대시보드만 멍하니 바라봤다. 이번 편은 내가 결국 붙잡은 세 가지 핵심 지표와, 왜 하필 그 세 개인지에 대한 이야기다.


1. 사용자 경험을 세 조각으로 나누기

느리다는 불평을 자세히 들어보니, 사람들이 말하는 느림은 사실 세 종류였다. 첫째는 화면에 뭔가 뜨기까지 오래 걸리는 것이다. 빈 화면을 오래 보고 있으면 사람들은 사이트가 죽었다고 느낀다. 둘째는 화면은 떴는데 눌러도 반응이 없는 것이다. 버튼을 눌렀는데 아무 일도 안 일어나면 다시 누르게 되고 결국 화가 난다. 셋째는 멀쩡히 보던 화면이 갑자기 밀려서 엉뚱한 곳을 누르게 되는 것이다.


이 세 가지는 각각 로딩, 반응성, 시각 안정성이라고 부를 수 있었다. 흥미롭게도 업계 표준 핵심 지표도 정확히 이 세 축으로 나뉘어 있었다. 최대 콘텐츠가 그려지는 시간, 상호작용 후 다음 화면이 갱신되기까지의 시간, 그리고 누적 레이아웃 이동량이 그것이다. 사람의 불만을 기계가 잴 수 있는 숫자로 번역한 것이 바로 이 셋이었다.


내가 이 분류에 감탄한 이유는, 서로 겹치지 않으면서도 사용자 경험의 큰 덩어리를 빠짐없이 덮기 때문이었다. 아무리 로딩이 빨라도 버튼이 안 눌리면 소용없고, 반응이 좋아도 화면이 계속 흔들리면 못 쓴다. 세 축을 따로 재야 어디가 문제인지 정확히 짚을 수 있었다. 하나의 종합 점수로 뭉뚱그리면 원인이 흐려졌다.


나는 이 셋을 각각 다른 사용자의 목소리로 상상했다. 로딩 지표는 언제 보여주냐고 재촉하는 사람, 반응성 지표는 왜 안 눌리냐고 짜증내는 사람, 안정성 지표는 왜 자꾸 움직이냐고 당황하는 사람이었다. 세 사람을 동시에 만족시켜야 비로소 사이트가 쾌적하다는 소리를 들었다.


2. 왜 세 개면 충분한가

처음엔 지표가 세 개뿐이라는 게 오히려 불안했다. 성능에 영향을 주는 요소는 수십 가지인데, 고작 세 숫자로 판단해도 되나 싶었다. 그런데 써보니 이 세 개가 사용자가 실제로 체감하는 순간들을 대표했다. 나머지 세부 지표들은 대부분 이 셋 중 하나의 원인을 설명하는 하위 요소였다.


예를 들어 서버가 첫 바이트를 늦게 주는 것은 그 자체로도 지표지만, 결국 화면이 늦게 뜨는 로딩 문제로 이어진다. 자바스크립트가 무거워 메인 스레드를 오래 붙잡는 것도 따로 재지만, 사용자에겐 버튼이 안 눌리는 반응성 문제로 나타난다. 즉 세부 지표는 진단용이고, 핵심 세 지표는 사용자가 느끼는 결과였다. 결과부터 보고 원인으로 파고드는 순서가 맞았다. 나는 세 지표가 빨간불일 때 그 뒤에 숨은 세부 지표들을 뒤져서 진짜 원인을 찾았고, 세부 지표만 붙잡고 씨름하다 정작 사용자 경험은 그대로인 헛수고를 피할 수 있었다.


지표를 적게 유지하는 건 실용적으로도 중요했다. 재야 할 게 스무 개면 아무도 꾸준히 안 본다. 세 개면 매일 힐끗 확인할 수 있고, 통과인지 아닌지 즉시 판단된다. 나는 관리할 지표를 늘리고 싶은 유혹을 참았다. 핵심을 좁게 유지하는 것이 오히려 지속 가능한 관리로 이어졌다. 지표가 많으면 매일 보기 싫어지고, 안 보면 있으나 마나였다. 나는 매일 눈에 담을 수 있는 개수를 넘기지 않는 것을 원칙으로 삼았고, 그 덕에 성능 점검이 특별한 이벤트가 아니라 일상이 되었다.


물론 이 셋이 전부는 아니다. 접근성이나 안정성 같은 다른 품질 축도 있다. 다만 순수하게 속도와 쾌적함을 말할 때는 이 세 지표가 공용 기준이 되어 있었고, 검색 엔진도 이 셋을 순위 신호로 쓴다. 그래서 나는 논쟁의 여지 없이 이 셋을 기본 자로 삼았다.


3. 좋음의 기준선

지표에는 각각 통과선이 정해져 있었다. 로딩은 대략 2.5초 안에 최대 콘텐츠가 떠야 좋음으로 친다. 최근에는 이 선을 2초로 조이자는 흐름도 생겨서, 2초와 2.5초 사이는 개선 필요 구간으로 밀려났다. 반응성은 다음 화면 갱신까지 200밀리초 안에 들어와야 하고, 시각 안정성은 누적 이동량이 0.1 아래여야 한다.


이 숫자들은 누군가 기분으로 정한 게 아니라, 사람이 지연을 어떻게 느끼는지에 대한 연구에 기반한 것이었다. 100밀리초 안쪽이면 즉각적이라 느끼고, 1초를 넘으면 흐름이 끊긴다고 느낀다는 오래된 인지 연구가 바탕에 있었다. 나는 이 기준을 그냥 외우기보다, 왜 그 선인지 이해하고 나니 목표가 훨씬 구체적으로 다가왔다.


중요한 건 이 통과선이 실험실 값이 아니라 현장 값 기준이라는 점이었다. 그것도 앞 편에서 말한 75 백분위수로 본다. 내 방문의 4분의 3이 2.5초 안에 떠야 로딩이 좋음이 되는 것이다. 소수의 빠른 접속으로는 통과하지 못한다. 나는 이 엄격함이 마음에 들었다. 대다수를 챙기라는 압박이었기 때문이다. 평균만 보면 잘 쓰는 소수의 좋은 경험이 나머지의 고통을 가려버리는데, 백분위수 기준은 그 가림막을 걷어내고 실제로 힘들어하는 사람들을 정면으로 보게 만들었다.


기준선은 목표를 명확하게 만들어줬다. 막연히 빠르게가 아니라 2.5초 아래로라는 구체적 과녁이 생기니, 언제 손을 떼야 할지도 분명해졌다. 나는 각 페이지마다 세 숫자를 적어두고, 빨간불이 켜진 지표부터 순서대로 공략했다. 통과선은 우선순위표이자 완료 조건이었다.


4. 지표끼리의 줄다리기

세 지표를 동시에 좋게 만드는 건 생각보다 까다로웠다. 하나를 개선하면 다른 하나가 나빠지는 경우가 종종 있었기 때문이다. 예를 들어 첫 화면을 빨리 띄우려고 많은 걸 미리 불러오면 자바스크립트가 몰려서 반응성이 나빠졌다. 반대로 반응성을 챙기려고 실행을 잘게 쪼개면 화면이 조금씩 늦게 완성됐다.


시각 안정성도 로딩과 부딪혔다. 이미지를 빨리 보여주려고 크기 정보 없이 먼저 그리면, 나중에 실제 크기가 정해지면서 화면이 밀려 안정성이 무너졌다. 결국 세 지표는 서로 당기는 줄 같아서, 한쪽만 세게 당기면 균형이 깨졌다. 나는 어느 하나를 극단으로 밀지 않고 셋을 함께 통과선 위에 올리는 쪽을 택했다.


이 줄다리기 때문에라도 세 개를 동시에 봐야 했다. 로딩만 보고 최적화하다가 반응성이 무너진 걸 뒤늦게 발견한 적이 있었다. 그 뒤로는 하나를 손댈 때마다 나머지 둘도 함께 확인했다. 한 지표의 승리가 다른 지표의 패배로 상쇄되면 전체적으로는 제자리였다. 나는 커밋 하나를 올릴 때마다 세 숫자를 나란히 적어 비교했고, 하나가 좋아지고 다른 하나가 나빠졌다면 그 교환이 정말 이득인지 따로 판단했다.


균형을 잡는 감각은 숫자를 자주 볼수록 늘었다. 어떤 변경이 어느 지표를 건드리는지 경험이 쌓이니, 나중에는 손대기 전에 어느 쪽이 흔들릴지 예측할 수 있었다. 측정과 경험이 함께 자라면서 나는 점점 덜 헤맸다.


5. 지표는 목적이 아니라 대리자

마지막으로 스스로 경계한 점이 있다. 지표는 사용자 경험의 대리자일 뿐, 그 자체가 목적이 아니라는 것이다. 숫자를 좋게 만드는 데만 몰두하다 보면, 정작 사람은 불편한데 점수만 좋은 이상한 상태에 빠질 수 있었다. 나는 숫자를 좇되 항상 실제 화면을 눈으로 확인했다.


가끔은 지표를 만족시키려는 꼼수가 사용자 경험을 해치기도 했다. 예를 들어 안정성 점수를 위해 콘텐츠를 늦게 밀어 넣으면 이동량은 0이 되지만 사람은 더 오래 기다린다. 이런 건 숫자를 속이는 것이지 개선이 아니었다. 나는 지표를 게임하지 않으려고 조심했다. 목표는 언제나 사람이었다.


그래서 나는 지표를 나침반으로만 썼다. 방향은 지표가 알려주지만, 도착했는지는 내 눈과 사용자의 반응으로 확인했다. 이 둘이 어긋나면 지표가 아니라 사람 쪽을 믿었다. 숫자는 사람을 위한 도구지, 사람이 숫자를 위한 존재는 아니었다. 지표가 통과선을 넘었는데도 사용자가 불편해한다면, 그건 내가 잘못된 것을 재고 있다는 신호였고 그럴 땐 무엇을 재는지부터 다시 의심했다.


이렇게 무엇을 재는지가 정해졌으니, 이제 각 지표를 하나씩 깊이 파고들 차례다. 다음 편에서는 세 지표 중 사용자가 가장 먼저 마주하는 로딩, 즉 최대 콘텐츠가 그려지는 시간을 다룬다. 첫 화면이 왜 늦게 뜨는지, 그리고 내가 그것을 어떻게 앞당겼는지 구체적으로 풀어보겠다.