서비스 핵심인 포트폴리오 게시판 조회 속도가 7초가 걸렸습니다.
두가지 문제를 발견했습니다.
문제를 해결하기 전 왜 이런 코드가 작성됐나 분석했습니다.
다형성을 이용해 코드 스타일을 통일했기 때문에 이런 코드가 나왔었습니다.
회사 코드이기 때문에 간단한 샘플 코드로 설명하겠습니다.
class SampleService {
public Outer.SampleDto getSamples(){
SampleEntity sample = sampleReponsitory.findById(1);
Outer.SampleDto sampleDto = SampleDto.of(sample);
return sampleDto;
}
}
class Outer {
@Builder
static class SampleDto{
String thumbnailImage;
static SampleDto of (SampleEntity sampleEntity){
return SampleDto.builder()
.thumbnailImage(sampleEntity.getImages().get(0))
.build();
}
}
}
@Entity
public class SampleEntity {
@OneToMany(mappedBy = "sampleEntity")
private List<ImageEntity> images;
}
JPA를 통해 Entity를 가져옵니다. 그리고 스태팃 메서드인 of에 인자로 넘겨줍니다. 이런 패턴을 활용한 이유는 모든 영역에서 Dto를 간단하게 생성할 수 있기 때문입니다.
첫 번째 방법
Service에서 가장 첫번째 이미지만 가져온 후 of 메서드 매개변수에 String thumbnailImage를 추가하는 방법을 고려했었습니다.
class SampleService {
public Outer.SampleDto getSamples(){
SampleEntity sample = sampleReponsitory.findById(1);
ImageEntity image = imageRepository.findFirstBySampldId(1);
Outer.SampleDto sampleDto = SampleDto.of(sample, image.getUrl());
return sampleDto;
}
}
이런 식으로 말입니다.
하지만 이렇게 하면 전체적인 코드와 통일되지 않았습니다.
두 번째 방법
그래서 ThumbnailImage 테이블을 따로 만든 후 Sample 테이블과 Image 테이블 교차 테이블로 만들었습니다.
class Outer {
@Builder
static class SampleDto{
String thumbnailImage;
static SampleDto of (SampleEntity sampleEntity){
return SampleDto.builder()
.thumbnailImage(sampleEntity.getThumbnailImage())
.build();
}
}
}
이렇게 기존과 같은 스타일로 모든 이미지를 가져오는 문제를 해결할 수 있었습니다.
전체적으로 고용량 이미지 파일이 많았습니다. 그 이유는 썸네일 파일 용량이 매우 컸기 때문입니다. 서비스 특성상 고화질 이미지가 많았습니다. 하지만 썸네일은 작게 보여지기 때문에 그럴 필요가 없었습니다. Marvin 라이브러리를 통해 썸네일 이미지를 2mb이하로 줄였습니다.