기존 이미지 업로드의 문제
1. 미리보기 시간이 걸림 - 업로드->백엔드->스토리지 갔다가 돌아와야하므로
2. 이미지 찌꺼기들이 쌓임 - 이미지를 업로드하고 등록하지 않은 경우
해결
미리보기는 자바스크립트로 브라우저에서 임시 URL만들기 -> 최종등록 안해도 스토리지에 찌꺼기 없음
최종 게시글 등록할때 -> upload 파일 선행
이 것을 하나의 함수로 묶는다.
export default function ImageUploadPreview(){
const [file1, setFile1] = useState<File>()
const [imageUrl, setImageUrl] = useState("")
const [createBoard] = useMutation(CREAT_BOARD);
const [uploadFile] = useMutation<Pick<IMutation, "uploadFile">, IMutationUploadFileArgs>(UPLOAD_FILE)
const onChangeFile = (event:ChangeEvent<HTMLInputElement>) =>{
const file = event.target.files?.[0]
if(!file) {
alert("파일이 없습니다!")
return
}
const fileReader = new FileReader()
fileReader.readAsDataURL(file) // blob 파일을 임시 url 형태로 만들어줌 - 미리보기용
// 파일 다 읽으면 아래 함수 실행
fileReader.onload = (data) => {
if(typeof data.target?.result === "string"){
console.log(data.target?.result) // 파일을 문자열 형태로 읽은 결과
setImageUrl(data.target?.result)
setFile1(file)
}
}
}
const onClickSumbit = async() =>{
// 여기서 uploadFile과 createBoard 묶어서 함
const result1 = await uploadFile({
variables:{file : file1}
})
const imageUrl= result1.data.uploadFile.url
const result2 = await createBoard({
variables: { createBoardInput:{
writer:"수리",
password:"1234",
title:"화요일",
contents:"이미지 업로드할래",
images:[imageUrl]
} },
});
console.log(result2.data.createBoard._id)
}
return(
<div>
<input type="file" onChange={onChangeFile}/>
<img src={imageUrl}/>
<button onClick={onClickSumbit}>게시글 등록하기</button>
</div>
)
}
이미지를 스크롤을 내릴때 미리 다 다운받을것인가
아니면 내릴때마다 조금씩 필요한 것 들만 다운받을 것인가 - 라이브러리사용(react-lazyload)
필요한 그림들만 미리 받고 스크롤 내릴때마다 조금씩 받아옴
다른 메뉴에 있을때 미리 사진을 다운 받아둠(대기, 페이지전환하면 바로 보여줌, 코드로 구현)
import { useEffect, useRef, useState } from "react"
export default function ImagePreloadPage(){
const [imgTag, setImgTag] = useState<HTMLImageElement>()
const [isLoaded, setIsLoaded] = useState(false)
const divRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const img = new Image()
img.src = "https://pixabay.com/get/g38c8d00a4dcd6230c798d612f69eb660cf5f3d4ea97aa84137d9a0446293c973e533fd1dad078670288462eb268fb802.jpg"
img.onload = () =>{
setImgTag(img)
}
})
const onClickPreload = () => {
if(imgTag) divRef.current?.appendChild(imgTag)
}
const onClickLoad = () => {
setIsLoaded(true)
}
return(
<div>
<div ref={divRef}></div>
<button onClick={onClickPreload}>이미지 프리로드</button>
==================================================
{isLoaded && <img src="https://pixabay.com/get/g38c8d00a4dcd6230c798d612f69eb660cf5f3d4ea97aa84137d9a0446293c973e533fd1dad078670288462eb268fb802.jpg" />}
<button onClick={onClickLoad}>이미지 일반로드</button>
</div>
)
}
일반로드는 시간이 걸리지만 프리로드는 이미 다운 받아져있으므로 바로 뜬다.
google page speed insight 에서 페이지 성능 측정가능