wrapAsync부분 제네릭으로 만들기
export const wrapAsync = <T> //나만의 타입적은것. (asyncFunc(event:T)=>Promise<void>)=>(event:T)=>{ // :해당타입 void asyncFunc(event) } // 알아서 해당타입이 추론되어 작동될것임.
event타입이 다 다를 수 있기에 제네릭타입이나 any를 사용한다.
==> 기존방법
낙관적 UI
좋아요 카운트 등 중요하지 않는곳에 사용.
미리 카운트 해놓고 보여주고, 후에 DB에 보내 실제 결과를 그 후에 보여주어 다른지 비교함
덜 중요하면서, 실패해도 문제가 되지 않고, 성공확률이 99%인곳에서 사용!!(결제에 사용X).
=> 낙관적 UI!!
필요시에만 import하기. 버튼클릭시 보여지는 컴포넌트 -> Next의 next/dynamic사용, 또는 React 의 React.lazy사용
프리로드 프리패치의 경우 next에서 자체적으로 일부 해주기도한다.(yarn build로 최적화시키면 html로 바뀌면서 preload, prefetch가 적용된것을 볼 수 있다.
브라우저주소창의 실체
스크랩핑 + 크롤링
==> 다른 사이트 정보 가져오기
스크래핑: 긁어오기(한번가져오기 Cheerio라는 라이브러리 사용)
크롤링: 헤엄쳐서 일정주기동안가져오기(퍼펙티어라는 라이브러리 사용)
이전에 브라우저에 대해 간단히 알아보자.
자세히보면 document로 먼저 받아그려지는 부분이 네트워크에 보여지고, response,request가 있고 get방식이라고 적혀있는것으로 보아 얘도 rest-api의 get요청이라고 할 수 있다.
따라서 포스트맨이나 터미널의 curl을 이용하면 같은 결과를 받아올 수 있다.
차이점
브라우저는 html코드를 예쁘게 변경해 화면에 그려주는 역할까지 하는것이고 나머지의 작동방법은 같다.
(단지 브라우저는 html코드이면 화면에 예쁘게 그려주는것)
요청을 보낸다 => /엔드포인트
이다 => html로 돌려주고, 브라우저에서는 이 html을 그림으로 변경해준다!!
우리폴더에 pages라는 폴더에있는 폴더들이 바로 rest의 엔드포인트가 되시겠다.
요즘트랜드 => 벡엔드 엔드포인트를 요청하면 JSON을 주고,
프론트엔드 엔드포인트를 요청하면 html을 주고 브라우저이니 그림으로 그려서 보여줌.
다시말하면 axios로 html을 받아올 수 있다는말이된다!
채팅창등에 사이트 주소를 입력해 전달하면 주소와 그림? 이 같이 뜨는것을 볼수 있다.
그렇다면 이것들을 직접 다 코딩하는것일까>?
제공자관점: 제목, 내용등으로 만들어 제공.
개발자관점.: 해당사이트를 스크랩핑해서 제공되는저것을 변수에 담아 뽑아 화면에 보여준다.
그렇다면 제공자는 어떻게 제공을 하나?
meta태그에 og:~~ 라고나온 부분이 보인다.
똑같이 나온것을 볼 수 있다.
따라서 내 사이트가 미리보기가 되었으면 한다면 저렇게 제공해주어야한다. og를 오픈 그래프라고하는데 처음에는 페이스북에서 만들어 사용되었다.
(별다른 의미는 없다는 말)
실습해보기.
// 제공자일때 -> 네이버, 다음, 쿠팡..
import Head from "next/head";
export default function OpengraphProviderPage(): JSX.Element {
return (
<>
<Head>
<meta property="og:title" content="중고마켓" />
<meta property="og:description" content="나의 중고마켓" />
<meta
property="og:image"
content="http://~~"
/>
</Head>
<div>중고마켓에 오신것을 환영합니다(어기는 Body입니다.)</div>
</>
);
}
>
// 개발자일때 - > 디스코드, 카카오톡, 슬랙 등
import axios from "axios";
import { wrapAsync } from "../../../src/commons/libraries/asyncFunc";
export default function OpengraphDeveloperPage(): JSX.Element {
const onClickEnter = async (): Promise => {
// 채팅을 입력했을때 해당 주소와 사진을 나오게..
// 1. 채팅 데이터에 주소가 있는지 찾기(http ~~~)
// 2. 주소를 요청해(axios로) 받아서 변수에 넣어 꺼내씀(해당 주소로 스크랰핑하기)
// 3. 메타태그에서 오픈그래프 (og: )찾기
// 해당 벡엔드서버, 또는 프론트엔드에서 CORS를 열어주지 않으면 사용할 수 없다.
// 이럴경우에 해당 서버를 우회하는 프록시 서버를 만들어 사용해야한다.
// 우회하기: 나의 벡엔드를 만들어 우회하기(서버에서 서버는 가능하나) --> 얘가 프록시서버
// 또는 모바일에서는 무조건 가능하니 모바일로(브라우저만 안되는것 - 브라우저에서 막는것이니)
const result = await axios.get(
"http://localhost:3000/section32/32-01-opengraph-provider"
); // 프론트엔드에서 처리하는 방법: 웹펙서버(프론트엔드서버)에서 프록시서버 만들기 라는것이 가능. 또는직접벡엔드(node벡엔드)만들어서 처리.
console.log(result.data);
console.log(result.data.split("<meta"));
console.log(
result.data.split("<meta").filter((el: string) => el.includes("og:")) // <meta를 기준으로 쪼개고. 그 안에서 og: 가 든것만 뽑기
);
};
return (
<>
채팅입력후 엔터치기
</>
);
}
-----
다이나믹 오픈 그래프!!
???뺙
페이지 주소가 배번 바뀐다.(상품마다 다르게 사진, 내용 등 다르게 보이기)
한 페이지 안에서 og를 바꿔치기 ??
useQuery해서 fetch해서 받은 data를 받고 이것을 각각 넣으면 되지않나?
> 실재로 이렇게 코드를 작성해 data를 각각의 content에 넣었고, 브라우저를 확인해보니 Element에 잘 나오는것이 확인된다.
그런데 같은 주소를 입력해 postman에서 확인해보니 meta태그에 og는 있으나 이 content가 없는것이 보인다.
그리고 브라우저에서 네트워크의 document부분을 다시 보니 여기서도 이 content가 없는것이 보인다.
그럼 Element에서는 어떻게 나오는것일까?
>> 모든 첫요청은 브라우저 첫 HTML. 이 최초접속시 나오는 html은 data가 없다.
html을 받고 나서 data에 대한 요청을 보내어 받고 랜더링하고나서야 이 data를 화면에 보여준다.(클라이언트 사이드에서)
### SSR!
서버사이드랜더링 . data까지 있는 html을 내놓으라고요청
DB에서꺼내서 벡엔드를 통해 data까지 포함된 html을 받는다.
==> 이 과정이 바로 서버사이드랜더링. 프론트에서 벡으로 요청하기.
---
## 서버사이드랜더링.
안에 데이터를 못바꾼다는 단점이있다.
페이지접속때마다 서버에서 데이터 받아서 완성된 html을 보내 브라우저에 보여준다. ===> **SEO**좋음(검색엔진노출좋음)
## CSR(클라이언트 서버 랜더링?)
html만 받아오고, data는 처음에 빠져있으니 SEO는 좋지 않다. 처음에는 data가 빠져있어서 엔진이 못잡기때문이다.
>> 따라서 검색엔진 최적화를 위해서는 SSR을 적용하는것이 좋다.
### 그럼 무조건 SSR을 적용해야하는가?
NO, 접속때마다 느리기때문에 모든곳에 적용하는것이 아니다. 요즘에는 CSR을 주로쓰기때문애html을 먼저 받아오고 후에 data를 요청해 받아오기때문에 빠르다.
대부분의 상세페이지의 경우는 SSR을 적용!!