서비스를 이용하다보면 화면이 너무 늦게 로딩되면 화가난다...🔥🔥🔥
대부분의 사용자는 화면이 너무 늦게 로딩되면 이를 기다리지 못하고 떠나가버린다...
이는 수익성 창출로 이루어지기 때문에 열심히 코딩을 해서 개발을 했다하더라도 사용자들이 떠나면... 물거품이 된다는 말이다ㅜ
그러면 도대체 성능은 어떻게 측정하고 해결해야하는지 궁금증이 생길 것이다!
이는 사이트마다 다를 수 있고, 회사마다 성능 측정 방식이 다를 수 있지만 makeup-api를 통해 화장품 목록을 가져오고 이를 구글의 Light house를 이용하여 성능을 해결하고자 한다..!
하지만 해당 글을 읽어보면... 서버와 클라이언트 모두 다 성능에 집중해야한다는 사실을 알게 될 것이다..
총 네트워크 바이트를 최소화하려면 텍스트 기반 리소스를 압축(gzip, deflate, brotli)하여 제공해야 합니다.
useEffect(() => {
axios
.get('http://makeup-api.herokuapp.com/api/v1/products.json', {
headers: {
'Content-Type': 'application/json',
'Accept-Encoding': 'gzip',
},
})
.then((res) => {
setData(res.data.slice(0, 16));
});
}, []);
위와 같이 작성하여 요청 해더에 gzip으로 보내주었더니 결과가 크게 달라지지 않는다는 것을 확인하였다. 텍스트 압축 활성화를 읽어보았더니 이는 서버에서 압축 시에 크게 절감효과가 일어난다는 것이었다!
웹사이트 성능 개선을 위한 gzip 압축 적용 : Apache, Tomcat, Weblogic과 Servlet Filter 해당 블로그에 자세히 나와있지만 난 이해를 하지 못했다...
gzip 압축이 정상적으로 적용었다면 아래와 같이 response를 보내준다고 한다.
하지만 makeup-api는 적용이 되지 않았다는 것을 확인할 수 있었다.
효율적인 캐시 정책으로 정적 자산 제공을 통해 Cache-Control 값으로 max-age값이 적으면 적을 수록 좋다고 이야기하는 것 같았다. 그래서 해당 url을 전체 product인 json형태가 아닌 page api가 있다면 그 형식으로 변경해주려고 했지만 해당 api가 category와 type으로 분류를 해서 그걸로 변경해주었더니 성능이 빠르게 올라간 것을 확인할 수 있었다.
하지만 웹 서비스 캐시 똑똑하게 다루기 글을 통해 HTTP 캐시를 효율적으로 관리하려면 Cache-Control 헤더를 섬세하게 조절해야한다고 한다. 웹 브라우저가 서버에서 지금까지 요청한 적이 없는 리소스(HTML, CSS, JS, 이미지, 비디오 등)을 요청할 때, 서버와 브라우저는 완전한 HTTP 요청/응답을 주고 받는다고 한다. 하지만 요청 받은 이후 HTTP응답은 헤더 Cache-Control 헤더에 따라 받은 리소스의 생명주기가 결정이 된다고 한다. 즉, 두 번째 요청을 할 때 캐시가 유효한지 재검증을 수행한다는 것이다.
그래서 응답시에 Cache-Control 값으로 max-age=0, s-maxage=31536000
을 설정하면 이로써 브라우저는 HTML 파일을 가져올 때마다 서버에 재검증 요청을 보내고, 그 사이에 배포가 있었다면 새로운 HTML 파일을 내려받는다고 한다.
makeup-api
에선 어떻게 적용할 수 있을까? 위에서는 리소스가 가지는 Cache-Control 헤더 값이 max-age=31536000
이었기에 아마도 makeup-api에선 max-age가 1728000
이기에 max-age=0, s-maxage=1728000
로 설정하면 되지 않을까 싶다!
그렇다면 지금 현재 내가 성능을 높일 수 있는 건 무엇이 있을까?
async
await
로 기존 전체 product api를 비동기 처리하니 무려 6
이나 느는 것을 확인할 수 있었다!
useEffect(() => {
const getData = async () => {
try {
await axios.get('http://makeup-api.herokuapp.com/api/v1/products.json').then((res) => {
setData(res.data.slice(0, 16));
});
} catch (err) {
console.log(err);
}
};
getData();
}, []);
하지만 product_category는 conceal이고, product_type이 foundation인 json을 불러왔더니 무려 10
이나 느는 것을 확인할 수 있었다!
useEffect(() => {
const getData = async () => {
try {
await axios
.get(
'http://makeup-api.herokuapp.com/api/v1/products.json?product_category=concealer&product_type=foundation'
)
.then((res) => {
setData(res.data.slice(0, 16));
});
} catch (err) {
console.log(err);
}
};
getData();
}, []);
스켈레톤 적용 전
스켈레톤 적용 후
첫번째는 스켈레톤을 적용하지 않은 결과이고, 두번째는 스켈레톤을 적용한 결과이다. 스켈레톤을 적용하지 않은 결과에서 왜 다시 테스트 해보니깐 성능이 73
으로 줄어들었는지는 모르겠다.. 우선 기존과 성능을 비교했을 때 81로 같았지만 사용자 관점에서 보았을 때 빈 화면이었을 때 보다 스켈레톤을 적용함으로써, 데이터가 불러오는 효과가 있었다. 뿐만 아니라 수치 상으로도 Total Blocking Time이 줄어들었다.
Light house
를 통해 성능 측정 결과 같은 조건에서도 테스트를 돌릴 때마다 수치가 변경되는 것을 확인하여서 좋은 테스트는 아니다라는 것을 깨닫게 되었다. 좀 더 성능에 대해 공부를 해야겠다...
혹시라도 제가 잘못작성한 부분이 있다면 댓글로 달아주시면 감사하겠습니당~
출처)
https://watermelonlike.tistory.com/entry/LightHouse\
https://toss.tech/article/smart-web-service-cache