지난번에 힘겹게 이미지 업로드 하는 방법을 배웠는데 여러장을 올리면서 최적화도 가능하다니
쉬울 줄 알았는데 역시나 너무 어려웠다. 까다로운 이미지 올리기 ㅠㅠ
이미지 많이 쓰는 쇼핑몰 같은 곳은 정말 대단한거였어... 열심히 해보자...
기존방식대로 이미지를 올릴 때는 몇가지 비효율적인 면이 존재한다.
따라서 이미지 선택 후 백엔드로 보내주지 않고 브라우저에서 접속가능한 url로 바로 변경(미리보기 성능개선)하고 등록하기를 누르면 그때 백엔드로 보내주면 효율적이다.
이미지와 같은 file에 관련된 기능들을 모아 놓은 것을 FileReader
라고 하며, 파일을 읽어서 바로 url로 바꿔주는 기능은 readAsDataURL
이다.
const fileReader = new FileReader();
fileReader.readAsDataURL(file)
이미지 미리보기 기능은 FileReader 대신 내 컴퓨터에서만 볼 수 있는 임시미리보기 주소로 URL.createObjectURL(file)
도 사용가능하다.
하지만 URL.createObjectURL(file)과 FileReader는 백엔드로 전송이 불가하고
URL.createObjectURL(file)는 가짜주소이며, FileReader는 용량이 너무커서
백엔드에 보낼 때는 무조건 스토리지에서 받은 url로 보내야함을 잊지 말자!
promise는 시간이 걸리는 작업을 할 때 사용하는데 이미지를 여러개 올리고 싶을 때는 이미지가 하나하나씩 올라가는 것을 다기다려야 하는 불편함이 있다.
따라서 여러개를 한번에 올리는 Promise.all
을 사용하면 된다.
const onClickPromiseAll = async () => {
console.time("시작!!");
const result = await Promise.all([ //배열로 만들기
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("https://dog1.jpg");
}, 3000);
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("https://dog2.jpg");
}, 2000);
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("https://dog3.jpg");
}, 1000);
}),
])
console.timeEnd("시작!!");
console.log(result); //배열로 나옴
}
그냥 promise를 사용하게 되면 각각 await를 작성하고 각각 변수에 담아서 확인하는 불편함이 있고 시간이 많이 걸리지만
Promise.all을 사용할 경우 Promise.all에만 await를 붙여주면서 Promise.all안에 있는 배열이 동시에 요청된다.
따라서 위의 예시에서는 3개를 요청했지만 최대시간인 3초밖에 걸리지 않게 된다!
lazyload
는 전체 화면의 이미지를 미리 다 다운받지 않고 스크롤하는거에 맞춰서 스크롤을 때릴때마다 보여지는 이미지를 다운받는 것을 말한다.
먼저 보여줄 부분 보여줌으로써 성능높일 수 있으며 npm에서 react-lazyload 라이브러리를 사용하면 편하다.
import React from 'react';
import ReactDOM from 'react-dom';
import LazyLoad from 'react-lazyload';
import MyComponent from './MyComponent';
const App = () => {
return (
<div className="list">
<LazyLoad height={200}>
<img src="tiger.jpg" /> /*
Lazy loading images is supported out of box,
no extra config needed, set `height` for better
experience
*/
</LazyLoad>
<LazyLoad height={200} once >
/* Once this component is loaded, LazyLoad will
not care about it anymore, set this to `true`
if you're concerned about improving performance */
<MyComponent />
</LazyLoad>
<LazyLoad height={200} offset={100}>
/* This component will be loaded when it's top
edge is 100px from viewport. It's useful to
make user ignorant about lazy load effect. */
<MyComponent />
</LazyLoad>
<LazyLoad>
<MyComponent />
</LazyLoad>
</div>
);
};
preLoad
는 용량이 큰 이미지가 로드될 때 이미지가 끊겨서 조금씩 로드되는 현상을 방지하기 위해 미리 이미지를 다운로드를 받아놨다가 페이지에 들어갔을 때 보여주어 사용자의 경험을 좋게하고 이탈율을 방지하는 효과를 준다.
페이지가 실행되면 바로 이미지를 다운받을 수 있도록 useEffect 사용하면 된다.