본문 바로가기
개발기초

개발기초 Vue.js computed (캐싱, 반응형, 성능 최적화)

by bestdevgear 2026. 5. 30.
반응형

Vue.js computed (캐싱, 반응형, 성능 최적화)

Vue.js를 처음 배울 때 computed를 보고 "그냥 함수랑 뭐가 다르지?"라고 생각하신 적 있으신가요. 저도 그랬습니다. 그런데 제조 MES 프로젝트에서 설비 상태 데이터를 실시간으로 화면에 뿌리다가 브라우저가 버벅거리기 시작했을 때, 그 생각이 완전히 바뀌었습니다. computed는 단순한 편의 기능이 아니었습니다.

methods로 버텼던 시절, 그리고 한계

처음 MES 화면을 만들 때는 설비 상태 계산 로직을 전부 methods로 처리했습니다. 데이터가 적을 때는 문제가 없었는데, 실시간으로 들어오는 데이터가 많아지기 시작하면서 테이블 필터링과 상태 집계 함수가 화면이 갱신될 때마다 반복 실행되는 상황이 벌어졌습니다. 버튼 하나 눌러도 화면 전체가 버벅거렸고, 처음에는 서버 문제인 줄 알았습니다.

여기서 핵심 차이를 짚어야 합니다. Vue.js의 반응형 시스템(Reactivity System)은 데이터 상태가 바뀔 때 화면을 자동으로 갱신해주는 구조입니다. 쉽게 말해, 데이터가 바뀌면 Vue가 "어느 부분을 다시 그려야 하는지" 스스로 추적하는 방식입니다. 문제는 methods는 이 반응형 추적과 무관하게, 화면이 다시 렌더링될 때마다 무조건 함수를 새로 실행한다는 점입니다. 아무리 관련 없는 데이터가 바뀌어도 methods는 매번 돌아갑니다.

제가 직접 써봤는데, 설비 수십 개의 상태를 계산하는 함수가 1초에도 여러 번 실행되고 있었습니다. 이걸 computed로 바꾸고 나서야 화면 반응 속도가 눈에 띄게 안정됐습니다.

캐싱(Caching)이란 이전에 계산한 결과를 저장해두고, 관련 데이터가 바뀌지 않으면 저장된 값을 그대로 사용하는 방식입니다. computed는 이 캐싱 구조 덕분에 의존하는 데이터가 변경될 때만 다시 계산하고, 그 외에는 이전 결과를 재사용합니다. methods와 computed의 차이를 정리하면 이렇습니다.

  • methods: 화면이 렌더링될 때마다 매번 실행, 캐싱 없음
  • computed: 의존 데이터가 바뀔 때만 재계산, 그 외에는 캐시된 값 반환
  • watch: 특정 데이터 변화를 감지하고 부수효과(side effect) 처리에 적합

computed의 캐싱 구조, 어디까지 믿을 수 있나

솔직히 이건 예상 밖이었습니다. computed를 처음 알게 됐을 때 "Vue가 알아서 최적화해주는구나"라고 생각했는데, 실제로는 그렇게 단순하지 않았습니다. Vue.js가 반응형 시스템을 제공하는 건 맞지만, 개발자가 데이터 흐름과 렌더링 구조를 잘못 설계하면 성능 문제는 그대로 발생합니다.

의존성 추적(Dependency Tracking)이란 Vue가 computed 함수 내부에서 어떤 반응형 데이터를 참조하는지 자동으로 기록하고, 해당 데이터가 바뀔 때만 재계산을 트리거하는 메커니즘입니다. Vue 공식 문서에서도 computed의 캐싱은 반응형 의존성에 기반한다고 명시하고 있습니다(출처: Vue.js 공식 문서).

여기서 함정이 하나 있습니다. computed 안에 API 호출이나 외부 상태 변경 같은 부수효과(side effect)를 넣으면 Vue의 반응형 흐름이 예측 불가능하게 꼬입니다. 부수효과란 함수 실행 과정에서 외부 상태를 변경하거나, 비동기 요청을 보내는 등 함수 바깥에 영향을 미치는 동작을 말합니다. computed는 순수하게 계산만 해야 하는 공간입니다.

제 경험상 이건 좀 다릅니다. 초반에는 computed 안에 조건부 API 호출 로직을 집어넣은 적도 있었는데, 렌더링 타이밍이 뒤틀리면서 데이터가 엉뚱한 시점에 갱신되는 문제가 생겼습니다. 나중에야 그 역할은 watch 또는 라이프사이클 훅(Lifecycle Hook)에서 처리해야 한다는 걸 몸으로 깨달았습니다. 라이프사이클 훅이란 컴포넌트가 생성되고, 마운트되고, 업데이트되고, 소멸되는 각 시점에 개발자가 원하는 코드를 실행할 수 있게 해주는 Vue의 내장 함수들입니다.

프론트엔드 개발에서 렌더링 최적화는 꾸준히 논의되는 주제입니다. 실제로 크롬 개발자 도구의 성능 탭을 통해 렌더링 비용을 측정하면, methods와 computed의 차이가 수치로 드러납니다(출처: Google Chrome DevTools).

실무에서 computed를 제대로 쓰는 방법

제가 MES 프로젝트를 거치면서 결국 정착한 방식은 역할을 명확하게 구분하는 것이었습니다. computed는 오직 계산과 파생 상태 반환에만 씁니다. 상태 변경이나 비동기 처리는 절대 넣지 않습니다. 그 경계를 지키고 나서야 코드가 훨씬 읽기 쉬워졌고, 나중에 합류한 팀원도 데이터 흐름을 빠르게 파악할 수 있었습니다.

실무에서 computed를 올바르게 사용하기 위해 제가 기준으로 삼는 포인트는 다음과 같습니다.

  • 반환값이 기존 반응형 데이터에서 파생된 계산 결과인가 → computed 적합
  • 특정 데이터 변화에 반응해 외부 API를 호출하거나 로직을 실행해야 하는가 → watch 적합
  • 사용자 이벤트에 반응하거나 매번 새 결과가 필요한가 → methods 적합
  • 컴포넌트 생성·마운트 시점에 초기 데이터를 불러와야 하는가 → 라이프사이클 훅 적합

이 구분이 처음에는 이론처럼 느껴졌는데, 직접 여러 프로젝트를 지나고 나니 이게 Vue.js 코드 품질을 결정하는 가장 기본적인 설계 감각이라는 걸 체감했습니다.

또 하나 강조하고 싶은 건 computed의 게터(getter)와 세터(setter) 구조입니다. 게터란 값을 읽어오는 함수이고, 세터란 값을 설정하는 함수입니다. computed는 기본적으로 읽기 전용 게터만 사용하는 경우가 많지만, 필요에 따라 세터를 정의해서 양방향 데이터 흐름을 구성할 수도 있습니다. 다만 세터를 남용하면 데이터 흐름이 복잡해지므로, 꼭 필요한 경우에만 제한적으로 사용하는 게 좋다고 생각합니다.

결국 Vue.js를 잘 다루는 개발자는 문법을 많이 아는 사람이 아니라, 데이터가 어디서 만들어지고 어디서 소비되는지 계속 의식하면서 코드를 설계하는 사람이라고 저는 생각합니다. computed 하나를 제대로 이해하는 게 단순한 기능 학습이 아니라, Vue의 반응형 철학 전체를 이해하는 출발점이 됩니다. MES 프로젝트에서 버벅거리던 화면 앞에서 느꼈던 그 답답함이, 결국 저한테는 가장 좋은 교과서였습니다.


참고: https://dkkim2318.tistory.com/158

반응형

소개 및 문의 면책조항 개인정보처리 방침

© 2026 블로그 이름