페이지를 읽어주는 시점에 중요하지 않은 리소스 로딩을 추후에 하는 기술로,
스크롤을 내리면서 보여질 필요가 있는 부분만 추가적으로 받아오는 식으로 불필요한 서버와의 통신을 줄일 수 있다.(데이터낭비x)
페이지를 읽어줄 때 미리 리소스를 받아놓는 기술
LazyLoad의 경우에는 필요할 때마다 데이터를 로드하는 방법이라면, PreLoad의 경우에는 모든 데이터들을 미리 로드해놓고 대기하는 방식이다.
[실습 section31-09]
- index.tsx
import { useRouter } from "next/router"; import { useEffect } from "react"; // 프리로드된 이미지를 넣어둘 배열 const saveImgBox = []; export default function ImagePreloadPage(): JSX.Element { const router = useRouter(); // let saveImg; //초기화되므로 좋지 않은 방법 useEffect(() => { const img = new Image(); // img.src = "용량큰배너이미지.jpg"; img.src = "https://upload.wikimedia.org/wikipedia/commons/9/96/%22Den_kjekke_gutt%22_-_6._Internasjonale_Akademiske_Vinterleker_%281939%29_%2840200856483%29.jpg"; // img 태그가 onload 되었을 때 img.onload = () => { // 프리로드 된 이미지들을 saveImgBox 배열에 넣어준다. saveImgBox.push(img); }; }); const onClickMove = (): void => { void router.push("/section31/31-09-image-preload-moved"); }; return <button onClick={onClickMove}>페이지이동하기</button>; }
- preload-moved.tsx
export default function ImagePreloadMovedPage(): JSX.Element { // return <img src="용량큰배너이미지.jpg" />; return ( <img src="https://upload.wikimedia.org/wikipedia/commons/9/96/%22Den_kjekke_gutt%22_-_6._Internasjonale_Akademiske_Vinterleker_%281939%29_%2840200856483%29.jpg" /> ); }
- index.tsx
import { useQuery, gql, useApolloClient } from "@apollo/client"; import { useRouter } from "next/router"; import type { IQuery, IQueryFetchBoardsArgs, } from "../../../src/commons/types/generated/types"; const FETCH_BOARDS = gql` query fetchBoards($page: Int) { fetchBoards(page: $page) { _id writer title contents } } `; const FETCH_BOARD = gql` query fetchBoard($boardId: ID!) { fetchBoard(boardId: $boardId) { _id writer title contents } } `; export default function StaticRoutingPage(): JSX.Element { const router = useRouter(); const { data } = useQuery<Pick<IQuery, "fetchBoards">, IQueryFetchBoardsArgs>( FETCH_BOARDS ); // console.log(data); const client = useApolloClient(); const onClickMove = (boardId: string) => (): void => { void router.push(`/section31/31-10-data-prefetch-moved/${boardId}`); }; const onPrefetchBoard = (boardId: string) => async () => { await client.query({ query: FETCH_BOARD, //다운로드 전 캐시에 들렸다가 옴. variables: { boardId }, //어떤 아이디 조회할 건지 }); }; return ( <div> {data?.fetchBoards.map((el) => ( <div key={el._id}> <span style={{ margin: "10px" }} onMouseOver={onPrefetchBoard(el._id)} onClick={onClickMove(el._id)} {el.title} </span> <span style={{ margin: "10px" }}>{el.writer}</span> </div> ))} </div> ); }
- prefetch-moved/[dynamicrouting]
import { useQuery, gql } from "@apollo/client"; import { useRouter } from "next/router"; const FETCH_BOARD = gql` query fetchBoard($boardId: ID!) { fetchBoard(boardId: $boardId) { _id writer title contents } } `; export default function StaticRoutingPage(): JSX.Element { const router = useRouter(); console.log(router); const { data } = useQuery(FETCH_BOARD, { variables: { boardId: router.query.dynamicrouting }, }); console.log(data); return ( <div> <div>2번 게시글 이동이 완료되었습니다.</div> <div>작성자: {data?.fetchBoard?.writer}</div> <div>제목: {data?.fetchBoard?.title}</div> </div> ); }
- Google PageSpeed Insights
: 실제 배포를 진행하고 나서, 내가 배포한 페이지의 개선할 점을 찾을때 유용한 사이트
- Webp 확장자
구글에서 만든 이미지 포맷(웹피)
이미지 서버의 부담을 줄이고, 서버비를 아낄 수 있는 방안으로 Webp라는 확장자를 만들었다.Webp의 장점
Webp는 GIF, PNG, JPEG 확장자 모두를 대체 가능한 확장자이며 이미지를 파일을 압축했을 때 기존 PNG, JPEG보다 약 30%정도 용량을 줄일 수 있있다.
같은 이미지를 webp으로 받을시 webp은 300kb라면 png는 500kb정도다.
그리고 GIF는 256색만 표현할 수 있지만, Webp은 파일 크기도 작고,
색상 수에 제한이 없으므로 GIF보다 훨씬 좋은 성능을 보인다.
또한, PNG 처럼 알파 채널(투명한 배경)을 지원한다.▼ Webp 확장자 변환하기
https://cloudconvert.com/
- react-dropzone : 파일 드래그해서 첨부하기
https://www.npmjs.com/package/react-dropzone- react-avatar-editor : 사진 사이즈, 사진 모양 편집
https://www.npmjs.com/package/react-avatar-editor- react-beauriful-dnd : 카드 드래그앤 드롭
https://www.npmjs.com/package/react-beautiful-dnd
- wappalyzer : 홈페이지 만드는데 사용된 기술 확인 가능
https://chrome.google.com/webstore/detail/wappalyzer-technology-pro/gppongmhjkpfnbhagpmjfkannfbllamg- codenary : 사이트별 기술 스택 확인
https://www.codenary.co.kr/