pile·
프론트엔드·티몬티몬·

[알쓸신팁-부록] Javascript 성능 저하 방지법

프론트엔드에서 작은 실수 하나로 화면 성능이 떨어지는 상황을 막는 세 가지 방법을 다룬 글이다. 전역 객체 캐싱, 문자열 조합 방식, 노드 생성 방식을 각각 비교 코드와 함께 짚는다. 티몬의 실제 코드를 고치는 예시도 함께 나온다.

핵심 포인트
  • 전역 변수는 스코프 체인의 마지막에 있어 반복 접근하면 탐색 비용이 누적된다.
  • document를 지역 변수에 담아두면 스캐닝 대상이 줄어 더 빠르고 안정적으로 실행된다.
  • 반복문 안에서 매번 DOM에 붙이는 대신 문자열로 모아 한 번에 append하면 document 접근이 사라진다.
  • 문자열 조합은 이제 concat이 배열 join보다 빠르므로 옛 상식을 뒤집어야 한다.
  • 노드가 적으면 appendChild가, 많으면 innerHTML이 빠르다.
상세 정리
  • 문제 상황: 프론트 개발 중 작은 실수로 화면 성능이 크게 떨어지는 경우가 있어 미리 막을 방법 세 가지를 든다.
  • 방법 1 원리: 전역 변수 내에서 태그 탐색 같은 일을 하면 스코프 체인을 매번 타게 돼 비용이 커진다.
  • 방법 1 코드: 개선 전 함수는 반복문 안에서 document에 계속 접근하고, 개선 후 함수는 전역 객체 참조를 지역 변수에 복사해 그 변수로 접근하며 반복문의 length도 미리 담아둔다.
  • jQuery 적용: 같은 선택자를 네 번 호출하는 대신 한 번 담아 변수로 재사용하는 편이 효율적이다.
  • 실제 코드 개선: option 태그를 인원수만큼 붙이던 코드를 문자열로 누적한 뒤 한 번만 append하도록 바꿨다. 인원이 아무리 많아도 document 접근이 없다.
  • 측정: 백만 번 루프에서 매번 getElementById로 값을 읽고 쓰는 쪽과 값을 지역 변수에 담아 계산하는 쪽을 비교하면 시간 차가 크게 벌어진다. 극단적인 반복이긴 하지만 스크립트로 화면 대부분을 제어한다면 무시하기 어렵다고 본다.
  • 방법 2 배경: IE 6과 7 시절에는 브라우저의 스크립트 성능이 낮아 concat이 배열 join보다 느리다고 알려져 있었다.
  • 방법 2 현재: 브라우저 성능이 좋아지면서 concat이 join보다 훨씬 빨라졌으므로 가독성도 좋고 쓰기도 편한 concat을 쓰라고 권한다.
  • 방법 2 검증: 백만 번 루프에서 concat 쪽이 더 많은 문자열을 합치는데도 더 빨랐고, 공개 벤치마크 사이트에서 다섯 가지 방식을 비교해도 짧은 concat이 가장 빠르고 join이 가장 느렸다.
  • 방법 3 기준: innerHTML과 appendChild는 만들 노드의 양에 따라 성능이 뒤집힌다.
  • 방법 3 적은 경우: innerHTML은 문자열을 해석해 노드로 만드는 일을 함께 해야 해서 노드가 적으면 appendChild가 빠르다.
  • 방법 3 많은 경우: appendChild를 연속 수행하면 호출 횟수가 그만큼 늘어나 innerHTML보다 느려진다.
  • jQuery append와의 차이: append는 요소 개수만큼 만들어 매번 할당하지만 innerHTML은 노드를 직렬화해 한 번에 할당하므로 더 빠르다.
왜 읽나화면이 멈춘 듯 느려지는 구간을 찾고 있다면 반복문 안의 DOM 접근과 노드 생성 방식이라는 두 지점을 먼저 확인하게 해준다.
티몬
티몬 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 프론트엔드·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

    항공 프론트엔드 구축기 (7/10): 창구를 하나만 두었습니다

    여기어때 항공 서비스 프론트엔드가 웹과 앱 웹뷰 두 환경에서 동일한 함수 호출로 동작하는 앱 브릿지 추상화 레이어를 설계한 과정을 다룬다. iOS·안드로이드 규약 차이와 "웹에 존재하지 않는 브릿지를 어떻게 호출하나"라는 문제를 단일 추상화 층으로 해결한 구현 사례다.

    요약 이어보기
    #react#typescript#webview+2