2022.08.04(Thurs)
[TIL] Day70
[SEB FE] Day71
โฐย ์ต์ ํ: ์ฃผ์ด์ง ์กฐ๊ฑด์ผ๋ก ์ต๋ ํจ์จ์ ๋ผ ์ ์๋๋ก ํ๋ ๊ฒ
โฐย ์ต์ ํ in ์น๊ฐ๋ฐ: ์ฃผ์ด์ง ์กฐ๊ฑด ์๋์์ ์ต๋ํ ๋น ๋ฅด๊ฒ ํ๋ฉด์ ํ์ํ๋๋ก ๋ง๋๋ ๊ฒ
์ดํ
์ด๋? ๋ฐฉ๋ฌธ์๊ฐ ์น ์ฌ์ดํธ ์ฒซ ํ์ด์ง์์ ์๋ฌด๋ฐ ์ํธ์์ฉํ์ง ์๊ณ ์ข
๋ฃํ๋ ๊ฒ์ ํ์จ
์ด๋? ํ์๊ฐ์
, ์ํ ๊ตฌ๋งค, ๊ฒ์๊ธ ์กฐํ, ๋ค์ด๋ก๋ ๋ฑ์ ํ์์ ํ ๋ฐฉ๋ฌธ์์ ๋น์จํ๋ฉด ๋ ๋๋ง์
HTML ํ์ผ โ DOM ํธ๋ฆฌ
,CSS ํ์ผ โ CSSOM ํธ๋ฆฌ
๋ฅผ ๊ฒฐํฉํ์ฌ ์ฌ์ฉ
โ ๋ ํธ๋ฆฌ ์ค์์ ํ๋๋ผ๋ ๋ณ๊ฒฝ๋๋ฉด ๋ฆฌ๋ ๋๋ง ์ ๋ฐ!
โ ํธ๋ฆฌ ํฌ๊ธฐ๊ฐ ํฌ๊ธฐ ๋ณต์กํ ์๋ก ๋ ๋ง์ ๊ณ์ฐ ํ์!
โ ๋ฆฌ๋ ๋๋ง์ ์๋ชจ๋๋ ์๊ฐ๋ ๊ธธ์ด์ง
HTML ํ์ผ์์ JS ํ์ผ์ ๋ถ๋ฌ์ฌ ๋
<script>
์์, CSS ํ์ผ์ ๋ถ๋ฌ์ฌ ๋<link>
์์ ์ฌ์ฉ
๐ ํ์ผ์ ๋ถ๋ฌ์ค๋ ์์น๊ฐ ์ด๋์ธ๊ฐ์ ๋ฐ๋ผ์ ๋ ๋๋ง ์๋ฃ ์์ ์ด ๋ฌ๋ผ์ง ์ ์์
<head>
<link href="style.css" rel="stylesheet" />
</head>
<script>
์์๋ฅผ ๋ง๋๋ ์๊ฐ ํด๋น ์คํฌ๋ฆฝํธ ์คํ<script>
์์ ์ด์ ๊น์ง ์์ฑ๋ DOM๊น์ง๋ง ์ ๊ทผ<script>
์์๋ฅผ HTML ์ฝ๋ ์ค๊ฐ์ ๋ฃ๋๋ค๋ฉด, ํ๋ฉด์ด ์๋ํ ๋๋ก ํ์๋์ง ์๊ฒ ๋จ<body>
...
// body ์ง์ ์ ์์ฑํ๋ ๊ฒ์ด good
<script src="script.js" type="text/javascript"></script>
</body>
ํ์ด์ง ๋๋ถ๋ถ์ ์ฉ๋์ ์ด๋ฏธ์ง ํ์ผ๊ณผ ๊ฐ์ ๋ฏธ๋์ด ํ์ผ์ด ์ฐจ์ง
์ด๋ฏธ์ง ์คํ๋ผ์ดํธ
: ์ฌ๋ฌ ๊ฐ์ ์ด๋ฏธ์ง๋ฅผ ๋ชจ์ ํ๋์ ์คํ๋ผ์ดํธ ์ด๋ฏธ์ง๋ฅผ ๋ง๋ค๊ณ , background-position
์์ฑ์ ์ฌ์ฉํด ์ด๋ฏธ์ง ์ผ์ ๋ถ๋ถ๋ง ํด๋์ค ๋ฑ์ผ๋ก ๊ตฌ๋ถํ์ฌ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
์์ด์ฝ ํฐํธ ์ฌ์ฉํ๊ธฐ
CDN์ผ๋ก ์ฌ์ฉ: Font Awesome ๊ฐ์
์ ํคํธ ๋ฐ๊ธ โ HTML ํ์ผ์์ <head>
์์์ ์ฝ์
Font Awesome ๋ชจ๋ ์ค์น
# ํต์ฌ ํจํค์ง ์ค์น
$ npm i --save @fortawesome/fontawesome-svg-core
# Font Awesome React ๊ตฌ์ฑ ์์ ์ค์น
$ npm i --save @fortawesome/react-fontawesome@latest
โย ํด๋์ค๋ช ์ ์ง์ ๋ถ์ด๊ฑฐ๋ Font Awesome ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ฌ ์์ด์ฝ ์คํ์ผ๋ง ๊ฐ๋ฅ
<picture>
ํ๊ทธ๋ฅผ ์ด์ฉํ์ฌ ๊ฐ ๋ธ๋ผ์ฐ์ ํธํ์ ๋ง๋๋ก ๋ถ๊ธฐ ๋์ฒด ๊ฐ๋ฅ<picture>
: img ์์์ ๋ค์ค ์ด๋ฏธ์ง ๋ฆฌ์์ค๋ฅผ ์ํ Container ์ ์์ ์ฌ์ฉ
<!-- webP ์ด๋ฏธ์ง ํฌ๋งท ๋ฏธ์ง์์ <source> ํ๊ทธ ๋ฌด์ -->
<picture>
<source srsset="logo.webp" type="image/webp">
<img src="logo.png" alt="logo">
</picture>
โฐย
์บ์
: ๋ค์ด๋ก๋ ๋ฐ์ ๋ฐ์ดํฐ๋ ๊ฐ์ ๋ฏธ๋ฆฌ ๋ณต์ฌํด ๋๋ ์์ ์ฅ์
๐ซง ๋ฐ์ดํฐ ์ ๊ทผ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๊ฑฐ๋ ๋ค์ ๊ฐ์ ๊ณ์ฐํ๋ ์๊ฐ์ ์ ์ฝํ๊ณ ์ถ์ ๊ฒฝ์ฐ์ ์ฌ์ฉ
โ ์บ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋งค๋ฒ ๋ฆฌ์์ค ๋ค์ด๋ก๋ ๋ฐ์ ํ์ ์์ด ์บ์์์ ๊บผ๋ด์ ์ฌ์ฌ์ฉํ๋ฉด ๋๋ฏ๋ก ๋คํธ์ํฌ ๋ฆฌ์์ค๋ ๋ฌผ๋ก ๋ก๋ฉ ์๊ฐ์ ์ค์ผ ์ ์์
โจย Front์์ ์บ์๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด HTTP ์์ฒญ์ ๋ณด๋ผ ๋ ์กฐ๊ฑด๋ถ ์์ฒญ ํค๋๋ฅผ ์์ฑํ์ฌ ์บ์๋ฅผ ์ฌ์ฌ์ฉํด๋ ๋๋์ง ํ์ธํด์ฃผ๋ฉด ๋จ
If-Modified-Since
: ์บ์๋ ๋ฆฌ์์ค์ Last-Modified
๊ฐ ์ดํ์ ์๋ฒ ๋ฆฌ์์ค๊ฐ ์์ ๋์๋์ง ํ์ธ. ์์ ๋์ง ์์์ผ๋ฉด ์บ์๋ ๋ฆฌ์์ค ์ฌ์ฉIf-None-Match
: ์บ์๋ ๋ฆฌ์์ค์ ETag
๊ฐ๊ณผ ํ์ฌ ์๋ฒ ๋ฆฌ์์ค์ ETag
๊ฐ์ด ๊ฐ์์ง ํ์ธํ๊ณ , ๊ฐ์ผ๋ฉด ์บ์๋ ๋ฆฌ์์ค ์ฌ์ฉย โย ๋ณดํต ๋ ์ข ๋ฅ ํค๋ ๋์ ์ฌ์ฉ
Content Delivery Network
- ์ธ๊ณ ๊ณณ๊ณณ์ ๋ถํฌํ ์๋ฒ์ ์ฝํ ์ธ ์ ์ฅ
๐ย CDN์ ์ ์ ๊ฐ ๊ฐ๊น์ด ๊ณณ์ ์์นํ ๋ฐ์ดํฐ ์ผํฐ(์๋ฒ)์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด โ ๋ฐ์ดํฐ ์ ๋ฌ์ ์ํด ๊ฑฐ์ณ์ผ ํ๋ ์๋ฒ ๊ฐ์ ํฌ๊ฒ ๊ฐ์ โ ๋ก๋ฉ ์๋ fast
: ๋๋ฌด๋ฅผ ํ๋ค์ด ์๊ฐ์ง๋ฅผ ํธ์ด๋ด๋ฏ ๋ถํ์ํ ์ฝ๋๋ฅผ ์ ๊ฑฐํ๋ ๊ฒ
๐ธย ํธ๋ฆฌ์์ดํน์ ํ๋ฉด ์ข์ ์ด์
JS ํ์ผ ํฌ๊ธฐ
JS ํ์ผ ์คํ ์๊ฐ
Tree Shaking
์ ํตํ ์ต์ ํ ํ์ํ์ํ ๋ชจ๋๋ง import
import { useState, useEffect } from 'react'
Babelrc
ํ์ผ ์ค์
import
์ง์ โย โ require
๋ก ๋ณ๊ฒฝ โ ํธ๋ฆฌ์์ดํน์ ๊ฑธ๋ฆผ๋๐ชจrequire
๋ export
๋๋ ๋ชจ๋ ๋ชจ๋์ ๋ถ๋ฌ์ค๊ธฐ ๋๋ฌธ!{
โpresetsโ: [
[
โ@babel/preset-envโ,
{
"modules": false // true ์ค์ -> ํญ์ ES5 ๋ฌธ๋ฒ์ผ๋ก ๋ณํํ๋ฏ๋ก ์ฃผ์!~!
}
]
]
}
sideEffects
์ค์
// sideEffects false ์ค์ -> ์ฝ๋๋ฅผ ์ ์ธ์์ผ๋ ๋จ์ ์นํฉ์๊ฒ ์๋ฆผ
{
"name": "tree-shaking",
"version": "1.0.0",
"sideEffects": false
// "sideEffects": ["./src/components/NoSideEffect.js"]
}
ES6 ๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ ๋ชจ๋ ์ฌ์ฉ
: ๊ตฌ๊ธ์์ ๊ฐ๋ฐํ ์คํ์์ค๋ก์ ์น ํ์ด์ง์ ํ์ง์ ๊ฐ์ ํ ์ ์๋ ์๋ํ ํด
๐ย ์ฑ๋ฅ, ์ ๊ทผ์ฑ, PWA, SEO ๋ฑ์ ๊ฒ์ฌํ์ฌ ์ฌ์ฉ์๋ ์ด๋ค ์นํ์ด์ง๋ ํ์ง ๊ฒ์ฌ ๊ฐ๋ฅ
ํฌ๋กฌ์ผ๋ก ๊ฒ์ฌํ๊ณ ์ถ์ ํ์ด์ง url์ ์ ์ํ์ฌ ๊ฐ๋ฐ์ ๋๊ตฌ open
lighthouse
ํญ ํด๋ฆญ
Analyze page load
ํด๋ฆญํ๊ณ ๊ฒฐ๊ณผ ํ์ธํด๋ณด๊ธฐ
Lighthouse ์ ์ญ ๋ชจ๋๋ก ์ค์น
$ npm install -g lighthouse
๊ฒ์ฌ ์คํ
# Naver ์ฌ์ดํธ ๊ฒ์ฌ ์คํ
$ lighthouse https://www.naver.com/
๋ชจ๋ ์ต์ ํ์ธ
$ lighthouse --help
Performance
: ์น ์ฑ๋ฅ ์ธก์ Accessibility
: ์น ํ์ด์ง๊ฐ ์น ์ ๊ทผ์ฑ์ ์ ๊ฐ์ถ๊ณ ์๋์ง ํ์ธBest Practices
: ์น ํ์ด์ง๊ฐ ์น ํ์ค ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ ๋ฐ๋ฅด๊ณ ์๋์ง ํ์ธSEO
: ์นํ์ด์ง๊ฐ ๊ฒ์ ์์ง ์ต์ ํ๊ฐ ์ ๋์ด์๋์ง ํ์ธrobots.txt
๊ฐ ์ ํจํ์ง<meta>
์์๋ ์ ์์ฑ๋์ด ์๋์งPWA
(Progressive Web App
): ํด๋น ์น ์ฌ์ดํธ๊ฐ ๋ชจ๋ฐ์ผ ์ฑ์ผ๋ก์๋ ์ ์๋ํ๋์ง ํ์ธ (์ฒดํฌ๋ฆฌ์คํธ๋ก ํ์ธ)Splash
ํ๋ฉด์ด ์๋์งFirst Contentful Paint
(FCP
): ์ฑ๋ฅ(Performance) ์งํ ์ถ์ ๋ฉํธ๋ฆญLargest Contentful Paint
(LCP
): Viewport๋ฅผ ์ฐจ์งํ๋ ๊ฐ์ฅ ํฐ ์ฝํ
์ธ ์ render ์๊ฐ ์ธก์ LCP time(in seconds) | Color-coding |
---|---|
0-2.5 | Green ๐ข (fast) |
2.5-4 | Orange ๐ ย (moderate) |
Over 4 | Red ๐ด (slow) |
Speed Index
: ์ฑ๋ฅ ์งํ ์ถ์ ๋ฉํธ๋ฆญSpeen Index (in seconds) | Color-coding |
---|---|
0-3.4 | Green ๐ข (fast) |
3.4-5.8 | Orange ๐ (moderate) |
Over 5.8 | Red ๐ดย (slow) |
Time to interactive
(TTI): ํ์ด์ง๊ฐ ๋ก๋๋๋ ์์ ๋ถํฐ ์ฌ์ฉ์์์ ์ํธ์์ฉ์ด ๊ฐ๋ฅํ ์์ ๊น์ง์ ์๊ฐ ์ธก์ [๊ธฐ์ค]
- ํ์ด์ง์ FCP๋ก ์ธก์ ๋ ์ปจํ
์ธ ํ์๋์ด์ผ ํจ
- ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๊ฐ์ฅ ์ ๋ณด์ด๋ ํ์ด์ง์ ์๋ฆฌ๋จผํธ์ ๋ฑ๋ก
- ํ์ด์ง๊ฐ 0.05์ด์์ ์ฌ์ฉ์์ ์ํธ์์ฉ์ ์๋ต
TTI metric (in seconds) | Color-coding |
---|---|
0-3.8 | Green ๐ขย (fast) |
3.8-7.3 | Orange ๐ (moderate) |
Over 7.3 | Red ๐ด (slow) |
Total Blocking Time
(TBT
): ํ์ด์ง๊ฐ ์ ์ ์ ์ํธ์์ฉํ๊ธฐ๊น์ง์ ๋งํ์๋ ์๊ฐ ์ธก์ FCP
~ TTI
์ฌ์ด์ ๊ธด ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ์์
๋ค์ ๋ชจ๋ ๊ธฐ๋กํ์ฌ TBT
์ธก์ Cumulative Layout Shift
(CLS
): ์ฌ์ฉ์์๊ฒ ์ปจํ
์ธ ๊ฐ ํ๋ฉด์์ ์ผ๋ง๋ ๋ง์ด ์์ง์ด๋์ง(๋ถ์์ ํ์ง) ์์นํํ ์งํโย Opportunities
ํญ๋ชฉ์ ํ์ธํ๋ฉด ๊ฐ Metric๋ณ ๋ฌธ์ ํ์ธ ๊ฐ๋ฅ
Opportunities
ํญ๋ชฉ์ ํ์ธํ๋ฉด ๊ฐMetric
๋ณ ๋ฌธ์ ํ์ธ ๊ฐ๋ฅ!
๐ Naver
์น์ฌ์ดํธ ํ์ธํด๋ณด๊ธฐ
: ์ด๋ฏธ์ง ํฌ๋งท์ ๋ง์ถฐ์ค๐
ย ๐งโจย ํด๊ฒฐ๋ฐฉ์
imgix
์ ๊ฐ์ ์ด๋ฏธ์ง cdn ์ฌ์ฉํ๊ธฐ: ์ฌ์ฉํ์ง ์๋ JavaScript ์ฝ๋๋ฅผ ์ค์ฌ์ค ๐
โย ์ฌ์ฉํ์ง ์๋ JS ๋ก๋์ ๋ถํ์ํ๊ฒ ๋์ญํญ ์ฆ๊ฐ, FCP ์ง์ฐ โ ์ ์ฒด ํ์ด์ง ์ฑ๋ฅ ๋๋ ค์ง
ย ๐งโจย ํด๊ฒฐ๋ฐฉ์
React.lazy()
& Suspense
๋ฅผ ์ฌ์ฉํ์ฌ ์ง๊ธ ๋น์ฅ ํ์ํ ์ฝ๋๊ฐ ์๋๋ฉด ๋ฐ๋ก ๋ถ๋ฆฌ์ํค๊ณ , ๋์ค์ ํ์ํ ๋ ๋ถ๋ฌ์์ ์ฌ์ฉํ๊ธฐ โ ํ์ด์ง ๋ก๋ฉ ์๋ ๊ฐ์ !Tree Shaking
์ฌ์ฉํด๋ณด๊ธฐ: ์ฌ์ฉํ์ง ์๋ CSS ์ญ์ ํด์ค ๐
ย ๐งโจย ํด๊ฒฐ๋ฐฉ์
PurgeCSS
๋ผ๋ postcss ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์ฌ์ฉํ์ง ์๋ CSS ์ญ์ ๊ฐ๋ฅ# postcss-purgecss ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
$ yarn add -D @fullhuman/postcss-purgecss@3.0.0 postcss@7.0.35
// postcss.config.js ํ์ผ ์ถ๊ฐํด์ฃผ๊ธฐ
const purgecss = require('@fullhuman/postcss-purgecss');
module.exports = {
plugins: [
purgecss({
content: ['./src/**/*.vue', './public/index.html'],
css: ['**/*.css'],
whitelistPatterns: [
/-(leave|enter|appear)(|-(to|from|active))$/,
/^(?!(|.*?:)cursor-move).+-move$/,
/^router-link(|-exact)-active$/,
/data-v-.*/,
],
defaultExtractor(content) {
const contentWithoutStyleBlocks = content.replace(
/<style[^]+?<\/style>/gi,
''
);
return (
contentWithoutStyleBlocks.match(/[A-Za-z0-9-_/:]*[A-Za-z0-9-_/]+/g) ||
[]
);
},
}),
],
};
: ๋ ๋๋ง์ ๋ฐฉํดํ๋ ๋ฆฌ์์ค๋ฅผ ์ ๊ฑฐํด์ค๐
โย Render blocking
?
: ๋ธ๋ผ์ฐ์ ๊ฐ ์ธ๋ถ ๋ฆฌ์์ค๋ฅผ ๋ค์ด๋ก๋ํ๊ณ ํ์ฑํ๋ ๋์ ํ์ด์ง ์ฝํ
์ธ ๋ฅผ ํ์ฑ/๋ ๋๋งํ์ง ์๊ธฐ ๋๋ฌธ์ ํ์ด์ง ํ์ ์๋ ์ ํ โฌ๏ธ
ย ๐งโจย ํด๊ฒฐ๋ฐฉ์
<link rel=โpreloadโ>
์ ์ฉ โ CSS๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์์ฒญ: ์ฌ๋ฌ ํ์ด์ง ๋ฆฌ๋๋ ์ ์ ํผํด์ค๐
โย ๋ฆฌ๋๋ ์ ์ ํ์ด์ง ๋ก๋ ์ ์ ์ถ๊ฐ ์ง์ฐ์ ๋ฐ์์ํด
ย ๐งโจย ํด๊ฒฐ๋ฐฉ์