https://facebook.com/groups/graphql-kr logo
#클럽-프론트엔드
Title
# 클럽-프론트엔드
h

Hyeseong Kim

02/17/2021, 9:08 AM
Copy code
useQuery(gql`...1페이지 쿼리...`)

const [load] = useLazyQuery(gql`...나머지 쿼리...`)

useEffect(() => {
  // condition
  load();
}, [...]);
u

undefined

02/18/2021, 1:41 AM
이거 시도해봤는데여, 이렇게 해도 요청이 완료되면 re-render 가 발생해서 백그라운드에서 도는 효과를 내지는 못하네요…
일단 쿼리는 다음과 같이 나뉘어있습니다. 1. A~Z 이름을 가져오는 쿼리 2. A~Z 매개변수를 바탕으로 각 데이터를 가져오는 쿼리 제가 시도한 방식은, 1. A~Z 이름을 모두 가져오고 A의 아이디를 매개변수로 넘겨 데이터를 가져와서 보여준다. 2. 1이 완료되자마자 B~Z 아이디를 매개변수로 넘겨 데이터를 가져오는 쿼리를 실행한다. 여기서 이제 2가 완전한 백그라운드로 돌아야 하는데 렌더링이 발생합니다.
아폴로 클라이언트를 직접 쓰면 해결될 것 같기도 하네여 시도해보고 오겠습니다
h

Hyeseong Kim

02/18/2021, 2:06 AM
일단... "백그라운드"는 어떤걸 의미하고 "렌더링은 왜 피해야" 하나요...?
u

undefined

02/18/2021, 2:27 AM
1. 백그라운드란 렌더링에 영향을 주지 않으면서 서버 요청이 진행되는 상황을 말합니다. 2. 렌더링을 피해야 하는 이유는 UX 에 방해가 되기 때문입니다.
뭐 어떻게 해결하긴 했는데여, best practice 인지는 모르겠네여 ㅋㅋㅋ 비동기로 불러온다음 ref 에 저장해두고 B~Z 선택할 때마다 state 업데이트 하는 방식 썼습니다
h

Hyeseong Kim

02/18/2021, 5:11 AM
리렌더링이 정말 UX를 해치는지는 여러번 생각해봐야 합니다. 말씀하신 케이스는 "렌더링만 나중으로 미룸" 인데 그렇게 했을 때 얻는 것이 있나요
그리고 일반적으로 Background task 라고 불리는 것들과 정의가 좀 달라서 질문을 잘 이해하기 어려웠어요
u

undefined

02/18/2021, 5:15 AM
기존: A~Z 를 전부 요청한다음 렌더링 이후: A만 렌더링 한다음 백그라운드에서 B~Z 요청 이렇게 해서 초기로딩 속도 개선을 위함이었습니다!
h

Hyeseong Kim

02/18/2021, 5:17 AM
네 원래 하고자 하셨던게 쿼리패스를 분할하고 불필요한 부분을 defer 하는 처리로 이해해서요
그럼 background 에서 실행이 아니라 그냥 실행을 미루는것이고
이후 로딩된 것을 "미리" 렌더링 하는 것이 초기 렌더링을 느리게 하는 요인이 아닐거같고요
애초에 다 비동기 작업이므로..
뭐 우선순위 문제가 있다면 실행을 requestIdleCallback 같은데 위임하는거 정도는 있겠지만
u

undefined

02/18/2021, 5:18 AM
로딩된 것을 “미리” 렌더링한다기 보다 요청이 완료되지 않았을 경우 “로딩 바” 를 계속해서 렌더링하기 때문에 사용자 입장에선 느리게 판단하는 거인것 같네여
즉, “로딩 바” 를 렌더링하는 시간을 줄이는 게 목표였습니당
제가 설명을 잘 못했네여
h

Hyeseong Kim

02/18/2021, 5:19 AM
로딩바 따로 돌게 하면 되잖아용
u

undefined

02/18/2021, 5:19 AM
따로 어떻게여?
h

Hyeseong Kim

02/18/2021, 5:19 AM
UI 레벨 블로킹이 모든 요청 단위로 일어날 필요는 이제 지우셨으니까
로딩바를 애초에 보여줄 필요가 없죠
u

undefined

02/18/2021, 5:20 AM
첫 요청이 완료되지 않았을 때 로딩 바를 보여줘야 합니당
h

Hyeseong Kim

02/18/2021, 5:20 AM
네네
근데 defer 된 요청에 대해서는 말이죠
그니까 그거 때문에 ref 를 쓰는게 이상하다는 지적인데요
(ref를 그런 용도로 쓰는건 정말 이상하게 느껴져요)
ref 없이도 할 수 있는 일이고 (일반 state 로)
u

undefined

02/18/2021, 5:22 AM
넴 defer 된 요청은 2가지로 구분되는데, 1. 사용자가 버튼을 클릭했을 때 데이터가 없으면 로딩 바를 보여줍니다. 2. 사용자가 버튼을 클릭했을 때 데이터가 있으면 데이터를 보여줍니다. ref 의 용도는 DOM 컨트롤 또는 렌더를 일으키지 않는 변수에 사용해서 썼구여
일반 state 로 하게 되면 렌더링이 발생하게 되지 않나요?
h

Hyeseong Kim

02/18/2021, 5:22 AM
네 그럼 그냥 state 쓰면 되고 리액트 리렌더는 신경쓸게 아닌거 같습니다
리렌더가 실제로 일어나야 하기 때문에 일어나는거고
ref 로 그걸 막을 수 있다는건 오해입니다
일단 그렇게 쓰는게 concurrent safe 하지 않을뿐더러... 이해하기도 어려운 코드를 만들어서
u

undefined

02/18/2021, 5:23 AM
오해라기 보단 의도인데요, ref 가 실제로 렌더를 일으키진 않지 않나요?
h

Hyeseong Kim

02/18/2021, 5:24 AM
위에 정리해서 적어주신게 상태에 따른 UI 변경을 얘기하신거잖아요
u

undefined

02/18/2021, 5:24 AM
즉, 렌더링을 인터랙션 발생했을 때로 늦추기 위함이에요, 서버에서 요청 완료되도 렌더링 안되게 말이죠
h

Hyeseong Kim

02/18/2021, 5:24 AM
ref를 쓰던 아니던 동작의 차이가 없죠
indirection 만 더 했을 뿐
네네 의도는 이해했고요
그걸 ref 를 사용하셨다기에
u

undefined

02/18/2021, 5:25 AM
🤔 근데 state 를 쓰면 인터랙션이 발생하지 않아도 렌더링이 발생하는데요?
h

Hyeseong Kim

02/18/2021, 5:25 AM
그 렌더링이
상태 변경에 따라서 리액트 컴포넌트 렌더링 하는 부분의 코드가 다시 호출되는데요 를 의미하는 거라면 그건 자연스러운 현상이므로 막을 필요가 없고요
그걸 막는걸 React에선 권장하지 않습니다
u

undefined

02/18/2021, 5:26 AM
음 state 로 되나 확인해보고 올게영
state 로 해도 되는군요 왜이리 잘못 알고 있는게 많은건지… 감사합니다!