[TIL] Day70 #Optimization #Lighthouse

Beanxxยท2022๋…„ 8์›” 4์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
70/120
post-thumbnail

2022.08.04(Thurs)

[TIL] Day70
[SEB FE] Day71

โ˜‘๏ธย Optimization

โžฐย ์ตœ์ ํ™”: ์ฃผ์–ด์ง„ ์กฐ๊ฑด์œผ๋กœ ์ตœ๋Œ€ ํšจ์œจ์„ ๋‚ผ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ
โžฐย ์ตœ์ ํ™” in ์›น๊ฐœ๋ฐœ: ์ฃผ์–ด์ง„ ์กฐ๊ฑด ์•„๋ž˜์—์„œ ์ตœ๋Œ€ํ•œ ๋น ๋ฅด๊ฒŒ ํ™”๋ฉด์„ ํ‘œ์‹œํ•˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ

๐Ÿ“Žย ์ตœ์ ํ™” ํ•„์š”์„ฑ / ํšจ๊ณผ

  1. ์ดํƒˆ๋ฅ  ๊ฐ์†Œ โฌ‡๏ธ
    • ์ดํƒˆ์ด๋ž€? ๋ฐฉ๋ฌธ์ž๊ฐ€ ์›น ์‚ฌ์ดํŠธ ์ฒซ ํŽ˜์ด์ง€์—์„œ ์•„๋ฌด๋Ÿฐ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๊ณ  ์ข…๋ฃŒํ•˜๋Š” ๊ฒƒ
    • ํ™”๋ฉด ๋ถˆ๋Ÿฌ์˜ค๋Š” ์‹œ๊ฐ„์ด ๊ธธ์–ด์ง€๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ์ดํƒˆํ•  ํ™•๋ฅ  ๋†’์•„์ง
  2. ์ „ํ™˜์œจ ์ฆ๊ฐ€ โฌ†๏ธ
    • ์ „ํ™˜์œจ์ด๋ž€? ํšŒ์›๊ฐ€์ž…, ์ƒํ’ˆ ๊ตฌ๋งค, ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ, ๋‹ค์šด๋กœ๋“œ ๋“ฑ์˜ ํ–‰์œ„์„ ํ•œ ๋ฐฉ๋ฌธ์ž์˜ ๋น„์œจ
    • ์ดํƒˆ๋ฅ ์ด ์ค„์–ด๋“ค๋ฉด, ์ „ํ™˜์œจ์ด ๋†’์•„์งˆ ํ™•๋ฅ ๋„ ์ปค์ง
  3. ์ˆ˜์ต ์ฆ๋Œ€ โฌ†๏ธ
    • ์ดํƒˆ๋ฅ  ๊ฐ์†Œ, ์ „ํ™˜์œจ ์ฆ๊ฐ€ โ†’ ํŠธ๋ž˜ํ”ฝ ์ฆ๋Œ€ / ํšŒ์› ์ˆ˜ ์ฆ๊ฐ€ โ†’ ์ˆ˜์ต ์ฆ๋Œ€
  4. ์‚ฌ์šฉ์ž ๊ฒฝํ—˜(UX) ํ–ฅ์ƒ โฌ†๏ธ
    • ํŽ˜์ด์ง€ ๋กœ๋”ฉ์ด ๋น ๋ฅผ์ˆ˜๋ก UX ํ–ฅ์ƒ

โ˜‘๏ธย Optimization ๊ธฐ๋ฒ•

ํ™”๋ฉด ๋ Œ๋”๋ง์‹œ HTML ํŒŒ์ผ โ†’ DOM ํŠธ๋ฆฌ, CSS ํŒŒ์ผ โ†’ CSSOM ํŠธ๋ฆฌ๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉ
โ†’ ๋‘ ํŠธ๋ฆฌ ์ค‘์—์„œ ํ•˜๋‚˜๋ผ๋„ ๋ณ€๊ฒฝ๋˜๋ฉด ๋ฆฌ๋ Œ๋”๋ง ์œ ๋ฐœ!
โ†’ ํŠธ๋ฆฌ ํฌ๊ธฐ๊ฐ€ ํฌ๊ธฐ ๋ณต์žกํ• ์ˆ˜๋ก ๋” ๋งŽ์€ ๊ณ„์‚ฐ ํ•„์š”!
โ†’ ๋ฆฌ๋ Œ๋”๋ง์— ์†Œ๋ชจ๋˜๋Š” ์‹œ๊ฐ„๋„ ๊ธธ์–ด์ง

๐Ÿ”นย HTML ์ตœ์ ํ™”

  1. DOM ํŠธ๋ฆฌ ๊ฐ€๋ณ๊ฒŒ ๋งŒ๋“ค๊ธฐ
    • DOM ํŠธ๋ฆฌ๊ฐ€ ๊นŠ์„์ˆ˜๋ก, ์ž์‹ ์š”์†Œ๊ฐ€ ๋งŽ์„์ˆ˜๋ก DOMํŠธ๋ฆฌ ๋ณต์žก๋„ ์ปค์ง โฌ†๏ธ
    • ๋ณต์žก๋„๊ฐ€ ํด์ˆ˜๋ก DOM ํŠธ๋ฆฌ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ ๊ณ„์‚ฐํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ๋„ ๋งŽ์•„์ง โฌ†๏ธ
    • โœ”๏ธย ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๊นŠ์ด๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ์š”์†Œ๊ฐ€ ์žˆ๋‹ค๋ฉด ์‚ญ์ œํ•˜๊ธฐ!
  2. ์ธ๋ผ์ธ ์Šคํƒ€์ผ ์‚ฌ์šฉ โŒ
    • ์ธ๋ผ์ธ ์Šคํƒ€์ผ์€ ๊ณ„์†ํ•ด์„œ ๋ฆฌํ”Œ๋กœ์šฐ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ ๋ Œ๋”๋ง ์™„๋ฃŒ ์‹œ์  ๋Šฆ์ถค
    • ์ธ๋ผ์ธ ์Šคํƒ€์ผ์€ ์›น ํ‘œ์ค€์— ๋งž์ง€ ์•Š์œผ๋ฏ€๋กœ ์ง€์–‘!

๐Ÿ”นย CSS ์ตœ์ ํ™”

  1. ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” CSS ์ œ๊ฑฐํ•˜๊ธฐ
    • ์š”์†Œ ์‚ญ์ œ์‹œ, CSS ์ฝ”๋“œ๋„ ํ•จ๊ป˜ ์‚ญ์ œ
  2. ๊ฐ„๊ฒฐํ•œ Selector ์‚ฌ์šฉํ•˜๊ธฐ
    • Selector๊ฐ€ ๋ณต์žกํ• ์ˆ˜๋ก ์Šคํƒ€์ผ ๊ณ„์‚ฐ๊ณผ ๋ ˆ์ด์•„์›ƒ์— ์‹œ๊ฐ„์„ ๋” ๋งŽ์ด ์†Œ๋ชจ

๐Ÿ”นย ๋ฆฌ์†Œ์Šค ๋กœ๋”ฉ ์ตœ์ ํ™”

HTML ํŒŒ์ผ์—์„œ JS ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜ฌ ๋• <script> ์š”์†Œ, CSS ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜ฌ ๋• <link> ์š”์†Œ ์‚ฌ์šฉ
๐Ÿ‘‰ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์œ„์น˜๊ฐ€ ์–ด๋””์ธ๊ฐ€์— ๋”ฐ๋ผ์„œ ๋ Œ๋”๋ง ์™„๋ฃŒ ์‹œ์ ์ด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Œ

  1. CSS ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
    • CSSOM ํŠธ๋ฆฌ๋Š” CSS ์ฝ”๋“œ๋ฅผ ๋ชจ๋‘ ํ•ด์„ํ•ด์•ผ ๊ตฌ์„ฑ ๊ฐ€๋Šฅํ•จ
      โ‡’ CSSOM ํŠธ๋ฆฌ๋ฅผ ๋น ๋ฅด๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก HTML ๋ฌธ์„œ ์ตœ์ƒ๋‹จ์— ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Œ ๐Ÿ‘
    <head>
    	<link href="style.css" rel="stylesheet" />
    </head>
  2. JavaScript ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
    • <script> ์š”์†Œ๋ฅผ ๋งŒ๋‚˜๋Š” ์ˆœ๊ฐ„ ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰
      โ†’ <script> ์š”์†Œ ์ด์ „๊นŒ์ง€ ์ƒ์„ฑ๋œ DOM๊นŒ์ง€๋งŒ ์ ‘๊ทผ
      โ†’ <script> ์š”์†Œ๋ฅผ HTML ์ฝ”๋“œ ์ค‘๊ฐ„์— ๋„ฃ๋Š”๋‹ค๋ฉด, ํ™”๋ฉด์ด ์˜๋„ํ•œ ๋Œ€๋กœ ํ‘œ์‹œ๋˜์ง€ ์•Š๊ฒŒ ๋จ
    • ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€ DOM ํŠธ๋ฆฌ ์ƒ์„ฑ ์ค‘๋‹จ โ†’ ์ค‘๋‹จ ์‹œ๊ฐ„๋งŒํผ ๋ Œ๋”๋ง ์™„๋ฃŒ ์‹œ๊ฐ„ delay
      โ‡’ JSํŒŒ์ผ์€ DOM ํŠธ๋ฆฌ ์ƒ์„ฑ ์™„๋ฃŒ ์‹œ์ ์ธ HTML ๋ฌธ์„œ ์ตœํ•˜๋‹จ์— ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Œ ๐Ÿ‘
      <body>
          ...
       	// body ์ง์ „์— ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด good
       	<script src="script.js" type="text/javascript"></script>
      </body>

๐Ÿ”นย ๋ธŒ๋ผ์šฐ์ € ์ด๋ฏธ์ง€ ์ตœ์ ํ™”

ํŽ˜์ด์ง€ ๋Œ€๋ถ€๋ถ„์˜ ์šฉ๋Ÿ‰์€ ์ด๋ฏธ์ง€ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๋ฏธ๋””์–ด ํŒŒ์ผ์ด ์ฐจ์ง€

  1. ์ด๋ฏธ์ง€ ์Šคํ”„๋ผ์ดํŠธ
    : ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ด๋ฏธ์ง€๋ฅผ ๋ชจ์•„ ํ•˜๋‚˜์˜ ์Šคํ”„๋ผ์ดํŠธ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค๊ณ , background-position ์†์„ฑ์„ ์‚ฌ์šฉํ•ด ์ด๋ฏธ์ง€ ์ผ์ • ๋ถ€๋ถ„๋งŒ ํด๋ž˜์Šค ๋“ฑ์œผ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

    • ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„ ์š”์ฒญ์ด ์ฆ๊ฐ€ํ• ์ˆ˜๋ก ๋กœ๋”ฉ ์‹œ๊ฐ„์€ ์ ์  ๋Š˜์–ด๋‚จ
      โ‡’ ์›น ํŽ˜์ด์ง€ ๋กœ๋“œ์— ํ•„์š”ํ•œ ์„œ๋ฒ„ ์š”์ฒญ ์ˆ˜๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ์ด๋ฏธ์ง€ ์Šคํ”„๋ผ์ดํŠธ ๊ธฐ๋ฒ• ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    • ๐Ÿ‘ย ์ด๋ฏธ์ง€ ์Šคํ”„๋ผ์ดํŠธ ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด 1๋ฒˆ์˜ ์ด๋ฏธ์ง€ ์š”์ฒญ์œผ๋กœ ๊ฐœ๋ณ„ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋„คํŠธ์›Œํฌ ๋กœ๋”ฉ ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ์Œ
    • ๐Ÿ‘ย ํŠน์ • ์Šคํ”„๋ผ์ดํŠธ ์ด๋ฏธ์ง€ ํŒŒ์ผ๋งŒ ๊ด€๋ฆฌํ•˜๋ฉด ๋˜๋ฏ€๋กœ ๊ด€๋ฆฌ๊ฐ€ ์šฉ์ดํ•จ

  2. ์•„์ด์ฝ˜ ํฐํŠธ ์‚ฌ์šฉํ•˜๊ธฐ

    1. CDN์œผ๋กœ ์‚ฌ์šฉ: Font Awesome ๊ฐ€์ž…์‹œ ํ‚คํŠธ ๋ฐœ๊ธ‰ โ†’ HTML ํŒŒ์ผ์—์„œ <head> ์š”์†Œ์— ์‚ฝ์ž…

    2. Font Awesome ๋ชจ๋“ˆ ์„ค์น˜

      # ํ•ต์‹ฌ ํŒจํ‚ค์ง€ ์„ค์น˜ 
      $ npm i --save @fortawesome/fontawesome-svg-core
      
      # Font Awesome React ๊ตฌ์„ฑ ์š”์†Œ ์„ค์น˜
      $ npm i --save @fortawesome/react-fontawesome@latest

      โœ‹ย ํด๋ž˜์Šค๋ช…์„ ์ง์ ‘ ๋ถ™์ด๊ฑฐ๋‚˜ Font Awesome ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์•„์ด์ฝ˜ ์Šคํƒ€์ผ๋ง ๊ฐ€๋Šฅ

  1. WebP / AVIF ์ด๋ฏธ์ง€ ํฌ๋งท ์‚ฌ์šฉํ•˜๊ธฐ
    • WebP / AVIF ์‚ฌ์šฉ์‹œ JPEG/PNG๋ณด๋‹ค ์šฉ๋Ÿ‰ ๋Œ€ํญ ๊ฐ์†Œ
    • But, ๋น„๊ต์  ์ตœ๊ทผ์— ๋“ฑ์žฅํ•œ ์ด๋ฏธ์ง€ ํฌ๋งท์ด๋ฏ€๋กœ ๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ˜ธํ™˜ โŒ
      โ‡’ <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 ๊ฐ’์ด ๊ฐ™์€์ง€ ํ™•์ธํ•˜๊ณ , ๊ฐ™์œผ๋ฉด ์บ์‹œ๋œ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ

ย  โœ‹ย ๋ณดํ†ต ๋‘ ์ข…๋ฅ˜ ํ—ค๋” ๋™์‹œ ์‚ฌ์šฉ

๐Ÿ”นย CDN ์‚ฌ์šฉ

Content Delivery Network

  • ์„ธ๊ณ„ ๊ณณ๊ณณ์— ๋ถ„ํฌํ•œ ์„œ๋ฒ„์— ์ฝ˜ํ…์ธ  ์ €์žฅ
    ๐Ÿ‘‰ย CDN์€ ์œ ์ €๊ฐ€ ๊ฐ€๊นŒ์šด ๊ณณ์— ์œ„์น˜ํ•œ ๋ฐ์ดํ„ฐ ์„ผํ„ฐ(์„œ๋ฒ„)์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ด โ‡’ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์„ ์œ„ํ•ด ๊ฑฐ์ณ์•ผ ํ•˜๋Š” ์„œ๋ฒ„ ๊ฐœ์ˆ˜ ํฌ๊ฒŒ ๊ฐ์†Œ โ†’ ๋กœ๋”ฉ ์†๋„ fast

๐ŸŒฒย Tree Shaking

: ๋‚˜๋ฌด๋ฅผ ํ”๋“ค์–ด ์ž”๊ฐ€์ง€๋ฅผ ํ„ธ์–ด๋‚ด๋“ฏ ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ

๐Ÿ”ธย ํŠธ๋ฆฌ์‰์ดํ‚น์„ ํ•˜๋ฉด ์ข‹์€ ์ด์œ 

  1. JS ํŒŒ์ผ ํฌ๊ธฐ

    • ์ ์  ์ธํ„ฐ๋ž™์…˜์ด ํ™”๋ คํ•ด์งˆ์ˆ˜๋ก ํŒŒ์ผ ํฌ๊ธฐ โฌ†๏ธย โ†’ HTTP ์š”์ฒญ ์ˆ˜ ๋˜ํ•œ ์ฆ๊ฐ€ โฌ†๏ธ โ†’ ๋„คํŠธ์›Œํฌ ๋ฆฌ์†Œ์Šค ์†Œ๋ชจ โฌ†๏ธ
    • โœ”๏ธย ํŠธ๋ฆฌ์‰์ดํ‚น์„ ํ†ตํ•ด ํŒŒ์ผ ํฌ๊ธฐ๋ฅผ ๊ฐ€๋Šฅํ•œ ์ค„์ด๋Š” ๊ฒƒ์ด ์ตœ์ ํ™”์— ๋„์›€!
  2. JS ํŒŒ์ผ ์‹คํ–‰ ์‹œ๊ฐ„

    • JS๋Š” ์ฝ”๋“œ ์‹คํ–‰๊นŒ์ง€ ๊ฑฐ์ฒ˜์•ผ ํ•˜๋Š” ๊ณผ์ •์ด ๋งŽ์œผ๋ฏ€๋กœ ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค์— ๋น„ํ•ด ์‹คํ–‰๊นŒ์ง€ ์ƒ๋Œ€์ ์œผ๋กœ ๋งŽ์€ ์‹œ๊ฐ„ ์†Œ๋ชจ
      โ‡’ Tree Shaking์„ ํ†ตํ•œ ์ตœ์ ํ™” ํ•„์š”

๐ŸŒฟย JS Tree Shaking ์ˆ˜ํ–‰ ๋ฐฉ๋ฒ•

  1. ํ•„์š”ํ•œ ๋ชจ๋“ˆ๋งŒ import

    import { useState, useEffect } from 'react'
  2. Babelrc ํŒŒ์ผ ์„ค์ •

    • Babel: JS ๋ฌธ๋ฒ•์ด ๊ตฌํ˜• ๋ธŒ๋ผ์šฐ์ €์—์„œ๋„ ํ˜ธํ™˜ ๊ฐ€๋Šฅํ•˜๋„๋ก ES5 ๋ฌธ๋ฒ•์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • ES5๋ฌธ๋ฒ•์€ import ์ง€์› โŒย โ†’ require๋กœ ๋ณ€๊ฒฝ โ‡’ ํŠธ๋ฆฌ์‰์ดํ‚น์— ๊ฑธ๋ฆผ๋Œ๐Ÿชจ
      • require๋Š” export๋˜๋Š” ๋ชจ๋“  ๋ชจ๋“ˆ์„ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋•Œ๋ฌธ!
    {
      โ€œpresetsโ€: [ 
        [
          โ€œ@babel/preset-envโ€,
          {
    	    "modules": false // true ์„ค์ • -> ํ•ญ์ƒ ES5 ๋ฌธ๋ฒ•์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋ฏ€๋กœ ์ฃผ์˜!~!
          }
        ]
     ]
    }
  3. sideEffects ์„ค์ •

    • Webpack์€ sideEffects๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ, ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋ผ๋„ ํŠธ๋ฆฌ์‰์ดํ‚น ๋Œ€์ƒ์—์„œ ์ œ์™ธ์‹œํ‚ด
    // sideEffects false ์„ค์ • -> ์ฝ”๋“œ๋ฅผ ์ œ์™ธ์‹œ์ผœ๋„ ๋จ์„ ์›นํŒฉ์—๊ฒŒ ์•Œ๋ฆผ
    {
      "name": "tree-shaking",
      "version": "1.0.0",
      "sideEffects": false
    	// "sideEffects": ["./src/components/NoSideEffect.js"]
    }
  4. ES6 ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“ˆ ์‚ฌ์šฉ

    • ES5 ๋ฌธ๋ฒ• ์ผ๋ถ€๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ โ†’ ES6๋ฅผ ์ง€์›ํ•˜๋Š” ๋‹ค๋ฅธ ๋ชจ๋“ˆ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ํŠธ๋ฆฌ์‰์ดํ‚น์— ์œ ๋ฆฌํ•จ

๐Ÿ“Žย Lighthouse

: ๊ตฌ๊ธ€์—์„œ ๊ฐœ๋ฐœํ•œ ์˜คํ”ˆ์†Œ์Šค๋กœ์„œ ์›น ํŽ˜์ด์ง€์˜ ํ’ˆ์งˆ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์ž๋™ํ™” ํˆด
๐Ÿ‘‰ย ์„ฑ๋Šฅ, ์ ‘๊ทผ์„ฑ, PWA, SEO ๋“ฑ์„ ๊ฒ€์‚ฌํ•˜์—ฌ ์‚ฌ์šฉ์ž๋Š” ์–ด๋–ค ์›นํŽ˜์ด์ง€๋“  ํ’ˆ์งˆ ๊ฒ€์‚ฌ ๊ฐ€๋Šฅ

๐Ÿ”นย Chrome ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ ์‹คํ–‰

  1. ํฌ๋กฌ์œผ๋กœ ๊ฒ€์‚ฌํ•˜๊ณ  ์‹ถ์€ ํŽ˜์ด์ง€ url์— ์ ‘์†ํ•˜์—ฌ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ open

  2. lighthouse ํƒญ ํด๋ฆญ

  3. Analyze page load ํด๋ฆญํ•˜๊ณ  ๊ฒฐ๊ณผ ํ™•์ธํ•ด๋ณด๊ธฐ

๐Ÿ”นย Node CLI์—์„œ ์‹คํ–‰

  1. Lighthouse ์ „์—ญ ๋ชจ๋“ˆ๋กœ ์„ค์น˜

    $ npm install -g lighthouse
  2. ๊ฒ€์‚ฌ ์‹คํ–‰

    # Naver ์‚ฌ์ดํŠธ ๊ฒ€์‚ฌ ์‹คํ–‰
    $ lighthouse https://www.naver.com/
  3. ๋ชจ๋“  ์˜ต์…˜ ํ™•์ธ

    $ lighthouse --help

๐Ÿ”ถย Lighthouse ๋ถ„์„ ๊ฒฐ๊ณผ ํ•ญ๋ชฉ

  1. Performance: ์›น ์„ฑ๋Šฅ ์ธก์ •
    • ํ™”๋ฉด์— ์ฝ˜ํ…์ธ ๊ฐ€ ํ‘œ์‹œ๋˜๋Š”๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„
    • ํ‘œ์‹œ๋œ ํ›„ ์‚ฌ์šฉ์ž์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๊ธฐ๊นŒ์ง€์˜ ์‹œ๊ฐ„
    • ํ™”๋ฉด์— ๋ถˆ์•ˆ์ •ํ•œ ์š”์†Œ๋Š” ์—†๋Š”์ง€
  2. Accessibility: ์›น ํŽ˜์ด์ง€๊ฐ€ ์›น ์ ‘๊ทผ์„ฑ์„ ์ž˜ ๊ฐ–์ถ”๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธ
    • ๋Œ€์ฒด ํ…์ŠคํŠธ๋ฅผ ์ž˜ ์ž‘์„ฑํ–ˆ๋Š”์ง€
    • ๋ฐฐ๊ฒฝ์ƒ‰๊ณผ ์ฝ˜ํ…์ธ  ์ƒ‰์ƒ ๋Œ€๋น„๊ฐ€ ์ถฉ๋ถ„ํ•œ์ง€
    • ์ ์ ˆํ•œ WAI-ARIA ์†์„ฑ์„ ์‚ฌ์šฉํ–ˆ๋Š”์ง€
  3. Best Practices: ์›น ํŽ˜์ด์ง€๊ฐ€ ์›น ํ‘œ์ค€ ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธ
    • HTTPS ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๋Š”์ง€
    • ์ฝ˜์†”์ฐฝ์— ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋˜์ง€๋Š” ์•Š๋Š”์ง€
  4. SEO: ์›นํŽ˜์ด์ง€๊ฐ€ ๊ฒ€์ƒ‰ ์—”์ง„ ์ตœ์ ํ™”๊ฐ€ ์ž˜ ๋˜์–ด์žˆ๋Š”์ง€ ํ™•์ธ
    • ์•ฑ์˜ robots.txt๊ฐ€ ์œ ํšจํ•œ์ง€
    • <meta> ์š”์†Œ๋Š” ์ž˜ ์ž‘์„ฑ๋˜์–ด ์žˆ๋Š”์ง€
    • ํ…์ŠคํŠธ ํฌ๊ธฐ๊ฐ€ ์ฝ๊ธฐ์—” ๋ฌด๋ฆฌ ์—†๋Š”์ง€
  5. PWA (Progressive Web App): ํ•ด๋‹น ์›น ์‚ฌ์ดํŠธ๊ฐ€ ๋ชจ๋ฐ”์ผ ์•ฑ์œผ๋กœ์„œ๋„ ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธ (์ฒดํฌ๋ฆฌ์ŠคํŠธ๋กœ ํ™•์ธ)
    • ์•ฑ ์•„์ด์ฝ˜์„ ์ œ๊ณตํ•˜๋Š”์ง€
    • Splash ํ™”๋ฉด์ด ์žˆ๋Š”์ง€
    • ํ™”๋ฉด ํฌ๊ธฐ์— ๋งž๊ฒŒ ์ฝ˜ํ…์ธ ๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ๋ฐฐ์น˜ํ–ˆ๋Š”์ง€

๐Ÿ”ถย Metrics

  1. First Contentful Paint (FCP): ์„ฑ๋Šฅ(Performance) ์ง€ํ‘œ ์ถ”์  ๋ฉ”ํŠธ๋ฆญ
    • ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€ ์ ‘์†์‹œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ DOM ์ปจํ…์ธ  ์ฒซ๋ฒˆ์งธ ๋ถ€๋ถ„์„ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„ ์ธก์ •
      โ‡’ ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ์ง€ํ•˜๋Š” ํŽ˜์ด์ง€ ๋กœ๋”ฉ์†๋„ ์ธก์ • (1.8s โฌ‡๏ธย ๐Ÿ‘)

  2. Largest Contentful Paint (LCP): Viewport๋ฅผ ์ฐจ์ง€ํ•˜๋Š” ๊ฐ€์žฅ ํฐ ์ฝ˜ํ…์ธ ์˜ render ์‹œ๊ฐ„ ์ธก์ •
    ๐Ÿ‘‰ย ์ฃผ์š” ์ฝ˜ํ…์ธ ๊ฐ€ ์œ ์ €์—๊ฒŒ ๋ณด์ด๋Š” ์‹œ๊ฐ„ ๊ฐ€๋Š  ๊ฐ€๋Šฅ
    LCP time(in seconds)Color-coding
    0-2.5Green ๐ŸŸข (fast)
    2.5-4Orange ๐ŸŸ ย (moderate)
    Over 4Red ๐Ÿ”ด (slow)

  3. Speed Index: ์„ฑ๋Šฅ ์ง€ํ‘œ ์ถ”์  ๋ฉ”ํŠธ๋ฆญ
    ๐Ÿ‘‰ย ํŽ˜์ด์ง€ ๋กœ๋“œ ๋™์•ˆ ์–ผ๋งˆ๋‚˜ ๋นจ๋ฆฌ ์ปจํ…์ธ ๊ฐ€ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œ์‹œ๋˜๋Š”์ง€ ์ธก์ •
    Speen Index (in seconds)Color-coding
    0-3.4Green ๐ŸŸข (fast)
    3.4-5.8Orange ๐ŸŸ  (moderate)
    Over 5.8Red ๐Ÿ”ดย (slow)

  4. Time to interactive(TTI): ํŽ˜์ด์ง€๊ฐ€ ๋กœ๋“œ๋˜๋Š” ์‹œ์ ๋ถ€ํ„ฐ ์‚ฌ์šฉ์ž์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์ด ๊ฐ€๋Šฅํ•œ ์‹œ์ ๊นŒ์ง€์˜ ์‹œ๊ฐ„ ์ธก์ •
    ๐Ÿ‘‰ย ํŽ˜์ด์ง€๊ฐ€ ์™„์ „ํžˆ ์ƒํ˜ธ ์ž‘์šฉ ๊ฐ€๋Šฅํ•˜๊ธฐ๊นŒ์ง€์˜ ์‹œ๊ฐ„ ์ธก์ •
    [๊ธฐ์ค€]
    
    - ํŽ˜์ด์ง€์— FCP๋กœ ์ธก์ •๋œ ์ปจํ…์ธ  ํ‘œ์‹œ๋˜์–ด์•ผ ํ•จ
    - ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๊ฐ€์žฅ ์ž˜ ๋ณด์ด๋Š” ํŽ˜์ด์ง€์˜ ์—˜๋ฆฌ๋จผํŠธ์— ๋“ฑ๋ก
    - ํŽ˜์ด์ง€๊ฐ€ 0.05์ดˆ์•ˆ์— ์‚ฌ์šฉ์ž์˜ ์ƒํ˜ธ์ž‘์šฉ์— ์‘๋‹ต
    TTI metric (in seconds)Color-coding
    0-3.8Green ๐ŸŸขย (fast)
    3.8-7.3Orange ๐ŸŸ  (moderate)
    Over 7.3Red ๐Ÿ”ด (slow)

  5. Total Blocking Time(TBT): ํŽ˜์ด์ง€๊ฐ€ ์œ ์ €์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๊ธฐ๊นŒ์ง€์˜ ๋ง‰ํ˜€์žˆ๋Š” ์‹œ๊ฐ„ ์ธก์ •
    • FCP ~ TTI ์‚ฌ์ด์— ๊ธด ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…๋“ค์„ ๋ชจ๋‘ ๊ธฐ๋กํ•˜์—ฌ TBT ์ธก์ •

  6. Cumulative Layout Shift(CLS): ์‚ฌ์šฉ์ž์—๊ฒŒ ์ปจํ…์ธ ๊ฐ€ ํ™”๋ฉด์—์„œ ์–ผ๋งˆ๋‚˜ ๋งŽ์ด ์›€์ง์ด๋Š”์ง€(๋ถˆ์•ˆ์ •ํ•œ์ง€) ์ˆ˜์น˜ํ™”ํ•œ ์ง€ํ‘œ

โœ‹ย Opportunities ํ•ญ๋ชฉ์„ ํ™•์ธํ•˜๋ฉด ๊ฐ Metric๋ณ„ ๋ฌธ์ œ ํ™•์ธ ๊ฐ€๋Šฅ

๐Ÿ’ก Opportunities

Opportunities ํ•ญ๋ชฉ์„ ํ™•์ธํ•˜๋ฉด ๊ฐ Metric๋ณ„ ๋ฌธ์ œ ํ™•์ธ ๊ฐ€๋Šฅ!

๐Ÿ™Œ Naver ์›น์‚ฌ์ดํŠธ ํ™•์ธํ•ด๋ณด๊ธฐ

๐Ÿ”นย Server images in next-gen formats

: ์ด๋ฏธ์ง€ ํฌ๋งท์„ ๋งž์ถฐ์ค˜๐Ÿ™

ย ๐Ÿง™โœจย ํ•ด๊ฒฐ๋ฐฉ์•ˆ

  • ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๋Š” ์‚ฌ์ด์ฆˆ์™€ ์‹ค์ œ ์ด๋ฏธ์ง€ ์šฉ๋Ÿ‰ ์ผ์น˜ํ•˜๊ธฐ
  • ๊ทธ๋Ÿผ ์šฉ๋Ÿ‰์€ ์–ด๋–ป๊ฒŒ ์ค„์ด์ง€? โ†’ imgix์™€ ๊ฐ™์€ ์ด๋ฏธ์ง€ cdn ์‚ฌ์šฉํ•˜๊ธฐ

๐Ÿ”นย Reduce unused JavaScript

: ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” JavaScript ์ฝ”๋“œ๋ฅผ ์ค„์—ฌ์ค˜ ๐Ÿ™

โœ‹ย ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” JS ๋กœ๋“œ์‹œ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋Œ€์—ญํญ ์ฆ๊ฐ€, FCP ์ง€์—ฐ โ†’ ์ „์ฒด ํŽ˜์ด์ง€ ์„ฑ๋Šฅ ๋Š๋ ค์ง

ย ๐Ÿง™โœจย ํ•ด๊ฒฐ๋ฐฉ์•ˆ

  • Code Spliting(์ฝ”๋“œ ๋ถ„ํ• ) ์ ์šฉ
    • React.lazy() & Suspense๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง€๊ธˆ ๋‹น์žฅ ํ•„์š”ํ•œ ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ฉด ๋”ฐ๋กœ ๋ถ„๋ฆฌ์‹œํ‚ค๊ณ , ๋‚˜์ค‘์— ํ•„์š”ํ•  ๋•Œ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•˜๊ธฐ โ‡’ ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์†๋„ ๊ฐœ์„ !
  • dead coe ์ œ๊ฑฐ: ํ˜„์žฌ ํŽ˜์ด์ง€์—์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” JS ์ฝ”๋“œ ์ œ๊ฑฐ ๐Ÿ‘‰ย Tree Shaking ์‚ฌ์šฉํ•ด๋ณด๊ธฐ

๐Ÿ”นย Reduce unused CSS

: ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” 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) ||
              []
            );
          }, 
        }),
      ],
    };

๐Ÿ”นย Eliminate render-blocking resources

: ๋ Œ๋”๋ง์„ ๋ฐฉํ•ดํ•˜๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์ œ๊ฑฐํ•ด์ค˜๐Ÿ™

โœ‹ย Render blocking?
: ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์™ธ๋ถ€ ๋ฆฌ์†Œ์Šค๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ํŒŒ์‹ฑํ•˜๋Š” ๋™์•ˆ ํŽ˜์ด์ง€ ์ฝ˜ํ…์ธ ๋ฅผ ํŒŒ์‹ฑ/๋ Œ๋”๋งํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํŽ˜์ด์ง€ ํ‘œ์‹œ ์†๋„ ์ €ํ•˜ โฌ‡๏ธ

ย ๐Ÿง™โœจย ํ•ด๊ฒฐ๋ฐฉ์•ˆ

  • <link rel=โ€preloadโ€> ์ ์šฉ โ†’ CSS๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์š”์ฒญ

๐Ÿ”นย Avoid multiple page redirects

: ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€ ๋ฆฌ๋””๋ ‰์…˜์„ ํ”ผํ•ด์ค˜๐Ÿ™

โœ‹ย ๋ฆฌ๋””๋ ‰์…˜์€ ํŽ˜์ด์ง€ ๋กœ๋“œ ์ „์— ์ถ”๊ฐ€ ์ง€์—ฐ์„ ๋ฐœ์ƒ์‹œํ‚ด

ย ๐Ÿง™โœจย ํ•ด๊ฒฐ๋ฐฉ์•ˆ

  • ๋ฆฌ๋””๋ ‰์…˜์„ ์ตœ๋Œ€ํ•œ ํ”ผํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ด์•ผํ•˜์ง€๋งŒ ํ”ผํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ๋ชฉํ‘œ๋ฅผ ๊ฐ€๋Šฅํ•œ ํ•˜๋‚˜๋กœ ์ œํ•œํ•˜๊ธฐ
profile
FE developer

0๊ฐœ์˜ ๋Œ“๊ธ€