지난번에 이어서 성능개선 후기
외부 스크립트의 상호작용 시점 변경
next의 경우 next/script 사용, afterInteractive 옵션 추가
<Script
id="GTM"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','${GTMID}');`,
}}
/>
beforeInteractive : 페이지가 상호작용되기 전에 로드 됩니다.
afterInteractive : 페이지가 상호작용이 가능해진 직후에 즉시 로드됩니다.
lazyOnload: idle time 동안에 로드 됩니다.
react의 경우 defer와 async 옵션 사용
<script defer type="text/javascript"></script>
<link
as="font"
rel="preload"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
<link
as="font"
rel="preload"
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.5/dist/web/static/pretendard.css"
/>
여기서 &display=swap 쿼리를 사용하면 웹폰트 로드 중 기본 폰트 노출 할 수 있습니다.
번들 트리 쉐이킹
코드 스플리팅
import dynamic from 'next/dynamic'
const MainGnbDynamic = dynamic(() => import('./layouts/main-gnb'), { suspense: true })
import {lazy, Suspense} from 'react'
const Request = lazy(() => import('./pages/request/request'))
Cloud Front를 통하는 미디어 리소스들에 대한 Cache-control 설정
사용하지 않는 CSS 제거
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"postbuild": "purgecss --css build/static/css/*.css --content build/index.html build/static/js/*.js --output build/static/css"
}