이미지 업로드

OwlSuri·2022년 4월 26일
0
post-custom-banner

기존 이미지 업로드의 문제
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>
    )
}

이미지를 스크롤을 내릴때 미리 다 다운받을것인가

LazyLoad -

아니면 내릴때마다 조금씩 필요한 것 들만 다운받을 것인가 - 라이브러리사용(react-lazyload)
필요한 그림들만 미리 받고 스크롤 내릴때마다 조금씩 받아옴

Preload -

다른 메뉴에 있을때 미리 사진을 다운 받아둠(대기, 페이지전환하면 바로 보여줌, 코드로 구현)

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 에서 페이지 성능 측정가능

profile
기억이 안되면, 기록을 -
post-custom-banner

0개의 댓글