1. lighthouse 점수를 위한 공부
lighthouse는 프론트엔드 배포를 했을 때, 얼마나 최적화가 잘 되어있는지 점수로 나타내는 지표이다. 여러가지 요소가 있지만 일단 SSR을 SSG로 바꾸는 것을 공부했다.
이렇게 react기반에서 데이터패칭을 한다고 생각하면 useState와 useEffect를 함께 사용해서 하는 것이 일반적이다. useEffect를 사용해서 패칭한 데이터를 state에 담아서 뿌려주는 방식이다. 사진에서는 더미데이터를 사용했다.
하지만 실제로 http 요청을 하는 상황에서는 이야기가 달라진다. useEffect는 컴포넌트 함수가 실행되고 난 이후에 실행된다. 처음 이 홈페이지 컴포넌트가 렌더링될 때 loadedMeetups는 비어있는 배열이다. 그 다음에 useEffect 함수가 실행되어 상태를 업데이트하고 다시 컴포넌트 함수가 실행된다. 그런 과정을 거치면 실제 데이터를 가지고 리렌더링된다.
두번의 렌더링을 거치는 싸이클인 것이다. 첫번째 싸이클에서 이 컴포넌트가 처음으로 렌더링되고 loadMeetups는 초기상태(비어있는 배열)이다. 이 순간에는 사용자가 잠깐 로딩화면을 보게 될 것이다. 특히 실제로 데이터 패칭이 일어나지 않는 페이지라면 이 과정이 불필요하다. HTML 페이지를 확인해보면 loadedMeetups로 전달한 내용이 비어있는 것을 확인할 수 있는데, 두번째 싸이클에서 비로소 렌더링되기 때문이다. 즉 이 방식은 SEO에 영향을 미치기에 렌더링방식을 수정할 필요가 있다.
이것은 Nextjs의 pre-rendering 방식 때문인데, pre-rendering은 사용자에게 더 빨리 보여주는 것이 목표이에 두번째 싸이클을 기다리지 않는 것이다. 언제나 패칭된 데이터가 반영되지 않은 첫번째 싸이클의 렌더링을 마친 이후의 스냅샷을 가진, 즉 pre-rendering한 html 코드를 반환한다. 이 문제를 해결할 수 있는 렌더링 방식이 SSG이다.
SSG와 SSR의 차이
ssg가 렌더링되는 시점은 애플리케이션을 빌드하거나, Nextjs프로젝트를 빌드하는 시점이다. 기본적으로 요청이 서버에 도달했을 때 렝더링하는 것이 아니라는 점이 중요하다. 즉 사이트가 배포되고나면 사이트는 변경되지 않는다. 이 pre-rendering된 페이지를 수정하려면 해당 빌드 프로세스 다시 실행하여 다시 배포하거나, ISR을 사용해야 한다.
완전히 정적인 페이지를 생성한다면 빌드 프로세스에서 생성된 것을 사용하면 될 일이다.하지만 데이터를 가져와서 추가해야 한다면, getStaticProps를 사용하면 된다. Next 프로젝트는 이 함수를 검색하여 발견하면 사전렌더링 프로세스 중에 이 함수를 실행한다. 첫번째 싸이클에서 컴포넌트 함수를 바로 호출하지 않고 반환된 JSX 스냅샷을 HTML 컨텐츠로 사용하기 위해 getStaticProps를 호출한다. getStaticProps는 비동기적으로 설정될 수 있는데, promise를 반환하게 되고 Next는 promise가 해결될 때까지 기다린다. 이렇게 되면 컴포넌트 함수가 실행되기 전에 데이터를 읽어들일 수 있어서 이 컴포넌트에서 필요한 데이터를 담아 렌더링할 수 있게 된다.
getStaticProps 함수 내에서는 서버에서 돌아가는 모든 코드를 사용할 수 있는데, 파일시스템이나 데이터베이스에도 안전하게 연결할 수 있다. 여기에 작성되는 모든 코드는 빌드 프로세스 중에 실행되기 때문에, 클라이언트에서는 실행되지 않는다. 예를 들어 API나 데이터베이스에서 데이터를 가져오거나 파일 시스템의 일부 파일에서 데이터를 읽어올 수 있다. 일단 데이터를 읽는 작업을 모두 완료했으면, getStaticProps에서 객체를 반환해야한다. 가장 중요한 점은 일반적으로 이름이 변하면 안 되는 props 프로퍼티를 설정한다는 점인데, 이 과정에서 useEffect나 state가 필요없게 되어 server 컴포넌트로 유지할 수 있게 된다.
코드를 이렇게 변환하면 페이지에 노출되는 내용은 같지만, html 코드를 확인해봤을 때 데이터가 들어가있는 것을 확인할 수 있고, 이는 SEO에 유리한 페이지가 되었다는 것을 뜻한다.
2. 수정된 내용 추가
1. 그라데이션 테두리 만드는 법
일단 그라데이션 테두리는 설정할 수 없다. 솔직히 언젠가는 만들어주면 좋겠다는 생각을 하지만 만들 때마다 참 불편하다는 생각이 든다.
컨테이너 생성 -> 컨테이너에 그라데이션 배경 추가 -> 자식컨테이너를 만들고 배경색을 흰색으로 -> 테두리 역할을 하도록 테두리 반경 추가 순으로 진행된다. 그래도 이번기회에 다시 상기할 수 있어서 좋았다.
import React from "react";
import Image from "next/image";
function SearchBar() {
return (
<div className="h-[82px] w-full rounded-[15px] bg-gradient-to-r from-[#6100FF] to-[#4F6BFF] p-[1px]">
<div className="w-calc(full-2px) relative mx-auto h-[80px] rounded-[14px] bg-white">
<form className="flex">
<input
type="text"
className="mx-auto my-6 ml-6 h-[32px] w-full border-none outline-none placeholder:text-[24px] placeholder:text-[#D6D6D6]"
placeholder="검색어를 입력해주세요."
/>
<Image
src="/icons/search-icon.svg"
alt="search-button"
width={26}
height={26}
className="my-[25px] mr-7"
/>
</form>
</div>
</div>
);
}
export default SearchBar;
테일윈드의 bg-gradient-to-r을 사용해서 배경에 그라데이션을 넣고, border가 1px이기에 자식컴포넌트에 2px을 빼주고 가운데정렬 한 모습이다.
2. tailwind 프로젝트에 폰트 적용하기
이번 수정본에서 추가된 내용 중 Pretenard라는 폰트도 있었는데, 물론 최근 수업시간에도 했지만 직접 하면서 한번 더 정리해보려 한다. Pretenard는 표준으로 자리잡은 한글 폰트로 스타일링이 다양하고 Inter에 비해 자간이 좁다고 느꼈다.
- 폰트의 공식 github로 가서 파일을 다운받는다.
- 압축을 풀고 PretendardVariable.woff2을 프로젝트에 넣는다.
- app.layout에 next패키지의 localFont로 임포트하는데, 여기서 src에 왜 절대경로로 안되는지 모르겠다. 퍼블릭 폴더에 있기에 src: "fonts/..."으로 썼다가 적용되지 않아서 잠깐 해멨다.
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import localFont from "next/font/local";
import Gnb from "@/components/Gnb";
import { cn } from "@/utils/cn";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
const pretendard = localFont({
src: "../../public/fonts/PretendardVariable.woff2",
display: "swap",
weight: "45 920",
variable: "--font-pretendard",
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="ko">
<body className={cn(inter.className, pretendard.variable, "select-none")}>
<Gnb />
{children}
</body>
</html>
);
}
// tailwind.config.ts
theme: {
extend: {
fontFamily: {
pretendard: ["var(--font-pretendard)"],
},
},
},
tailwind.config에 추가해주면 tailwind의 커스텀 속성처럼 사용할 수 있다.
본 후기는 본 후기는 [유데미x스나이퍼팩토리] 프로젝트 캠프 : Next.js 2기 과정(B-log) 리뷰로 작성 되었습니다.
'프로젝트 캠프 : Next.js 2기' 카테고리의 다른 글
[유데미x스나이퍼팩토리] 프로젝트 캠프 : Next.js 2기 - 프로젝트주차 7주차 후기 (0) | 2024.09.26 |
---|---|
[유데미x스나이퍼팩토리] 프로젝트 캠프 : Next.js 2기 - 프로젝트주차 5주차 후기 (0) | 2024.09.09 |
[유데미x스나이퍼팩토리] 프로젝트 캠프 : Next.js 2기 - 프로젝트주차 3주차 후기 (4) | 2024.09.01 |
Vercel 배포 방법 기록 (1) | 2024.08.22 |
[유데미x스나이퍼팩토리] 프로젝트 캠프 : Next.js 2기 - 프로젝트주차 2주차 후기 (0) | 2024.08.19 |