Skip to content

Latest commit

Β 

History

History
315 lines (208 loc) Β· 14.3 KB

performance-optimization.md

File metadata and controls

315 lines (208 loc) Β· 14.3 KB

μ„±λŠ₯ μ΅œμ ν™”

πŸ– λ ˆμ΄μ•„μ›ƒκ³Ό 리페인트

λΈŒλΌμš°μ € λ‘œλ”© κ³Όμ • 쀑 μŠ€νƒ€μΌ μ΄ν›„μ˜ κ³Όμ • (μŠ€νƒ€μΌ -> λ ˆμ΄μ•„μ›ƒ -> 페인트 -> ν•©μ„±)을 λ Œλ”λ§μ΄λΌκ³  ν•œλ‹€. 이 λ Œλ”λ§ 과정은 상황에 따라 λ°˜λ³΅ν•˜μ—¬ λ°œμƒν•  수 μžˆλ‹€.

λ ˆμ΄μ•„μ›ƒ

  • DOM이 μΆ”κ°€/μ‚­μ œλ˜κ±°λ‚˜, κΈ°ν•˜μ μΈ 영ν–₯(넓이, 높이, μœ„μΉ˜)을 μ£ΌλŠ” CSS 속성값을 λ³€κ²½λ˜λ©΄, λ Œλ” νŠΈλ¦¬λŠ” μž¬κ΅¬μ„±λœλ‹€.
  • λ ˆμ΄μ•„μ›ƒ 이후 κ³Όμ •λΆ€ν„° λ‹€μ‹œ μˆ˜ν–‰ν•˜λŠ” 것을 λ ˆμ΄μ•„μ›ƒ λ˜λŠ” λ¦¬ν”Œλ‘œμš°λΌκ³  ν•œλ‹€.
  • λ ˆμ΄μ•„μ›ƒμ€ ν™”λ©΄μ—μ„œμ˜ 전체 픽셀을 λ‹€μ‹œ 계산해야 ν•˜λ―€λ‘œ λΆ€ν•˜κ°€ 크닀. λ”°λΌμ„œ λΆˆν•„μš”ν•œ λ ˆμ΄μ•„μ›ƒμ΄ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ μ£Όμ˜ν•΄μ•Ό ν•œλ‹€.
  • κΈ°ν•˜μ  영ν–₯을 μ£ΌλŠ” css 속성값 : height, width, left, right, font-size, ...

리페인트

  • κΈ°ν•˜μ μΈ μš”μ†Œμ—λŠ” 영ν–₯을 주지 μ•ŠλŠ” CSS 속성값을 λ³€κ²½ν•˜λ©΄ λ ˆμ΄μ•„μ›ƒμ€ κ±΄λ„ˆλ›°κ³ , νŽ˜μΈνŠΈλΆ€ν„° μˆ˜ν–‰ν•˜κ²Œ λœλ‹€. 이λ₯Ό 리페인트라고 ν•œλ‹€.
  • 이미 κ³„μ‚°λœ 픽셀값을 μ΄μš©ν•˜μ—¬ 화면을 그리기 λ•Œλ¬Έμ—, λ ˆμ΄μ•„μ›ƒμ— λΉ„ν•΄ λΆ€ν•˜κ°€ 적닀.
  • κΈ°ν•˜μ  영ν–₯이 μ—†λŠ” css 속성값 : color, visibility, text-decoration, ...

λ¦¬ν”Œλ‘œμš°μ™€ λ¦¬νŽ˜μΈνŠΈμ— 영ν–₯을 μ£ΌλŠ” css 속성은 μ—¬κΈ°μ—μ„œ 확인할 수 μžˆλ‹€.

πŸ– μ›Ή νŽ˜μ΄μ§€ λ‘œλ”© μ΅œμ ν™”

✨ 블둝 λ¦¬μ†ŒμŠ€ μ΅œμ ν™”

νŒŒμ‹± 쀑 블둝 λ¦¬μ†ŒμŠ€κ°€ λ°œμƒν•  수 μžˆλŠ”λ°, css와 jsκ°€ 블둝 λ¦¬μ†ŒμŠ€μ— ν•΄λ‹Ήν•œλ‹€.

css μ΅œμ ν™”

  • CSSλŠ” 항상 HTML λ¬Έμ„œ μ΅œμƒλ‹¨μ— λ°°μΉ˜ν•œλ‹€.


    CSSOM νŠΈλ¦¬λŠ” CSSλ₯Ό λͺ¨λ‘ 해석해야 ꡬ성할 수 μžˆλ‹€. 즉, CSSOM νŠΈλ¦¬κ°€ κ΅¬μ„±λ˜μ§€ μ•ŠμœΌλ©΄, λ Œλ” νŠΈλ¦¬κ°€ λ§Œλ“€μ–΄μ§€μ§€ μ•Šκ³  λ Œλ”λ§μ΄ μ°¨λ‹¨λœλ‹€. λ Œλ”λ§μ΄ μ°¨λ‹¨λ˜μ§€ μ•Šλ„λ‘ HTML λ¬Έμ„œ μ΅œμƒλ‹¨μ— λ°°μΉ˜ν•œλ‹€.

<head>
  <link href="style.css" rel="stylesheet" />
</head>
  • νŠΉμ • μ‘°κ±΄μ—μ„œλ§Œ ν•„μš”ν•œ CSSκ°€ μžˆμ„ λ•Œ, λ―Έλ””μ–΄ 쿼리λ₯Ό μ‚¬μš©ν•œλ‹€.


    νŽ˜μ΄μ§€λ₯Ό μΈμ‡„ν•˜κ±°λ‚˜, 화면이 μ„Έλ‘œ λͺ¨λ“œμΌ κ²½μš°μ—λ§Œ μ‚¬μš©ν•˜λŠ” CSSκ°€ μžˆλ‹€λ©΄, ν•΄λ‹Ή μŠ€νƒ€μΌμ„ μ‚¬μš©ν•˜λŠ” κ²½μš°μ—λ§Œ λ‘œλ“œν•  수 μžˆλ„λ‘ media 속성을 λͺ…μ‹œν•˜μ—¬ μ‚¬μš©ν•œλ‹€.

<link href="style.css" rel="stylesheet" />
<link href="print.css" rel="stylesheet" media="print" />
<link href="portrait.css" rel="stylesheet" media="orientation:portrait" />
  • μ™ΈλΆ€ μŠ€νƒ€μΌμ‹œνŠΈλ₯Ό κ°€μ Έμ˜¬ λ•Œ @import μ‚¬μš©μ€ ν”Όν•œλ‹€.


    |@importλ₯Ό μ‚¬μš©ν•˜λ©΄, λΈŒλΌμš°μ €λŠ” μŠ€νƒ€μΌ μ‹œνŠΈλ₯Ό λ³‘λ ¬λ‘œ λ‹€μš΄λ‘œλ“œν•  수 μ—†μ–΄μ„œ, λ‘œλ“œ μ‹œκ°„μ΄ λŠ˜μ–΄λ‚  수 μžˆλ‹€.

/* foo.css */
@import url("bar.css")
  • λ•Œμ— 따라 λ‚΄λΆ€ μŠ€νƒ€μΌ μ‹œνŠΈλ₯Ό μ‚¬μš©ν•œλ‹€.


    μ™ΈλΆ€ μŠ€νƒ€μΌ μ‹œνŠΈλ₯Ό κ°€μ Έμ˜¬ λ•Œ λ°œμƒν•˜λŠ” μš”μ²­ 횟수λ₯Ό 쀄일 수 μžˆλ‹€. 단, λ‚΄λΆ€ μŠ€νƒ€μΌ μ‹œνŠΈλŠ” λ¦¬μ†ŒμŠ€ μΊμ‹œλ₯Ό μ‚¬μš©ν•  수 μ—†μœΌλ―€λ‘œ, ν•„μš”ν•œ κ²½μš°μ—λ§Œ μ‚¬μš©ν•œλ‹€.

<head>
  <style type="text/css">
    .wrapper {
      background-color: red;   
    }
  </style>
</head>

μžλ°”μŠ€ν¬λ¦½νŠΈ μ΅œμ ν™”

  • μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” HTML λ¬Έμ„œ μ΅œν•˜λ‹¨ (</body>직전)에 λ°°μΉ˜ν•œλ‹€.

    μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” DOMνŠΈλ¦¬μ™€ CSSOM트리λ₯Ό λ™μ μœΌλ‘œ λ³€κ²½ν•  수 μžˆμ–΄, HTML νŒŒμ‹±μ„ μ°¨λ‹¨ν•œλ‹€. λ˜ν•œ, script νƒœκ·Έ μ΄μ „κΉŒμ§€ μƒμ„±λœ DOMμ—λ§Œ μ ‘κ·Όν•  수 μžˆλ‹€.

    <script> νƒœκ·Έλ₯Ό λ§Œλ‚˜λ©΄, 슀크립트 싀행이 μ™„λ£Œλ  λ•ŒκΉŒμ§€ DOM 트리 생성이 μ€‘λ‹¨λœλ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ HTML νŒŒμ‹±μ„ μ°¨λ‹¨ν•˜μ§€ μ•Šκ²Œ ν•˜κΈ° μœ„ν•΄, HTML λ¬Έμ„œ μ΅œν•˜λ‹¨μ— λ°°μΉ˜ν•œλ‹€.

<body>
  <div>...</div>
  <div>...</div>
  <script src="app.js" type="text/javascript"></script>
</body>
  • <script>νƒœκ·Έμ— deferλ‚˜ async 속성을 λͺ…μ‹œν•œλ‹€.\

    defer, asyncλŠ” DOM νŠΈλ¦¬μ™€ CSSOM 트리λ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ² λ‹€λŠ” μ˜λ―Έμ΄λ―€λ‘œ, λΈŒλΌμš°μ €κ°€ νŒŒμ‹±μ„ λ©ˆμΆ”μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ, head에 μžλ°”μŠ€ν¬λ¦½νŠΈ νŒŒμΌμ„ 두어도 λœλ‹€. κ·ΈλŸ¬λ‚˜, μ§€μ›ν•˜λŠ” λΈŒλΌμš°μ €κ°€ ν•œμ •μ μ΄λ―€λ‘œ μ‚¬μš©μ— μœ μ˜ν•œλ‹€.\

    • defer

      • deferλŠ” 슀크립트λ₯Ό 'λ°±κ·ΈλΌμš΄λ“œ'μ—μ„œ λ‹€μš΄λ‘œλ“œν•œλ‹€. λ”°λΌμ„œ 슀크립트λ₯Ό λ‹€μš΄λ‘œλ“œ ν•˜λŠ” 쀑에도 HTML은 νŒŒμ‹±μ„ ν•  수 μžˆλ‹€.
      • defer 슀크립트 싀행은 νŽ˜μ΄μ§€ ꡬ성이 λλ‚ λ•ŒκΉŒμ§€ μ§€μ—°λœλ‹€.
      • DOMContentLoaded 이벀트 λ°œμƒ 전에 지연 μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λœλ‹€. λ”°λΌμ„œ λ‘˜μ˜ μ •ν™•ν•œ μˆœμ„œλŠ” μ˜ˆμΈ‘ν•  수 μ—†λ‹€.
      • deferλŠ” μ™ΈλΆ€ μŠ€ν¬λ¦½νŠΈμ—λ§Œ μœ νš¨ν•˜λ‹€.
      • 지연 μŠ€ν¬λ¦½νŠΈλŠ” HTML에 μΆ”κ°€λœ 순으둜 μ‹€ν–‰λœλ‹€.
    • async

      • async λ˜ν•œ 슀크립트λ₯Ό 'λ°±κ·ΈλΌμš΄λ“œ'μ—μ„œ λ‹€μš΄λ‘œλ“œν•œλ‹€. => HTML νŒŒμ‹±μ„ 막지 μ•ŠλŠ”λ‹€.
      • 단, async μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰μ€‘μ—λŠ” HTML νŒŒμ‹±μ„ λ©ˆμΆ˜λ‹€.
      • DOMContentLoaded μ΄λ²€νŠΈμ™€ 비동기 μŠ€ν¬λ¦½νŠΈλŠ” μ„œλ‘œλ₯Ό 기닀리지 μ•ŠλŠ”λ‹€.
      • λ‹€λ₯Έ μŠ€ν¬λ¦½νŠΈμ™€ 비동기 μŠ€ν¬λ¦½νŠΈλŠ” μ„œλ‘œλ₯Ό 기닀리지 μ•ŠλŠ”λ‹€.
      • νŽ˜μ΄μ§€μ— async μŠ€ν¬λ¦½νŠΈκ°€ μ—¬λŸ¬ 개 μžˆλŠ” 경우, κ·Έ μ‹€ν–‰ μˆœμ„œκ°€ 제각각이 λ©λ‹ˆλ‹€. 싀행은 λ‹€μš΄λ‘œλ“œκ°€ λλ‚œ 슀크립트 순으둜 μ§„ν–‰λœλ‹€.
<head>
    <script async src="https://google.com/analatics.js" type="text/javascript"></script>
  </head>
  <body>
    <div>...</div>
  </body>
</html>

✨ λ¦¬μ†ŒμŠ€ μš©λŸ‰ 쀄이기

μš©λŸ‰μ΄ 큰 λ¦¬μ†ŒμŠ€λ„ μ›Ή νŽ˜μ΄μ§€ λ‘œλ”© μ‹œκ°„μ„ 느리게 ν•œλ‹€. λΆˆν•„μš”ν•œ 데이터λ₯Ό μ œκ±°ν•˜κ³ , μ••μΆ•ν•˜μ—¬ μ‚¬μš©ν•˜λŠ” 것이 μ’‹λ‹€.

쀑볡 μ½”λ“œ μ œκ±°ν•˜κΈ°

자주 μ‚¬μš©λ˜λŠ” μ½”λ“œλŠ” utils.js 파일둜 정리해 μ‚¬μš©ν•œλ‹€.

만λŠ₯ μœ ν‹Έ μ‚¬μš© μ£Όμ˜ν•˜κΈ°

loadsh와 같은 만λŠ₯ μœ ν‹Έ 라이브러리λ₯Ό μ‚¬μš©ν•  λ•Œ, 일반적인 λ°©μ‹μœΌλ‘œ 가져와 μ‚¬μš©ν•˜λ©΄ μœ ν‹Έν•¨μˆ˜ 전체가 ν¬ν•¨λ˜μ–΄ μžλ°”μŠ€ν¬λ¦½νŠΈ 파일 μš©λŸ‰μ΄ 컀진닀. ν•„μš”ν•œ ν•¨μˆ˜λ§Œ λΆ€λΆ„μ μœΌλ‘œ κ°€μ Έμ™€μ„œ μš©λŸ‰μ΄ λŠ˜μ–΄λ‚˜μ§€ μ•Šλ„λ‘ ν•œλ‹€.

import array from 'lodash/array';
import object from 'lodash/fp/object';

array(...);
object(...);

HTML λ§ˆν¬μ—… μ΅œμ ν™”

λΆˆν•„μš”ν•œ λ§ˆν¬μ—…μ„ μ‚¬μš©ν•˜μ—¬ DOM νŠΈλ¦¬κ°€ μ»€μ§€λŠ” 것을 막고, HTML 파일 μš©λŸ‰μ΄ λŠ˜μ–΄λ‚˜μ§€ μ•Šλ„λ‘ ν•œλ‹€.

  • HTML은 νƒœκ·Έμ˜ 쀑첩을 μ΅œμ†Œν™”ν•˜μ—¬ λ‹¨μˆœν•˜κ²Œ κ΅¬μ„±ν•œλ‹€.
  • 곡백, 주석 등을 μ œκ±°ν•˜μ—¬ μ‚¬μš©ν•œλ‹€.

κ°„κ²°ν•œ CSS μ„ νƒμž μ‚¬μš©

  • μ„ νƒμžλŠ” μ΅œμ†Œν™”ν•˜μ—¬ μ‚¬μš©ν•œλ‹€.
  • 클래슀 μ„ νƒμžλ₯Ό μ‚¬μš©ν•˜λ©΄ μ€‘λ³΅λ˜λŠ” μŠ€νƒ€μΌμ„ λ¬Άμ–΄μ„œ μ²˜λ¦¬ν•œλ‹€.

μ••μΆ•ν•˜μ—¬ μ‚¬μš©ν•˜κΈ°

  • HTML, JS, CSS λͺ¨λ‘ μ••μΆ•ν•˜μ—¬ μ‚¬μš©
  • λΆˆν•„μš”ν•œ 주석과 곡백을 μ œκ±°ν•œ ν›„, λ‚œλ…ν™”ν•˜μ—¬ μ‚¬μš©ν•œλ‹€.
  • webpackκ³Ό 같은 ν”ŒλŸ¬κ·ΈμΈμœΌλ‘œ 이λ₯Ό μ²˜λ¦¬ν•  수 μžˆλ‹€.

πŸ– μ›Ή νŽ˜μ΄μ§€ λ Œλ”λ§ μ΅œμ ν™”

λ ˆμ΄μ•„μ›ƒ μ΅œμ ν™”

λ ˆμ΄μ•„μ›ƒμ€ DOM μš”μ†Œλ“€μ΄ 화면에 λ°°μΉ˜λ˜λŠ” 것을 κ²°μ •ν•˜λŠ” 계산 단계이닀. λ ˆμ΄μ•„μ›ƒμ€ 일일이 κ³„μ‚°ν•˜κ³ , μš”μ†Œκ°„ 관계λ₯Ό λͺ¨λ‘ νŒŒμ•…ν•΄μ•Ό ν•˜λ―€λ‘œ μ‹œκ°„μ΄ 였래 κ±Έλ¦¬λŠ” 과정이닀. λ ˆμ΄μ•„μ›ƒ μ΅œμ ν™”λ₯Ό 톡해 λ ˆμ΄μ•„μ›ƒμ— κ±Έλ¦¬λŠ” μ‹œκ°„μ„ μ΅œλŒ€ν•œ 단좕해야 ν•œλ‹€.

1. μžλ°”μŠ€ν¬λ¦½νŠΈ μ‹€ν–‰ μ΅œμ ν™”

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μ‹€ν–‰ μ‹œκ°„μ΄ κΈΈ 겨웅, ν•œ ν”„λ ˆμž„ μ²˜λ¦¬κ°€ 였래 κ±Έλ € λ Œλ”λ§ μ„±λŠ₯이 떨어진닀.

  • κ°•μ œ 동기 λ ˆμ΄μ•„μ›ƒ ν”Όν•˜κΈ°

    μ›λž˜ λ ˆμ΄μ•„μ›ƒμ€ λΉ„λ™κΈ°λ‘œ μΌμ–΄λ‚˜μ§€λ§Œ, νŠΉμ • μƒν™©μ—μ„œ λ™κΈ°μ μœΌλ‘œ λ ˆμ΄μ•„μ›ƒμ΄ λ°œμƒν•œλ‹€. 이λ₯Ό κ°•μ œ 동기 λ ˆμ΄μ•„μ›ƒμ΄λΌκ³  ν•˜λŠ”λ°, κ°•μ œ 동기 λ ˆμ΄μ•„μ›ƒμ€ JS의 μ‹€ν–‰ μ‹œκ°„μ„ λŠ˜μ–΄λ‚˜κ²Œ ν•˜λ―€λ‘œ μ£Όμ˜ν•΄μ•Ό ν•œλ‹€.

    μŠ€νƒ€μΌμ„ λ³€κ²½ν•œ λ‹€μŒ offsetHeight, offfsetTopκ³Ό 같은 κ³„μ‚°λœ 속성을 일을 λ•Œ, κ°•μ œ 동기 λ ˆμ΄μ•„μ›ƒμ΄ μˆ˜ν–‰λœλ‹€. 이와 같은 μ½”λ“œλ₯Ό μ΅œλŒ€ν•œ μ‚¬μš©ν•˜μ§€ μ•Šλ„λ‘ μ£Όμ˜ν•œλ‹€.

    const tabBtn = document.getElementById('tab_btn');

tabBtn.style.fontSize = '24px';
console.log(testBlock.offsetTop); // offsetTop 호좜 직전 λΈŒλΌμš°μ € λ‚΄λΆ€μ—μ„œλŠ” 동기 λ ˆμ΄μ•„μ›ƒμ΄ λ°œμƒν•œλ‹€.
tabBtn.style.margin = '10px';
// λ ˆμ΄μ•„μ›ƒ
  • λ ˆμ΄μ•„μ›ƒ μŠ€λ ˆμ‹± ν”Όν•˜κΈ°

    ν•œ ν”„λ ˆμž„ λ‚΄μ—μ„œ κ°•μ œ 동기 λ ˆμ΄μ•„μ›ƒμ΄ μ—°μ†μ μœΌλ‘œ λ°œμƒν•˜λ©΄, μ„±λŠ₯이 λ”μš± μ €ν•˜λœλ‹€. for문이 반볡될 λ•Œλ§ˆλ‹€ λ ˆμ΄μ•„μ›ƒμ΄ λ°œμƒν•˜λŠ” 것을 λ ˆμ΄μ•„μ›ƒ μŠ€λ ˆμ‹±μ΄λΌκ³  ν•œλ‹€. 반볡문 λ°–μ—μ„œ box μ—˜λ¦¬λ¨ΌνŠΈμ˜ λ„ˆλΉ„λ₯Ό μ½μ–΄μ˜€λ©΄ λ ˆμ΄μ•„μ›ƒ μŠ€λ ˆμ‹±μ„ ν”Όν•  수 μžˆλ‹€.

function resizeAllParagraphs() {
  const box = document.getElementById('box');
  const paragraphs = document.querySelectorAll('.paragraph');

  for (let i = 0; i < paragraphs.length; i += 1) {
    paragraphs[i].style.width = box.offsetWidth + 'px';
  }
}
// λ ˆμ΄μ•„μ›ƒ μŠ€λž˜μ‹±μ„ κ°œμ„ ν•œ μ½”λ“œ
function resizeAllParagraphs() {
  const box = document.getElementById('box');
  const paragraphs = document.querySelectorAll('.paragraph');
  const width = box.offsetWidth;

  for (let i = 0; i < paragraphs.length; i += 1) {
    paragraphs[i].style.width = width + 'px';
  }
}
  • κ°€λŠ₯ν•œ ν•˜μœ„ λ…Έλ“œμ˜ DOM을 μ‘°μž‘ν•˜κ³  μŠ€νƒ€μΌμ„ λ³€κ²½
    • DOM 트리의 μƒμœ„ λ…Έλ“œμ˜ μŠ€νƒ€μΌμ„ λ³€κ²½ν•˜λ©΄ ν•˜μœ„ λ…Έλ“œμ— λͺ¨λ‘ 영ν–₯을 λ―ΈμΉœλ‹€.
    • λ³€κ²½ λ²”μœ„λ₯Ό μ΅œμ†Œν™”ν•˜μ—¬ λ ˆμ΄μ•„μ›ƒμ˜ λ²”μœ„λ₯Ό 쀄인닀.
  • μˆ¨κ²¨μ§„ μ—˜λ¦¬λ¨ΌνŠΈ μˆ˜μ •
    • μˆ¨κ²¨μ§„ μƒνƒœμ—μ„œ μ—˜λ¦¬λ¨ΌνŠΈλ₯Ό λ³€κ²½ν•˜κ³  λ‹€μ‹œ 보이도둝 ν•˜μ—¬, λ ˆμ΄μ•„μ›ƒ λ°œμƒμ„ μ΅œλŒ€ν•œ 쀄인닀.
    • visibility: hidden은 보이지 μ•Šμ•„ λ¦¬νŽ˜μΈνŠΈλŠ” λ°œμƒν•˜μ§€ μ•Šμ§€λ§Œ, 곡간을 μ°¨μ§€ν•˜κΈ° λ•Œλ¬Έμ— λ ˆμ΄μ•„μ›ƒμ€ λ°œμƒν•œλ‹€.
    • display: none으둜 μˆ¨κ²¨μ§„ μ—˜λ¦¬λ¨ΌνŠΈλ₯Ό λ³€κ²½ν•˜λ©΄, λ ˆμ΄μ•„μ›ƒκ³Ό λ¦¬νŽ˜μΈνŠΈκ°€ λ°œμƒν•˜μ§€ μ•Šμ•„ μ„±λŠ₯에 μœ λ¦¬ν•˜λ‹€.

2. HTML, CSS μ΅œμ ν™”

  • cssκ·œμΉ™ 수 μ΅œμ ν™”

    • μ‚¬μš©ν•˜λŠ” κ·œμΉ™μ΄ μ μ„μˆ˜λ‘ 계산이 λΉ λ₯΄λ―€λ‘œ μ΅œμ†Œν™”ν•œλ‹€.
    • λ³΅μž‘ν•œ μ„ νƒμžλŠ” μŠ€νƒ€μΌ 계산에 λ§Žμ€ μ‹œκ°„μ΄ κ±Έλ¦¬λ―€λ‘œ ν”Όν•œλ‹€.
  • DOM 깊이 μ΅œμ†Œν™”

    DOMνŠΈλ¦¬κ°€ κΉŠμ„ 수둝, ν•˜λ‚˜μ˜ λ…Έλ“œμ— μžμ‹ λ…Έλ“œκ°€ λ§Žμ„μˆ˜λ‘ DOM νŠΈλ¦¬λŠ” 컀진닀. 그만큼 DOM을 λ³€κ²½ν–ˆμ„ λ•Œ, μ—…λ°μ΄νŠΈμ— ν•„μš”ν•œ 계산은 λ§Žμ•„μ§„λ‹€.

    • DOM이 μž‘κ³  κΉŠμ΄κ°€ μ–•μ„μˆ˜λ‘ 계산이빠λ₯΄λ‹€.
    • λΆˆν•„μš”ν•œ 래퍼 μ—˜λ¦¬λ¨ΌνŠΈλŠ” μ œκ±°ν•œλ‹€.

3. μ• λ‹ˆλ©”μ΄μ…˜ μ΅œμ ν™”

ν•œ ν”„λ ˆμž„ μ²˜λ¦¬κ°€ 16msλ‚΄λ‘œ μ™„λ£Œλ˜μ–΄μ•Ό λ Œλ”λ§μ‹œ λŠκΈ°λŠ” ν˜„μƒμ—†μ΄ μžμ—°μŠ€λŸ¬μš΄ λ Œλ”λ§μ„ λ§Œλ“€μ–΄λ‚Ό 수 μžˆλ‹€. μ• λ‹ˆλ©”μ΄μ…˜μ„ κ΅¬ν˜„ν•  λ•Œ, λ„€μ΄ν‹°λΈŒ μžλ°”μŠ€ν¬λ¦½νŠΈ APIλ₯Ό μ‚¬μš©ν•˜λŠ” 것보닀, CSS μ‚¬μš©μ„ ꢌμž₯ν•œλ‹€.

  • requestAnimationFrame() μ‚¬μš©

    • requestAnimationFrame APIλ₯Ό μ‚¬μš©ν•˜λ©΄ λΈŒλΌμš°μ €μ˜ ν”„λ ˆμž„ 속도(보톡 60fps)에 λ§žμΆ”μ–΄ μ• λ‹ˆλ©”μ΄μ…˜μ„ μ‹€ν–‰ν•  수 μžˆλ„λ‘ ν•΄μ€€λ‹€.
    • ν”„λ ˆμž„μ„ μ‹œμž‘ν•  λ•Œ ν˜ΈμΆœλ˜λ―€λ‘œ, μΌμ •ν•œ κ°„κ²©μœΌλ‘œ μ• λ‹ˆλ©”μ΄μ…˜μ„ μˆ˜ν–‰ν•  수 μžˆλŠ” μž₯점이 μžˆλ‹€.
    • ν˜„μž¬ νŽ˜μ΄μ§€κ°€ 보이지 μ•Šμ„ λ•ŒλŠ” μ½œλ°±ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜μ§€ μ•ŠμœΌλ―€λ‘œ λΆˆν•„μš”ν•œ λ™μž‘μ„ ν•˜μ§€ μ•ŠλŠ”λ‹€.
  • CSS μ• λ‹ˆλ©”μ΄μ…˜ μ‚¬μš©

    μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό μ‚¬μš©ν•œ μ• λ‹ˆλ©”μ΄μ…˜μ€ μ„±λŠ₯이 λ‚˜μ  수 μžˆλ‹€. CSS3 μ• λ‹ˆλ©”μ΄μ…˜μ„ μ‚¬μš©ν•˜λ©΄, λΈŒλΌμš°μ €κ°€ μ• λ‹ˆλ©”μ΄μ…˜μ„ μ²˜λ¦¬ν•˜λŠ”λ° μ΅œμ ν™”λ˜μ–΄ μžˆμ–΄μ„œ λΆ€λ“œλŸ¬μš΄ μ• λ‹ˆλ©”μ΄μ…˜μ„ κ΅¬ν˜„ν•  수 μžˆλ‹€.

    • position:absolute 처리

      μ• λ‹ˆλ©”μ΄μ…˜μ΄ μ£Όλ³€ μ˜μ—­μ— 영ν–₯을 주지 μ•Šλ„λ‘ μ£Όμ˜ν•΄μ•Ό ν•œλ‹€. position을 absoluteλ‚˜ fixed둜 μ„€μ •ν•˜μ—¬ μ£Όλ³€ λ ˆμ΄μ•„μ›ƒμ— 영ν–₯을 주지 μ•ŠλŠ”λ‹€.

    • transform μ‚¬μš©

      position, width, height와 같이 κΈ°ν•˜μ  λ³€ν™”λ₯Ό μœ λ°œν•˜λŠ” 속성을 λ³€κ²½ν•˜λ©΄ λ ˆμ΄μ•„μ›ƒμ΄ λ°œμƒν•œλ‹€. transform을 μ‚¬μš©ν•˜λŠ” μ—˜λ¦¬λ¨ΌνŠΈλŠ” λ ˆμ΄μ–΄λ‘œ λΆ„λ¦¬λ˜μ–΄, 영ν–₯λ°›λŠ” μ—˜λ¦¬λ¨ΌνŠΈκ°€ μ œν•œλ˜λ―€λ‘œ λ ˆμ΄μ•„μ›ƒκ³Ό 페인트λ₯Ό μ€„μΌμˆ˜ μžˆλ‹€. λ˜ν•œ ν•©μ„±λ§Œ λ°œμƒμ‹œν‚€κΈ° λ•Œλ¬Έμ— μ• λ‹ˆλ©”μ΄μ…˜ μ‚¬μš©μ‹œ λ Œλ”λ§ 속도가 ν–₯상될 수 μžˆλ‹€. ν•˜λ“œμ›¨μ–΄κ°€ 지원될 경우, GPUλ₯Ό μ‚¬μš©ν•  수 μžˆμ–΄ μ„±λŠ₯이 λΉ λ₯΄λ‹€.

4. DocumentFragment μ΄μš©ν•˜κΈ°

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ DOM κ°μ²΄λŠ” 연산을 μˆ˜ν–‰ν•  λ•Œλ§ˆλ‹€ DOM treeλΌλŠ” μžλ£Œκ΅¬μ‘°μ— μ ‘κ·Όν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μ„±λŠ₯을 μ €ν•˜μ‹œν‚€λŠ” 주된 μš”μΈ 쀑 ν•˜λ‚˜μ΄λ‹€. λ”°λΌμ„œ, μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μ„±λŠ₯을 μ΅œμ ν™”ν•˜κΈ° μœ„ν•΄μ„œλŠ” DOM 객체 접근을 μ΅œμ†Œν™”ν•˜λ„λ‘ μ½”λ“œλ₯Ό μž‘μ„±ν•΄μ•Ό ν•œλ‹€.

DocumentFragmentλŠ” 메인 DOM 트리의 일뢀가 λ˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ, DocumentFragmentλ₯Ό λ³€κ²½ν•˜μ—¬λ„ λ¬Έμ„œμ—λŠ” 영ν–₯이 μ—†μœΌλ©°, λ¦¬ν”Œλ‘œμš°λ„ μΌμœΌν‚€μ§€ μ•ŠλŠ”λ‹€.

DocumentFragmentλŠ” 주둜, createDocumentFragment()둜 DocumentFragmentλ₯Ό μƒμ„±ν•˜κ³ , κ·Έ μ•ˆμ—μ„œ DOM ν•˜μœ„ 트리λ₯Ό μ‘°λ¦½ν•œ λ‹€μŒ, DocumentFragmentλ₯Ό DOM νŠΈλ¦¬μ— μΆ”κ°€ν•˜λŠ” 것이닀. μ΄λ ‡κ²Œ ν•˜λ©΄ DocumentFragment의 λ…Έλ“œλ“€μ΄ DOM으둜 μ΄λ™λ˜κ³  빈 DocumentFragment만 λ‚¨κ²Œ λ©λ‹ˆλ‹€. 이λ₯Ό 톡해, μ—¬λŸ¬λ²ˆ λ¦¬ν”Œλ‘œμš°μ™€ λ Œλ”λ§μ΄ μΌμ–΄λ‚˜μ§€ μ•Šκ³ , 단 ν•œ 번만 λ¦¬ν”Œλ‘œμš°μ™€ λ Œλ”λ§μ΄ μΌμ–΄λ‚˜κ²Œ λœλ‹€.

  • μ΅œμ ν™” μ˜ˆμ‹œ
function addElements() {
    var target = document.getElementById('list');

    for (var i = 0; i < 100; i++) {
        var div = document.createElement('div');

        div.innerText = 'div';
        target.appendChild(div);
    }
}

μœ„μ˜ μ½”λ“œλŠ” DOM 객체에 100번 μ ‘κ·Όν•˜κ²Œ λœλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ μ œκ³΅ν•˜λŠ” DocumentFragment 객체λ₯Ό μ΄μš©ν•˜λ©΄ DOM 객체 접근을 μ΅œμ†Œν™”ν•  수 μžˆλ‹€.

function addElements() {
    var target = document.getElementById('list');
    var docFrag = document.createDocumentFragment();

    for (var i = 0; i < 100; i++) {
        var div = document.createElement('div');

        div.innerText = 'div';
        docFrag.appendChild(div);
    }
    target.appendChild(docFrag);
}

좜처