화면 성능 개선 전 학습 테스트

HTTP Cache, gzip,Servlet,Thread에 대한 학습 테스트를 진행 합니다.

학습 테스트

HTTP Cache


Cache-Control 관리하기

  • HTTP 응답 헤더에 Cache-Control 이 없으면 웹 브라우저가 휴리스틱 캐싱에 따른 암시적 캐싱을 한다.

  • 의도하지 않은 캐싱을 막기 위해 모든 응답의 헤더에 Cache-Control: no-cache를 명시한다.

  • 또한, 쿠키나 사용자 개인 정보 유출을 막기 위해 private도 추가한다.

휴리스틱 캐싱에 대해 자세히 알아보려면 해당 블로그에 분석 사례 확인하기

@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
    public static final String PREFIX_STATIC_RESOURCES = "/resources";


    private final ResourceVersion version;

    @Autowired
    public WebMvcConfig(ResourceVersion version) {
        this.version = version;
    }

    @Override
    public void addInterceptors(final InterceptorRegistry registry) {
        WebContentInterceptor interceptor = new WebContentInterceptor();
        interceptor.addCacheMapping(CacheControl.noCache().cachePrivate(), "/");
        registry.addInterceptor(interceptor);
    }

모든 응답에 대해 처리 해야 했기 때문에 특정 컨트롤러에서 헤더에 정보를 추가하지 않고 설정 파일에서 캐시 값을 적용하도록 수정하였다.

HTTP 압축 알고리즘 적용 with gzip

  • 스프링 부트 설정을 통해 gzip과 같은 HTTP 압축 알고리즘을 적용 시킬 수 있다.

  • 스프링에서 데이터를 압축할 때 기본 2KB부터 적용 되기 때문에 작은 크기의 파일은 압축하지 않는다. 작은 크기의 파일도 압축할 수 있도록 기본 설정을 10으로 변경한다.

스프링부트 설정 파일에 해당 설정 값을 작성하게 되면 아래와 같이 헤더 정보에 Transfer-Encoding이 chunked로 표시되는 것을 확인할 수 있다.

E-Tag 와 If-None-Match 를 활용한 HTTP 조건부 요청 캐싱

  • 필터를 활용하여 "/etag" 경로도 ETag를 적용해보자

etag로 접근하는 요청에 E-Tag 값을 넣어 ETag가 무엇인지 테스트를 통해 확인한다.

캐시 무효화

컨텐츠가 변경될 때 URL을 변경하여 응답을 장기간 캐시하게 만드는 기술이다.

정적 리소스를 max-age: 1년으로 설정한 후 JS나 CSS 리소스에 변경사항이 생기면 캐시가 제거되도록 할 때 사용하는 방식이다.

정적 파일을 서빙할 때 캐싱이 적용 되어 있는 "resources/{version}/js/index.js" 에 캐싱이 적용되어 있고 max-age는 1년이라고 가정 해보자.

만약, 1년이 지나지 않은 시점에서 변경사항이 일어나서 배포해야 한다면 어떻게 할 것인가?

버저닝을 날짜로 사용한다면 배포 시점이 달라질 때 마다 캐시가 무효화 되고 새롭게 E-Tag를 저장하여 다시 캐싱을 적용할 수 있다.

리소스 요청 예시: /resources/20250128000572/js/index.js

Servlet


스레드 공유 영역인 서블릿의 인스턴스 변수 범위 확인하기

  • 인스턴스 변수를 사용하는 서블릿에서 한 번의 요청을 보낼 때 마다 카운트를 증가 시키면 몇이 나올까?

4번 호출 한 서블릿의 카운터 변수는 결과적으로 "4"일 것이다. 그 이유는 쓰레드 간 해당 자원을 공유하고 있기 때문이다

서블릿의 로컬 영역에서 카운터 증가 확인하기

  • 로컬 변수를 사용하는 서블릿에서 한 번의 요청을 보낼 때 마다 카운트를 증가 시키면 몇이 나올까?

당연히 로컬 변수는 공유하지 않기 때문에 몇 번을 호출하더라도 1이 나올것이다.

서블릿의 필터를 활용하여 인코딩 값 검증하기

  • 서블릿이 생성 되고 HTTP로 넘어온 데이터를 파싱하고 서비스 로직을 호출하고 프로세스를 종료하는 과정들을 살펴 보며 인코딩 된 값을 어떻게 처리하는지 확인한다.

왜 인코딩을 따로 설정해야 하며, 어떻게 해야 하는지 알아볼 수 있는 코드이다. 해당 공식 문서를 읽어 보면 인코딩 방법을 명시 하지 않으면 기본적으로 ISO-8859를 사용한다고 한다.

그렇다면 특정 문자에 대해서는 디코딩이 이루어지지 않아 외계어를 볼 수 있기 때문에 세계 공용인 UTF-8로 인코딩 하여 반환 값을 검증했다.

Thread


톰캣에서 스레드 값 설정

Thread 동기화 및 Thread-Safe

  1. 동기화 되지 않아 예상 개수보다 적게 생성 되는 경쟁 상태를 동기화로 풀어주기

  2. syncronized 예약어를 사용하지 않고 Thread-Safe한 코드 생성하기

Thread Pool에 따른 Queue 적재 방식

  1. newFixedThreadPool 이 Queue에 저장하는 쓰레드 개수 검증하기

  2. newCachedThreadPool 이 Queue에 저장하는 쓰레드 개수 검증하기

Last updated