Case Study · cafe24 skin

장바구니 개편에서 부딪힌 것들

2026년 8월 25일부터 9월 10일까지 자사몰 장바구니를 새로 만들면서 막혔던 문제와, 다음에 같은 화면을 만들 때 바로 꺼내 쓸 처방을 모았습니다. 화면 디자인이 아니라 「왜 이렇게 만들었는지」가 이 문서의 내용입니다.

11.2 → 4.5MB페이지 무게
0.94 → 0.00첫 화면 내려앉음
536 → 52ms금액 따라오는 시간
7 / 7회귀 검사 · 3개 엔진
← 디자인 포탈

01가장 비쌌던 다섯 가지

고치는 데 오래 걸린 순서입니다. 증상만 보고는 원인이 안 보이던 것들입니다.

화면은 맞는데 서버는 다른 줄을 지우고 있었다반나절

증상
상품을 담고 다른 줄을 지우면 엉뚱한 상품이 사라졌다. 화면은 늘 정상으로 보였다.
원인
새로 담은 줄과 원래 줄의 체크박스 번호가 둘 다 _0으로 겹쳤다. 서버는 번호로 줄을 찾는다. 우리가 화면을 먼저 고쳐 두는 방식이라 잘못된 결과가 가려졌다.
처방
줄을 갈아끼울 때마다 체크박스·수량·옵션 링크 번호를 순서대로 다시 매긴다.
화면이 맞다고 서버도 맞다고 믿지 마라. 미리 그려 두는 방식은 틀린 결과까지 가린다. 서버에 실제로 무엇이 갔는지를 따로 확인할 것.

상품을 담으면 페이지가 얼어붙었다한나절

증상
담기 직후 화면 전체가 멈춰 아무것도 눌리지 않았다.
원인
할인 줄을 지키는 감시자와 금액을 쓰는 코드가 서로를 깨웠다. 없는 클래스를 지우는 무효 호출도 브라우저는 변화로 친다. 그래서 값이 하나도 안 바뀌는데 무한히 돌았다.
처방
바뀔 때만 쓴다. 쓰기 전에 지금 값과 비교하고, 감시자에는 1초에 몇 번 이상이면 스스로 멈추는 차단기를 단다.
같은 값을 다시 쓰는 코드는 화면엔 안 보이지만 재조립을 한 바퀴 더 돌린다. 느려지는 원인의 절반이 여기였다.

첫 화면이 1초 뒤에 「타닥」 내려앉았다layout-shift 0.56

증상
장바구니에 들어가면 목록이 먼저 뜨고, 1초 뒤 제목과 수량 버튼이 끼어들며 화면이 밀렸다.
원인
우리 코드가 파일 맨 끝에 있어, 카페24 기본 화면이 먼저 그려진 뒤에 재조립됐다. 좋음 기준은 0.1인데 0.56이었다.
처방
조립이 끝날 때까지 가리고, 끝난 그 순간에 드러낸다. 완성본만 한 번 그려진다. 코드가 죽어도 1.5초 뒤 무조건 드러나는 안전장치를 같이 둔다.
「그려진 뒤에 조립」하는 구조는 어디서든 튄다. 옵션 시트·하단 결제바·목록까지 세 번 같은 패턴이었다. 조립이 자바스크립트인 이상 가림막이 정답이다.

담고 나면 화면이 저절로 흘러내렸다실기기에서만

증상
갤럭시와 아이폰에서 담기 1초 뒤 화면이 수십에서 200px씩 저절로 움직였다. 에뮬레이터에서는 재현되지 않았다.
원인
스크롤을 시키는 코드를 전부 추적했더니 호출이 0건이었다. 남은 건 브라우저 기능. 목록이 갈아끼워질 때 기준 요소를 붙잡아 위치를 맞추는 동작이 우리 재조립과 엇갈렸다.
처방
그 기능을 끈다. 삽입 보정은 우리가 직접 한다.
추적기에 호출 0건이 찍히면 코드가 아니라 브라우저 기능을 의심할 것. 실기기 계측 없이는 못 잡는 종류다.

금액이 「0원」과 「확인 중」으로 깜빡였다두 번 반복

증상
수량을 올리면 하단바가 잠깐 0원이 됐다가 제 값으로 돌아왔다. 무료배송 게이지도 「장바구니 금액을 확인 중」으로 되돌아갔다.
원인
서버에서 새로 받아온 화면을 그대로 베꼈는데, 그 안의 금액과 문구는 아직 계산 전의 자리표시자였다.
처방
받아온 화면에서 베낄 칸과 베끼면 안 되는 칸을 나눈다. 금액·게이지는 우리가 방금 계산한 값으로 쓴다.
같은 실수를 하단바에서 한 번, 게이지에서 또 한 번 했다. 「서버 화면을 통째로 신뢰」가 기본값이면 안 된다.

02숫자로 남은 것

전부 같은 조건에서 잰 값입니다. 느린 기기를 흉내 내려고 처리 속도를 4배 낮춰 쟀습니다.

항목전후무엇을 바꿨나
페이지 무게 (PC)11.2MB4.5MB사진을 화면 크기로 줄이고, 글꼴을 조각 판으로
첫 화면 내려앉음0.940.00가림막 + 조립 끝난 틱에 드러내기
금액이 따라오는 시간536ms52ms자리표시자 베끼기 중단
멈추는 프레임 (2.5초 동안)8건4건같은 값 다시 쓰기 제거
PC 자바스크립트 실행383ms242ms남의 관찰자와의 되먹임 차단
글꼴 내려받기2,536KB875KB통짜 한 벌 대신 조각 판

03검사 도구가 거짓말한 순간들

「고쳤다」고 잘못 믿은 경우가 다섯 번 있었습니다. 다음에 같은 함정을 피하려고 적어 둡니다.

시험이 전부 통과했는데 아무것도 안 하고 있었다. 명령을 추출하는 부분이 조용히 비어 있어 「해당 없음」으로 통과였다. 전부 통과하면 먼저 그 경로를 진짜 탔는지 본다.
발행 직후 화면은 옛것이다. 카페24 캐시가 PC와 모바일이 따로 돌고, 상품마다도 따로 풀린다. 한 번 재보고 「안 됐다」로 판정하지 말고 서버 파일부터 확인한다.
새 창은 빈 주소로 열렸다가 이동한다. 찜 버튼이 어디로 가는지 볼 때 바로 주소를 읽으면 실패로 보인다. 주소가 잡힐 때까지 기다린다.
화면 폭이 좁으면 결제 버튼이 화면 밖에 남는다. 검사 창이 낮아서 안 보였을 뿐인데 「버튼이 죽었다」로 읽을 뻔했다.
덮고 있는 팝업을 먼저 걷어야 한다. 클릭 검사와 색 비교가 전부 팝업에 막혀 엉뚱한 결과를 냈다.

04다음에 이 순서로 한다

같은 종류의 화면을 새로 만들 때 바로 따라갈 순서입니다.

  1. 라이브를 새로 받아 그 위에서 고친다. 어제 사본으로 고치면 다른 사람 수정이 조용히 되돌아간다.
  2. 우리 코드는 한 덩어리로 묶고 그 덩어리만 갈아끼운다. 올린 뒤 되받아 지문(md5)까지 맞춰 본다.
  3. 조립이 끝날 때까지 가린다. 가림막에는 반드시 시간 안전장치와 자바스크립트 꺼짐 대비를 같이 둔다.
  4. 서버 응답에서 베낄 칸과 아닌 칸을 먼저 정한다. 금액·상태 문구는 자리표시자라고 보고 시작한다.
  5. 값이 바뀔 때만 쓴다. 감시자에는 스스로 멈추는 차단기를 단다.
  6. 회귀 검사를 먼저 만들고 고친다. 담기 → 수량 올려 무료배송 넘기기 → 내리기 → 체크 껐다 켜기까지 한 바퀴, 크롬과 사파리 엔진 양쪽에서.
  7. 느린 기기를 흉내 내서 잰다. 빠른 PC에서는 모든 문제가 사라진다.
  8. 마지막은 실기기다. 흘러내림과 좌우 흔들림은 에뮬레이터에서 절대 안 나온다.

05만들어 둔 검사 도구

이 작업에서 새로 만든 것들입니다. 파일 이름 그대로 다음 작업에 씁니다. 검사 파일은 세션 임시 폴더(scratchpad), 발행 도구는 C:/tmp에 있습니다.

?probe=1주소 뒤에 붙이면 폰에서 튐·끊김·스크롤 호출이 쌓이고 「결과 복사」로 보낼 수 있다. 블록 안에 내장
_regress.js담기 → 수량 올려 무료배송 넘기기 → 내리기 → 체크 토글. 매 단계 상품금액 − 할인 + 배송 = 총액 검사. chromium · webkit · pc 세 번
_perf.js · _imgaudit.js총 무게와 긴 작업. 사진이 화면보다 몇 배 큰지, 같은 파일을 두 번 받는지
_gauge1.js버튼 누른 뒤 무엇이 몇 밀리초에 바뀌는지 + 통신 시간표. 원인을 시간으로 좁힐 때
_cls1.js첫 로딩 내려앉음(layout-shift)을 원인 요소까지 찍어 준다
_hscroll.js · _tacontrol.js화면 밖으로 나간 요소 찾기 / 내 터치 도구가 규칙을 반영하는지 대조
_skytry.js발행하지 않고 라이브 화면에 색만 갈아끼워 후보 네 개를 한 장으로
_wishprobe.js · _wishverify.js버튼이 어느 플랫폼으로 가는지 실제로 눌러 확인

06어디를 고치면 되나

파일과 도구를 짝지어 둡니다. 다음에 여기부터 열면 됩니다.

고칠 것파일 (skin8 기준)올리는 도구
장바구니 기능·디자인order/basket.html 안의 ij-cart26 덩어리_put17_cart.js → _put8_basket.js
첫 로딩 가림막같은 파일 본문 위쪽 <style id="ij26-veil">_patch_base_0910.js (두 스킨 공용)
글꼴·측정 스크립트layout/basic/layout.html_prep8_layout.js → _put8_layout.js
상세 PC 결제 버튼·찜product/detail.html 안의 ij-pckakao 덩어리_put8_detail_kakaowish.js
메인 추천 카드layout/basic/inc/cate.html_put8_cate_passalacqua.js
메인 숫자 슬라이드layout/basic/inc/intro2.html_put8_intro2_passalacqua.js
헤더 메뉴layout/basic/navigation.html (PC·모바일 두 벌)_put8_nav_passalacqua.js
발행 도구는 전부 같은 틀이다. 라이브를 새로 받는다 → 앵커가 정확히 한 개인지 센다 → 넣은 것 말고 한 글자도 안 달라졌는지 되돌려 대조한다 → 백업 → 올림 → 되받아 지문 대조. 이 틀을 벗어나면 사고가 났다.
줄바꿈이 파일마다 다르다. 장바구니와 메인 조각은 한 종류, 헤더는 다른 종류다. 여러 줄 앵커를 한 종류로 고정해 쓰면 「앵커 0개」로 조용히 실패한다. 파일에서 읽어 맞출 것.
같은 내용이 두 벌 적힌 파일이 있다. 헤더 메뉴가 그렇다. 한 곳만 고치면 모바일에서만 옛 화면이 남는다.

07이번에 굳힌 원칙

바뀌지 않으면 건드리지 않는다. 같은 값을 다시 쓰는 것이 느림과 떨림의 가장 흔한 원인이었다.
완성될 때까지 가리고 한 번에 보여준다. 중간 과정을 보여주면 반드시 튄다.
남의 코드는 옮겨 쓰되 다시 배치하지 않는다. 간편결제 버튼은 위치를 바꾸는 순간 클릭이 엉뚱한 곳으로 샌다.
측정 없이 단정하지 않는다. 까 보면 거의 매번 가정이 뒤집혔다. 「호출 0건」 같은 관측이 가장 좋은 단서였다.
같은 실수가 두 번 나오면 세 번째는 도구로 막는다. 검사 겹침, 출력 파이프, 유령 프로세스는 이제 자동으로 걸린다.