Quill 에디터(편집 에디터)는 이미지를 첨부하면 base64 인코딩 형식으로 변환되어 저장됩니다.
하지만 base64 방식은 이미지 데이터를 긴 문자열 형태로 HTML에 포함시키기 때문에, 다음과 같은 문제가 발생합니다.
이를 해결하기 위해, base64 방식 대신 S3에 이미지를 업로드하고 해당 URL을 에디터에 삽입하는 방식을 선택하여 구현하였습니다.
항목 | base64 인코딩 | S3 업로드 |
---|---|---|
이미지 전달 방식 | 이미지 → base64 문자열로 변환 후 포함 | 이미지 → 서버에 업로드 후 URL 전달 |
전송 데이터 크기 | 약 1.3~1.4배 커짐 | 원본 그대로 전송 |
렌더링 성능 | <img src="data:image/png;base64,..."> → 해석 시간 더 걸림 | <img src="https://s3..."> → 브라우저 캐싱 가능 |
HTML/JS 코드 길이 | base64 문자열이 코드 내에 길게 삽입됨 | URL만 포함 |
사용자 경험(UX) | 초기 렌더 느릴 수 있음 | 빠르고 깔끔 |
이미지를 base64 대신 S3에 업로드하고, 응답받은 URL을 에디터에 삽입하는 흐름은 다음과 같습니다.
<img>
태그를 삽입합니다.Quill 에디터에서 이미지 버튼을 클릭했을 때의 동작을 직접 커스텀하려면, handlers
옵션을 설정해주어야 합니다.
const quill = new Quill(editorRef.current, {
...,
modules: {
toolbar: {
container: [...], // 생략
handlers: {
image: () => {
imageHandler(quill);
},
},
},
},
});
위와 같이 Quill 인스턴스를 생성할 때 handlers.image
에 사용자 정의 함수(imageHandler)를 지정하면, 기본 동작 대신 원하는 방식으로 이미지를 처리할 수 있습니다.
const imageHandler = useCallback((editor: any) => {
// 파일 입력창 생성
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.setAttribute('name', 'file');
input.setAttribute('multiple', '');
input.click();
// 파일 선택 후 이벤트 처리
input.onchange = async (event: any) => {
const target = event.target as HTMLInputElement;
const files = target.files;
if (!files || files.length === 0) return;
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append('images', files[i]);
}
// S3 업로드 요청
const response = await uploadImageToS3(token, formData); // 다중 파일
// Quill 에디터에 <img> 태그 추가
response?.imageUploadDto.forEach((img) => {
const range = editor.getSelection();
editor.insertEmbed(range.index, 'image', img.imageUrl);
editor.setSelection(range.index + 1);
});
};
}, []);
위 코드에서 imageHandler
함수는 Quill 에디터의 이미지 버튼을 클릭했을 때 실행되는 커스텀 핸들러입니다.
먼저 input
태그를 동적으로 생성해, 사용자가 로컬에서 이미지를 선택할 수 있도록 합니다.
이미지 선택이 완료되면 input.onchange
이벤트가 트리거되고, 선택된 파일들을 FormData
에 담아 서버(S3)에 업로드합니다.
업로드가 완료되면 서버로부터 이미지의 URL이 포함된 응답을 받습니다.
그 후 Quill 에디터의 현재 커서 위치를 가져와, 해당 위치에 <img>
태그를 삽입하고, 커서를 이미지 뒤로 이동시킵니다.
위와 같이 커스텀 이미지 핸들러를 적용하면, Quill 에디터에 이미지를 삽입할 때 base64가 아닌 실제 URL로 삽입되는 것을 확인할 수 있습니다.
이 방식은 렌더링 성능 향상, 콘텐츠 크기 최적화, 이미지 관리 용이성 등의 장점이 있습니다.