je개발 회고

[ je 개발 회고 ] L 프로젝트 (4) - 페이지 루프 기능 도입

Je-chan 2024. 3. 5. 23:12

1. 페이지 루프 기능에 대한 요구사항

  이번 프로젝트를 진행하면서 UI/UX 에 대한 고민을 굉장히 많이 했다. 부문장님이 우리 프론트엔드 개발자들에게 기대하셨던 건 "데이터를 어떻게 보여줄 것인가" 였고, 또 회사에는 디자이너가 없어 내가 맡은 페이지는 내가 디자인해야 했기에 UI/UX 에 대한 고민을 많이 할 수밖에 없었다. 그래서 나는 UI/UX 관련 서적 총 4권과 웹 자료 1개를 읽으며 UI/UX 에 대한 지식을 넓혔다. 팀에 UI/UX 공부한 것을 바탕으로 발표하는 시간을 가졌었는데, 그때 부문장님, 팀장님을 비롯해서 가장 호응을 많이 얻은 것이 "페이지 루프" 기능이었다. 

 

  "페이지 루프" 기능이란 사용자가 A 라는 페이지에서 b 라는 정보가 궁금해졌다면, b 의 정보를 자세하게 다루는 B 페이지로 네비게이션 바를 이용하지 않고 바로 넘어갈 수 있도록 유도하는 것을 의미한다. 예시를 들면, 발전소가 잘 발전되고 있는지 모니터링하는 페이지가 있고, 발전소에서 어떤 에러 사항이 발생했을 때 이 에러사항들을 상세히 기록하는 페이지가 있다고 하자. 그렇다면, 모니터링하는 페이지에서 발전소에 에러 사항이 발생해 모니터링 페이지에서 표출하고 있으면, 사용자는 이게 무슨 에러사항인지 좀더 상세하게 알 고 싶을 수 있을 것이다. 그러면 해당 에러사항을 표출하는 곳 근처에 에러를 상세히 기록하는 페이지로 넘어가는 링크를 심어 놓아 사용자가 굳이 네비게이션 바를 사용하지 않고도 에러 사항을 볼 수 있는 페이지로 넘어갈 수 있도록 사용자 행동을 유도할 수 있을 것이다. 또, 반대로 에러 사항을 기록하는 페이지에서 어떤 발전소의 에러들을 확인했는데, 그 시간대에 이 발전소의 발전량이 어느 정도로 나왔는지, 아니면 완전히 발전을 못하고 있었는지, 혹은 이 에러의 여파로 이후 발전량에 문제가 발생하진 않았는지 확인할 수 있게 발전소의 지난 발전량을 상세히 기록한 페이지로 넘어가는 링크를 심을 수 있을 것이다. 이처럼 하나의 페이지에서 사용자가 궁금할 수 있을 거 같은 정보가 있다면, 그 정보를 상세하게 보여줄 수 있는 페이지로 넘어갈 링크를 그 정보 근처(혹은 그 정보를 표시하는 텍스트)에 심어두어 사용자가 편리하고 또 회사 입장에서는 우리 플랫폼 내부에서 머물 수 있도록 하는 기능이다. 

 

  그런데 여기에 기능이 하나가 더 추가가 된다. 부문장님은 url 링크만 넘겨 받으면 언제든 그 페이지로 넘어갈 수 있기를 원하셨다. 즉 SSR 처럼, url 의 parameter, query 등을 활용해 해당 링크를 넘겨 받으면 똑같은 화면을 볼 수 있기를 원하셨던 것이다. 이는 url 의  parameter, query 가 곧 그 페이지의 state 처럼 다뤄지는 것이다. 이 기능을 사용하면 사용자들 사이의 커뮤니케이션이 원활해지는 장점이 있다. L Project 의 특성상, 화면을 공유하는 일이 많다. 그래서 사용자들 사이에 "A 페이지에서요 발전소 x 의 2024년 03월 05일 날짜의 데이터가 이상해요. 한 번 확인해주세요" 라고 말하는 경우가 많다. 만약, 위의 기능이 구현돼 있지 않다면, 사용자는 A 페이지에 들어가서 발전소 x 를 선택하고 조회할 날짜로 2024년 03월 05일을 선택한 후 조회 버튼을 눌러 확인해야 할 것이다. 하지만, 위의 기능이 구현되면 "domain.com/pageA?powerPlant=test&date=2024-03-05" 이런 url 하나만 던져서 데이터를 확인해달라는 요청을 할 수 있을 것이다. 

 

 

(1) A 페이지에서 발전소 x 의 2023년 03월 05일 데이터를 보고 있다.

(2) 이 날, 발전소 x 에 이상한 에러가 하나 발생했다는 정보를 확인했다.

(3) 그 정보 텍스트를 클릭하면 해당 정보를 상세하게 다루는 B 페이지로 넘어간다.

(4) 이때, B 페이지에서도 발전소 x, 2023년 03월 05일 날짜가 선택되어 정보를 보여준다.

(5) 지금 B 페이지에서의 URL 을 복사해서 다른 사용자의 컴퓨터에 해당 URL 로 들어가더라도 똑같이 발전소 x, 2023년 03월 05일 날짜의 정보를 볼 수 있어야 한다.  

 

  위의 시나리오가 우리가 원하는 시나리오다.

 

 

2. 어떻게 구현할까?

 

최대한 효율적으로. 이미 있는 것들을 활용해서.

 

  이 페이지 루프 기능을 구현할 때 최대의 고민은 어떻게하면 최대한 효율적으로 렌더링할 수 있는가였다. CSR 기반의 프레임워크인 Vue 를 활용해서 SSR 기능을 만들어야 하는 것. 그래서 일단, 페이지 루프 기능을 추가하기 위해서 필요한 것, 혹은 달라질 것들을 미리 나열해봤다.

 

(1) 다른 페이지로 넘어가는 링크는 현재 페이지의 state 에 맞춰 동적으로 바뀌어야 한다.

: 발전소 x, 2023년 03월 05일 등 현재 보고 있는 페이지의 정보를 다른 페이지에서도 맞춰야 하기 때문

 

(2) 한 페이지 내에서도 상태를 바꾼다는 것은, url 을 바꾸는 것과 동일하다.

: 지금 보고 있는 페이지의 url 을 다른 사람의 PC 에서 열었을 때 동일한 상태로 맞춰야 하므로. 상태가 변경됐을 때 url 이 서로 싱크가 맞아야 한다.

 

  여기에서 보면, 두 가지의 이벤트가 항상 함께 따라 다닌다. 첫 번째는 상태 업데이트 이벤트. 두 번째는 routing 이벤트다. 이 두 가지 이벤트를 Vue 라는 프레임워크 환경에서 어떻게하면 잘 녹여낼 수 있을지 고민해봤다. 그러려면 Vue 동작 원리에 대한 지식이 있어야 한다.

 

(2-1) Vue 라는 생태계

  첫 번째, Vue 는 모든 props 를 memoization 한다. React 로 따진다면 React.memo 를 모든 컴포넌트에서 다 하고 있다는 것이다. 그렇기 때문에 자식 컴포넌트와 상관 없는 상태가 부모에서 바뀌었다 하더라도, 자식 컴포넌트는 리렌더링 하지 않는다.

 

  두 번째, Vue 는 라이프 사이클 기반으로 동작한다. React 로 따진다면 클래스형 컴포넌트와 같다. 지금이야 React 는 다 함수형 컴포넌트라서 라이프 사이클 보다는 Trigger, Render, Commit 이라는 세 동작이 기반이지만, React 도 예전에는 라이프 사이클이 있어 해당 메서드를 활용해 로직을 작성했다. Vue 도 마찬가지다. Vue 3 버전에서 Composition API 를 활용하면, mount 가 됐을 때 호출할 로직은  onMounted 에서, 상태 혹은 props 가 변경된 이후 라이프 사이클에서 호출할 로직은 onUpdated 에서 작성하면 된다. 

 

(2-2) 구현 방법

  Vue router 4 버전 이후 버전에서는 컴포넌트에 props 를 넘기는 것이 가능하다. 즉 /pageA 라는 Path 와 PageA.vue 라는 컴포넌트가 매핑됐다면, router 에서 PageA.vue 컴포넌트에 넘겨줄 props 값을 지정할 수 있다는 것이다. 이때, url 쿼리 혹은 파라미터의 정보를 참조할 수 있으므로 그 값을 PageA.vue 의 props 로 넘길 수 있다. 

 

  이렇게 위에서 PageA.vue 의 props 로 paramter 혹은 query의 정보를 넘겨주었다면 onMounted, onUpdated 라이프 사이클에서 props 로 넘겨 받은 값으로 state 를 변경하는 로직을 작성한다. 이 때, 나는 

 

const onUrlUpdated = (...funcs: Array<() => void>) => {
  onMounted(() => funcs.forEach(func => func()))
  onUpdated(() => funcs.forEach(func => func()))
}

 

  이런 식의 코드를 활용해서, onMounted, onUpdated 를 두 번 이상 작성할 필요 없이 만들었다. (지금, 저 코드는 초기에 구상했을 때 만든 코드였고, 이후에 정책이 추가되고 문제점이 발견되면서 지금은 저 코드가 훨씬 복잡해져 있다)

 

  이렇게 구현하면, 이미 우리 환경에서 동작하고 있지만 활용하지 않고 있던 것들을 활용한 것 뿐이며 URL 이 바뀌는 것을 계속 watch 로 감시하지 않아도 되므로 메모리를 낭비하지 않아도 된다. 이 구현 방법이 내가 생각했던 여러 방법들 중 가장 효율적이라 판단했고 적용했다.

 

  

3. 페이지 루프에 대한 만족감과 긍정적인 영향

  정량적으로 평가할 수 있으면 좋으련만... 사실 내가 개발한 모든 페이지에는 이미 적용을 마쳤으나 사수가 작성한 페이지에는 몇 페이지가 적용이 되지 않아 아직까지 실제 클릭 수라든가 만족감 조사 등을 제대로 하기 어렵다. 특히, 내가 개발하는 페이지들은 Admin 페이지, 데이터를 가공하는 페이지가 많아 권한 있는 유저들만 들어올 수 있어 페이지 루프를 활용해서 들어오는 케이스가 매우 드물다.

 

  하지만 일단 페이지 루프가 구현된 페이지를 활용하고 있는 개발팀 내부에서는 굉장히 편리하게 활용하고 있다. 특히 팀장님이 누군가로부터 URL 을 넘겨 받았을 때 바로 상황을 확인할 수 있어서 아주 큰 만족감을 드러내고 계신다. 하루 빨리 모든 페이지에 페이지 루프 기능이 추가돼서 사용자로부터 직접적인 피드백이나 클릭 수를 확인해보고 싶다.

 

  또, 페이지 루프가 만들어낸 긍정적인 영향 중 하나는 페이지를 기획할 때 큰 도움이 됐다. 페이지 루프가 되니, 하나의 페이지에서 보여줄 정보를 확실하게 정하고, 곁들여야 하는 정보들을 나열한 후, 각 정보마다 페이지 루프를 걸어서 넘어가도록 구성할 수 있게 됐다. 도메인 성격상 하나의 데이터에서 많은 인사이트를 얻을 수 있고 다른 데이터와 연관하면 굉장히 많은 정보를 얻어낼 수 있기 때문에 페이지를 기획할 때마다 "이것도 중요하고, 저것도 중요한데" 라는 생각이 들어 뒤죽박죽 섞인 화면을 보여주게 됐다. 심지어 이전까지는 요구사항으로 "이 데이터면 이런 정보도 얻을 수 있는데 이 페이지에 다 보여주세요" 하는 것들도 많았다.(진짜 많았다). 하지만 페이지 루프가 되니, 그런 추가 정보들은 링크를 걸어주게 되어 기획할 때 딱 이 페이지에서 추구하는 바를 명확하고 간소화하게 표현할 수 있게 됐다.