웹 성능

Web Performance

개념

화면이 얼마나 빨리 뜨고 조작에 얼마나 빨리 반응하는지를 숫자로 재고 그 숫자를 줄이는 개발 영역입니다.

등장 배경

느리다는 말은 오랫동안 숫자가 아니라 기분이었습니다. 고객이 느리다고 하면 개발자가 자기 컴퓨터에서 화면을 열어 보고 괜찮은데요 하고 답하는 대화가 반복됐습니다. 두 사람 다 거짓말을 하지 않았습니다. 사무실의 유선 인터넷과 최신 노트북에서 1초에 뜨는 화면이, 지하철에서 3년 된 휴대폰으로 열면 6초가 걸립니다. 같은 화면을 두고 체감이 갈리는데 둘을 견줄 공통의 숫자가 없으니 대화가 거기서 멈췄습니다.

재는 방법이 아예 없지는 않았습니다. 초기에는 브라우저가 페이지를 다 읽었다고 판단하는 시점 하나를 재서 그것을 속도라고 불렀습니다. 그런데 이 숫자는 사람이 겪는 것과 자주 어긋났습니다. 본문이 이미 다 보이는데 아래쪽 추적 스크립트가 아직 돌고 있어 완료로 잡히지 않는 경우가 있고, 반대로 완료로 잡힌 뒤에 큰 이미지가 들어오면서 화면이 다시 출렁이는 경우도 있습니다. 숫자는 좋아졌는데 고객 문의는 그대로인 상황이 생기면 그 숫자는 근거로 쓰이지 못합니다.

그래서 측정이 하나에서 여럿으로 갈라졌습니다. 사람이 화면을 만나는 과정을 세 순간으로 쪼갠 것이 지금의 방식입니다. 볼 것이 언제 보이는가, 눌렀을 때 언제 반응하는가, 보고 있는 동안 흔들리지 않는가. 각각이 다른 원인에서 오고 다른 방법으로 고쳐지기 때문에 한 숫자로 뭉쳐 두면 무엇부터 손댈지 정할 수 없습니다.

이 셋을 나눠 놓으면 같은 느리다는 말이 서로 다른 신고로 갈립니다. 첫 화면이 안 뜬다는 말과 버튼이 안 먹힌다는 말과 글을 읽는데 자꾸 밀린다는 말은 고쳐야 할 코드가 전혀 다른 자리에 있습니다. 앞의 것은 처음에 내려받는 양이 많아서 생기고, 가운데 것은 브라우저가 다른 계산을 하느라 입력을 못 받아서 생기고, 마지막 것은 늦게 도착한 요소가 자리를 미리 안 잡아 둬서 생깁니다.

두 번째 갈래는 어디서 재느냐입니다. 개발자 컴퓨터에서 조건을 고정해 놓고 재는 방식과, 실제 사용자의 브라우저에서 벌어진 일을 모아 보는 방식은 서로 다른 답을 냅니다. 앞쪽은 고치기 전후를 비교하기에 좋고 뒤쪽은 지금 고객이 실제로 겪는 상태를 보여 줍니다. 고정 조건에서 잰 값은 같은 코드를 열 번 재도 거의 같은 숫자가 나와서 이번 배포가 나아졌는지를 가릴 수 있고, 실제 사용자에게서 모은 값은 기기와 망이 제각각이라 평균보다 상위 25퍼센트가 얼마나 느린지를 함께 봅니다. 앞쪽만 보면 느린 기기와 느린 망을 쓰는 사람들이 통째로 빠집니다. 사무실 장비로만 확인하는 팀이 고객 문의와 계속 어긋나는 이유가 여기 있습니다.

성능이 개발팀 안쪽의 취향 문제에서 벗어난 것은 숫자가 돈과 연결되면서부터입니다. 첫 화면이 1초에서 3초로 밀리면 그사이에 나가 버리는 사람이 눈에 띄게 늘어난다는 측정이 여러 곳에서 나왔고, 검색 엔진이 속도 지표를 순위 계산에 넣기 시작하면서 마케팅 쪽에서도 같은 숫자를 들여다보게 됐습니다. 그때부터 느린 것은 불편이 아니라 매출과 유입이 걸린 문제로 다뤄집니다.

분야 구성

이 아래 묶인 용어는 세 갈래로 나뉩니다. 무엇을 재는지 정해 둔 지표, 재 놓은 숫자를 줄이는 기법, 그리고 시간이 갈수록 느려지게 만드는 문제입니다. 순서가 있습니다. 재지 않으면 어디가 느린지 모르고, 모르면 기법을 아무 데나 쓰게 됩니다.

지표는 사용자가 겪는 순간을 나눠 맡습니다. 네 가지가 있고 앞의 셋이 화면에서 벌어지는 일을, 넷째가 그 앞 구간인 서버와 망을 봅니다.

  1. LCP — 화면에서 가장 큰 덩어리가 그려지기까지 걸린 시간입니다. 대개 맨 위 이미지나 제목 블록이 그 덩어리이고, 그것이 보이는 순간을 사람들은 페이지가 떴다고 느낍니다. 2.5초 안쪽을 좋은 수준으로 봅니다. 4초가 넘으면 광고를 눌러 들어온 사람의 상당수가 화면을 보기도 전에 뒤로 가기를 누릅니다.
  2. INP — 누르거나 입력한 뒤 화면이 반응하기까지 걸린 시간입니다. 버튼을 눌렀는데 아무 일도 일어나지 않는 구간이 여기서 잡힙니다. 0.2초를 넘기면 사람들은 한 번 더 누르고, 그 결과로 같은 요청이 두 번 들어갑니다. 댓글이 두 번 달리거나 결제가 두 번 시도되는 사고가 여기서 나오므로, 반응이 늦는 구간은 눌린 직후에 눌렸다는 표시라도 먼저 내보내 막습니다.
  3. CLS — 보고 있는 동안 화면 요소가 갑자기 밀린 정도를 누적한 값입니다. 늦게 도착한 이미지나 배너가 자리를 비집고 들어오면 읽던 문장이 아래로 내려가고, 누르려던 버튼 자리에 다른 버튼이 와 있습니다. 눌러서는 안 될 것을 누르게 만드는 지표라 체감 불쾌도가 가장 큽니다.
  4. TTFB — 요청을 보낸 뒤 서버가 첫 바이트를 돌려주기까지 걸린 시간입니다. 브라우저가 아직 아무것도 그릴 수 없는 구간이라, 이 값이 1초면 앞의 세 지표는 그 1초를 깔고 시작합니다. 화면 쪽을 아무리 손봐도 안 줄어드는 시간이 있으면 대개 여기입니다.

앞의 셋은 로딩·반응·안정성을 한 묶음으로 보는 코어 웹 바이탈이라는 이름으로 함께 불립니다. 검색 엔진이 순위에 반영한다고 말할 때 가리키는 것이 이 묶음이라, 개발팀과 마케팅이 같은 세 숫자를 놓고 이야기하게 됩니다.

기법은 숫자를 줄이는 손입니다. 네 가지가 각각 다른 낭비를 없앱니다.

  1. 캐싱 — 한 번 만든 결과를 저장해 두고 다음 요청에 그대로 내주는 방식입니다. 로고 이미지처럼 바뀌지 않는 파일은 한 번 받은 브라우저가 다시 받지 않게 하고, 목록 화면처럼 계산이 무거운 응답은 서버가 잠시 들고 있다가 재사용합니다. 그 저장 자리를 사용자 가까운 지역에 두는 것이 CDN입니다. 서울 사용자가 미국 서버까지 다녀오는 왕복 시간이 사라지므로 TTFB 가 눈에 띄게 줄어듭니다.
  2. 압축 — 보내는 데이터를 작게 만들어 전송 시간을 줄입니다. 글자로 된 파일은 반복이 많아 잘 줄어들어서, 1메가바이트짜리 스크립트가 300킬로바이트 안쪽으로 내려가는 일이 흔합니다. 이미 압축된 형식인 사진이나 동영상에는 같은 방법이 거의 듣지 않아서, 그쪽은 다음 항목이 따로 맡습니다. 서버 설정 한 줄로 켜지는 경우가 많아 들이는 품 대비 효과가 가장 좋은 자리로 꼽힙니다.
  3. 이미지 최적화 — 화면에 필요한 만큼만 보내게 만드는 일입니다. 300픽셀 자리에 3000픽셀짜리 원본을 넣어 두는 실수가 가장 흔하고, 형식을 바꾸거나 화면 밖 이미지를 나중에 받게 미루는 것도 여기 속합니다. 페이지 용량의 절반 이상이 이미지인 경우가 많아 효과가 가장 빨리 보입니다.
  4. 프리페치 — 곧 필요할 것을 미리 받아 두는 방식입니다. 목록에서 상세로 넘어가는 이동이 잦다면 목록이 한가할 때 상세 화면의 코드를 미리 내려받아 둡니다. 다만 미리 받는 것은 지금 필요한 것과 대역폭을 나눠 쓰므로, 아무거나 미리 받으면 첫 화면이 오히려 늦어집니다.

문제는 시간이 지나면서 나빠지는 쪽입니다. 메모리 누수는 다 쓴 자원이 반환되지 않고 쌓여 브라우저가 점점 무거워지는 현상입니다. 화면을 열자마자 재는 지표로는 잡히지 않고, 같은 탭을 하루 종일 열어 두는 제품에서만 오후에 드러납니다. 협업 문서 툴처럼 사용자가 탭을 닫지 않는 서비스는 첫 화면 속도보다 이쪽이 더 큰 불만을 만듭니다.

세 갈래는 한 방향으로 물려 있습니다. 지표가 어디가 느린지 가리키고, 그 자리에 맞는 기법을 골라 쓰고, 고친 뒤에 같은 지표로 확인합니다. 순서를 건너뛰면 대개 이미 빠른 곳을 더 빠르게 만드는 데 시간을 씁니다.

실무 용례

"LCP 가 4초인데 TTFB 만 2초예요. 화면 쪽 먼저 볼 일이 아닙니다."

느린 원인이 그리는 단계가 아니라 서버 응답 단계에 있다는 지적입니다.

"이번 배포 뒤로 CLS 가 0.3 으로 튀었어요. 배너 자리를 안 잡아 둔 것 같습니다."

늦게 들어오는 요소가 기존 화면을 밀어내고 있으니 자리를 미리 비워 두자는 말입니다.

"실험실 점수는 90점인데 실사용자 수치는 그대로예요."

조건을 고정해 놓고 잰 값만 좋아졌을 뿐 실제 고객의 기기와 망에서는 달라진 게 없다는 뜻입니다.

페이지덱에서 이 숫자를 처음 꺼낸 사람은 현우였습니다. 검색으로 들어오는 유입이 몇 달째 제자리였고, 원인을 찾다가 문서 공유 링크로 들어온 방문자의 절반이 화면이 뜨기 전에 나간다는 것을 확인했습니다. 태오가 재 보니 LCP 가 모바일에서 5초가 넘었고, 그중 2초 가까이가 TTFB 였습니다.

고친 순서가 그대로 이 페이지의 순서였습니다. 먼저 공유 문서 응답을 지역별로 나눠 두는 쪽으로 옮겨 TTFB 를 줄였고, 그다음 문서 안의 이미지를 화면 크기에 맞게 줄여 보냈습니다. 두 가지로 LCP 가 2.8초까지 내려왔습니다. 지현은 여기서 멈추자고 했습니다. 남은 0.3초를 줄이는 데 드는 시간이 다음 기능 하나를 내보내는 시간과 비슷했고, 이탈률은 이미 배포 전후로 눈에 띄게 달라져 있었기 때문입니다. 성능 작업은 어디까지 갈지를 정해 두지 않으면 끝이 없습니다.

흔한 오해

성능을 개발팀 내부의 기술 과제로 여기는 오해가 가장 흔합니다. 화면이 몇 초 만에 뜨는지는 코드와 서버의 문제로 보이니 자연스러운 생각입니다. 그런데 이 숫자가 실제로 움직이는 것은 유입과 전환입니다. 첫 화면이 늦으면 광고로 데려온 방문자가 페이지를 보기도 전에 나가고, 검색 엔진도 같은 지표를 순위에 반영합니다. 기술 과제로 분류해 두면 이 일은 늘 기능 개발에 밀립니다. 급하지 않아 보이니 다음 분기로 넘어가고, 그사이 쌓인 이미지와 스크립트 때문에 화면은 매달 조금씩 느려집니다. 1년 뒤에 손대면 고칠 자리가 열 곳으로 늘어나 있고, 어느 배포가 원인이었는지도 알 수 없습니다.

점수를 목표로 삼는 것도 자주 나옵니다. 측정 도구가 100점 만점으로 결과를 보여 주니 90점을 넘기자는 목표가 세워지기 쉽습니다. 그 점수는 정해진 기기와 정해진 망 조건에서 한 번 잰 값입니다. 조건을 고정했기 때문에 고치기 전후를 비교하기에는 좋지만, 그 조건에 없는 사용자는 점수 안에 들어 있지 않습니다. 점수만 보고 달리면 측정 조건에서 잘 나오는 항목부터 손대게 되고, 정작 느린 기기를 쓰는 고객의 체감은 그대로입니다. 그래서 점수는 작업 순서를 정하는 데 쓰고, 나아졌는지는 실제 사용자에게서 모은 값으로 확인합니다. 점수를 목표로 건 팀에서 흔히 벌어지는 일은, 90점을 받으려고 측정 도구가 감점하는 항목만 걷어 내고 정작 용량이 큰 이미지는 그대로 두는 것입니다. 두 숫자가 오래 어긋나 있으면 믿을 쪽은 후자입니다.

같이 보면 좋은 페이지

  • 엔지니어링

    웹 성능이 기술 조직의 어느 갈래에 얹혀 있는지 먼저 봅니다

  • LCP

    세 지표 중 가장 먼저 손대는 숫자라 다음은 여기입니다

  • 코어 웹 바이탈

    같은 숫자가 검색 순위와 마케팅 쪽에서 어떻게 쓰이는지로 이어집니다

하위 용어

연관 용어

마지막 업데이트 2026-09-16