리액트 심화반 5주차

귀찮Lee·2022년 4월 21일
0

22.04.21(목)
스파르타코딩클럽 리액트 심화반 - 5주차 과정

◎ 프로젝트 배포하기 (firebase 이용)

  • Firebase Console 에서 Hosting 탭으로 이동해서 진행
  • Firebase CLI 설치
yarn global firebase-tools
  • Firebase에 로그인하고 init 실행
#웹브라우저가 열리고 내 구글 계정 로그인함
yarn firebase login
#로그인 후 init!
yarn firebase init
  • 실행 시 설정사항
    • 사용하는 프로젝트 전부 선택해줌
    • Please select an option: Use an existing project
    • Rule 관련은 기본값으로 설정 (그냥 enter 눌러주면 됨)
    • What do you want to use as your public directory? public ( 또는 build)
    • Configure as a single-page app (rewrite all urls to /index.html)? N
  • 빌드 후 Firebase Hosting으로 배포
yarn build # 빌드하기

◎ SEO(Search Engin Optimization)

  • SEO(Search Engin Optimization, 검색엔진최적화) : 내가 만든 사이트가 검색 결과에 더 잘 보이게 하기 위한 과정

  • React는 HTML 파일이 딱 1개 뿐이고, 렌더링이 되기 전까지(자바스크립트를 실행하기 전까지)는 껍데기 html 내용만 나옴
    -> 기본적으로는 검색 엔진에 올라가기가 어려움
    -> React에서도 검색 엔진이 긁어갈 수 있도록 미리 html 파일 내용을 보여줄 필요가 있다.

  • React에서 검색엔진 최적화 하는법

    1. meta-data 넣기
    2. pre-rendering
    3. Server Side Redering

-> google 검색 엔진은 리액트같은 CSR방식 사이트도 크롤링을 잘 함, 검색 엔진마다 크롤링을 해가는 방법이 천차만별
-> 그래서 우리는 우리가 어떤 검색 엔진에 노출되고 싶은 지를 결정하고, 해당 검색 엔진이 제공하는 SEO 가이드에 맞춰서 어떤 방법을 사용할 지 정해야 함.
-> SEO는 사이트(프로젝트)에 따라 용도에 맞게 사용할 수도 안 할수도 있다.

◎ Pre-rendering

  • Pre-rendering : 빌드할 때 미리 특정 페이지를 렌더링해서 html 파일을 만들어 둔다. 검색 엔진이 크롤링하러 사이트에 들어왔을 때, 해당 내용물을 가져갈 수 있다.

  • react-snap을 사용하여 pre-rendering 하기

    yarn add react-router-dom # 페이지 이동
    yarn add --dev react-snap # --dev:개발 환경에서만
    • react-snap 적용
    // index.js
    import React from 'react';
    import ReactDOM, { hydrate } from "react-dom";
    ...
    const root = document.getElementById("root");
    
    if (root.hasChildNodes()) {
      // hydration : 정적으로 렌더링 된 HTML 컨텐츠를 우리가 알고 있는 컴포넌트 트리로 재구성함
      // hydrate : 렌더링한 컨테이너에 이벤트를 보충해주는 역할 (정적 컨텐츠가 동적으로 동작할 수 있도록 해줌)
      hydrate(
          <App />,
        root
      );
    } else {
      ReactDOM.render(
        <App />,
        root
      );
    }
    ...
    // package.json
    ...
    "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject",
        "postbuild": "react-snap"
      },
    ...
    // reactSnap에 pre-rendering 할 페이지 url을 넣음
    "reactSnap": {
        "include": [
          "/two",
          "/"
        ]
      },
    ...
    • Pre-rendering 로컬에서 적용 확인하기 // postman으로 확인
    yarn build # 빌드하기
    // src > serve.json 만들기
    {
      "rewrites": [
        { "source": "/", "destination": "/200.html" },
        { "source": "/two", "destination": "/two/index.html" }
      ]
    }

◎ Meta tag (페이지마다 다르게 적용해보기)

  • react-helmet 설치하기
yarn add react-helmet
  • 페이지에 적용해보기
//One.js
import React from "react";
import {Helmet} from "react-helmet";
const One = (props) => {
    return (
      <div>
        <Helmet>
          <title>page one</title>
          <meta property="og:title" content="page one" />
          <meta property="og:description" content="hi there :) page one" />
          <meta property="og:image" content="%PUBLIC_URL%/logo192.png" />
        </Helmet>
       ...
    );
}

export default One;

◎ 성능 지표 보기

  • webVitals : CRA(create react-app) 4버전 이후에 기본적으로 설치되는 것들 중 하나

  • 지표 정보

    • CLS : cumilative layout shift / 클릭 이벤트, 광고, 컨텐츠 위치 변화 등의 사용성 측정
    • FID : first input delay / 웹페이지의 반응성 지표
    • FCP: first contentful paint / 브라우저가 화면에 그려넣기 시작한 지점까지의 시간
    • LCP: largest contentful paint / 웹페이지에서 제일 커다란(중요고가 높은) 덩어리를 그리는데 걸린 시간
    • TTFB: time to first byte / 브라우저가 페이지에 들어갈 내용의 가장 첫번쨰 바이트를 가져오는데 걸린 시간 (서버사이드 랜더링, 프리 랜더링을 할때는 반드시 체크!)
      -> chrome dev-tools에서도 확인 가능
  • report를 콘솔에 찍어보기

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './shared/App';
import reportWebVitals from './reportWebVitals';
import store from "./redux/configureStore";

import { Provider } from "react-redux";

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals(console.log);
  • 어딘가로 보내기
// 함수를 만들고,
function sendToAnalytics(metric) {
  const body = JSON.stringify(metric);
  const url = 'https://example.com/analytics';

  // Use `navigator.sendBeacon()` if available, falling back to `fetch()`
  if (navigator.sendBeacon) {
    navigator.sendBeacon(url, body);
  } else {
    fetch(url, { body, method: 'POST', keepalive: true });
  }
}

// console.log 대신 넘겨줘요!
reportWebVitals(sendToAnalytics);
  • firebase analytics 연결하기
// firebase.js
...
import "firebase/analytics";

const firebaseConfig = {
  // 인증 정보!
};
...

const analytics = firebase.analytics();

export{auth, apiKey, firestore, storage, realtime, analytics};
//index.js
...
import { analytics } from "./shared/firebase";
...
function sendToAnalytics(metric) {
  const _report = JSON.stringify(metric);

  analytics.logEvent("web_vital_report", _report);

  console.log({ _report });
}

reportWebVitals(sendToAnalytics);

◎ 랜더링 횟수 줄이기

  • 기본적으로 부모 컴포넌트가 리랜더링 되면, 바뀔 것이 없는 자식 컴포넌트까지 리랜더링이 됨
  • 이를 막기위해, React.memo를 시용
// components/Post.js

import React from "react";
import { Grid, Image, Text, Button } from "../elements";

import {history} from "../redux/configureStore";

 const Post = React.memo((props) => {
   console.log("in post"); // React.memo 사용 했을때와 안 했을때 비교
   return (
     <React.Fragment>
       ...
     </React.Fragment>
   );
 });
...

◎ 이 후에는 뭘 해야할까?

  • 사이트는 다 만들었다고 끝이 아니예요! 계속 고쳐나가야 한다. 사이트가 느리지는 않은 지, 불편한 점은 없는 지 고민하고 개선해야 한다.

  • 성능 최적화:
    사이트 로딩 속도 개선, api 중복 호출 방지, 오류가 나지 않도록 api 호출 전후처리 꼼꼼히 하기 등등!

  • 사용성 끌어올리기:
    오류가 나도 빈화면을 보지 않도록 에러 페이지 만들어주기, 오래걸리는 비동기 작업이 있다면 스피너를 띄워주기, 이미지 지연로딩 등등!

profile
장비를 정지합니다.

0개의 댓글

관련 채용 정보