August 3, 2025

πŸ’£ 폴리필(polyfill)을 κ³Όλ„ν•˜κ²Œ μ‚¬μš©ν•œ λ²ˆλ“€ λΉ„λŒ€ν™”: 초기 λ‘œλ”© μ§€μ—°κ³Ό μ‚¬μš©μž κ²½ν—˜ μ €ν•˜

JavaScript
μ„±λŠ₯
μ›Ήν‘œμ€€
λΉŒλ“œ&λ²ˆλ“€λ§
ν˜Έν™˜μ„±
React
UX

Summary

λͺ¨λ“  λΈŒλΌμš°μ €λ₯Ό μ§€μ›ν•˜κΈ° μœ„ν•΄ 폴리필을 λ¬΄λΆ„λ³„ν•˜κ²Œ μ μš©ν•˜λ©΄ λ²ˆλ“€ 크기가 μ¦κ°€ν•˜κ³  μ„±λŠ₯이 μ €ν•˜λ©λ‹ˆλ‹€. Browserslist, 동적 폴리필 λ‘œλ”©, μ½”λ“œ 뢄할을 톡해 ν•„μš”ν•œ ν΄λ¦¬ν•„λ§Œ μ„ λ³„μ μœΌλ‘œ μ μš©ν•˜μ—¬ 졜적의 μ‚¬μš©μž κ²½ν—˜μ„ μ œκ³΅ν•΄μ•Ό ν•©λ‹ˆλ‹€.

Why Wrong?

μ΅œμ‹  JavaScript κΈ°λŠ₯을 κ΄‘λ²”μœ„ν•˜κ²Œ μ‚¬μš©ν•˜λ©΄μ„œ κ΅¬ν˜• λΈŒλΌμš°μ €λ₯Ό μ§€μ›ν•˜κΈ° μœ„ν•΄ λͺ¨λ“  κΈ°λŠ₯을 ν΄λ¦¬ν•„ν•˜λ©΄ λ²ˆλ“€ 크기가 κΈ°ν•˜κΈ‰μˆ˜μ μœΌλ‘œ μ¦κ°€ν•©λ‹ˆλ‹€. λΆˆν•„μš”ν•œ 폴리필은 초기 λ‘œλ”© μ‹œκ°„μ„ μ§€μ—°μ‹œν‚€κ³ , μ‚¬μš©μž κ²½ν—˜μ„ μ €ν•˜μ‹œν‚€λ©°, 특히 저사양 κΈ°κΈ°λ‚˜ 느린 λ„€νŠΈμ›Œν¬ ν™˜κ²½μ—μ„œ λ”μš± μ‹¬κ°ν•œ 문제λ₯Ό μ•ΌκΈ°ν•©λ‹ˆλ‹€. 핡심은 ν•„μš”ν•œ ν΄λ¦¬ν•„λ§Œ μ„ λ³„μ μœΌλ‘œ μ μš©ν•˜κ³ , μ΅œμ‹  λΈŒλΌμš°μ €μ—μ„œλŠ” 폴리필을 μ œκ±°ν•˜μ—¬ 졜적의 μ„±λŠ₯을 μœ μ§€ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

How to Fix?

  1. Targeted Polyfilling: Babel의 useBuiltIns μ˜΅μ…˜κ³Ό Browserslistλ₯Ό μ‚¬μš©ν•˜μ—¬ μ‹€μ œ ν•„μš”ν•œ ν΄λ¦¬ν•„λ§Œ ν¬ν•¨ν•˜λ„λ‘ μ„€μ •ν•©λ‹ˆλ‹€. BrowserslistλŠ” ν”„λ‘œμ νŠΈμ—μ„œ 지원해야 ν•˜λŠ” λΈŒλΌμš°μ € λ²”μœ„λ₯Ό μ •μ˜ν•˜κ³ , Babel은 이λ₯Ό 기반으둜 ν•„μš”ν•œ ν΄λ¦¬ν•„λ§Œ μžλ™μœΌλ‘œ μΆ”κ°€ν•©λ‹ˆλ‹€.
  2. Dynamic Polyfill Loading: Intersection Observer APIλ‚˜ User-Agent λ¬Έμžμ—΄μ„ μ‚¬μš©ν•˜μ—¬ λΈŒλΌμš°μ € κΈ°λŠ₯을 κ°μ§€ν•˜κ³ , ν•„μš”ν•œ κ²½μš°μ—λ§Œ 폴리필을 λ™μ μœΌλ‘œ λ‘œλ”©ν•©λ‹ˆλ‹€. polyfill.io와 같은 μ„œλΉ„μŠ€λ₯Ό μ‚¬μš©ν•˜μ—¬ CDN을 톡해 폴리필을 μ œκ³΅ν•˜κ³ , λΈŒλΌμš°μ €λ³„λ‘œ μ΅œμ ν™”λœ 폴리필 μ„ΈνŠΈλ₯Ό μ œκ³΅ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
  3. Modern Syntax Transpilation: μ΅œμ‹  JavaScript 문법(예: ES modules)을 μ‚¬μš©ν•˜μ—¬ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ³ , Babelκ³Ό 같은 트랜슀파일러λ₯Ό μ‚¬μš©ν•˜μ—¬ κ΅¬ν˜• λΈŒλΌμš°μ €μ—μ„œ μ‹€ν–‰ κ°€λŠ₯ν•œ μ½”λ“œλ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€. μ΄λ•Œ, μ΅œμ‹  λΈŒλΌμš°μ €λ₯Ό μœ„ν•œ μ½”λ“œλŠ” κ°€λŠ₯ν•œ ν•œ λ³€ν™˜μ„ μ΅œμ†Œν™”ν•˜μ—¬ μ„±λŠ₯을 μ΅œμ ν™”ν•©λ‹ˆλ‹€.
  4. Code Splitting: μ½”λ“œλ₯Ό μ—¬λŸ¬ 청크둜 λΆ„ν• ν•˜κ³ , 초기 λ‘œλ”©μ— ν•„μš”ν•œ μ½”λ“œλ§Œ λ¨Όμ € λ‘œλ”©ν•©λ‹ˆλ‹€. 폴리필 κ΄€λ ¨ μ½”λ“œλ₯Ό λ³„λ„μ˜ 청크둜 λΆ„λ¦¬ν•˜μ—¬ ν•„μš”ν•œ κ²½μš°μ—λ§Œ λ‘œλ”©ν•˜λ©΄ 초기 λ‘œλ”© μ‹œκ°„μ„ 단좕할 수 μžˆμŠ΅λ‹ˆλ‹€.

Before Code (Bad)

// babel.config.js
module.exports = {
  presets: [
    ['@babel/preset-env', {
      useBuiltIns: 'usage', // λͺ¨λ“  폴리필 포함
      corejs: 3,
      targets: '> 0.25%, not dead' // λͺ¨λ“  λΈŒλΌμš°μ € 지원
    }]
  ]
};

// index.js
const promise = Promise.resolve(123);
const array = [1, 2, 3].includes(2);

// ... λ‚˜λ¨Έμ§€ μ½”λ“œ

After Code (Good)

// babel.config.js
module.exports = {
  presets: [
    ['@babel/preset-env', {
      useBuiltIns: 'usage', // ν•„μš”ν•œ ν΄λ¦¬ν•„λ§Œ 포함
      corejs: 3,
      targets: {
        chrome: '79', // νŠΉμ • λΈŒλΌμš°μ € λ²„μ „λ§Œ 지원
        firefox: '72',
        safari: '13'
      }
    }]
  ]
};

// index.js
const promise = Promise.resolve(123);
const array = [1, 2, 3].includes(2);

// ... λ‚˜λ¨Έμ§€ μ½”λ“œ
```

```javascript
// 동적 폴리필 λ‘œλ”© μ˜ˆμ‹œ
if (!('IntersectionObserver' in window)) {
  import('intersection-observer').then(() => {
    // Intersection Observerλ₯Ό μ‚¬μš©ν•˜λŠ” μ½”λ“œ
  });
}

You Might Also Like

Babel의 `useBuiltIns` μ˜΅μ…˜μ€ Browserslist와 ν•¨κ»˜ μ‚¬μš©λ˜μ–΄ ν•„μš”ν•œ ν΄λ¦¬ν•„λ§Œ μžλ™μœΌλ‘œ ν¬ν•¨ν•˜λ„λ‘ μ„€μ •ν•˜λŠ” 방법을 μ œκ³΅ν•©λ‹ˆλ‹€. μ΄λŠ” λ²ˆλ“€ 크기λ₯Ό μ΅œμ ν™”ν•˜κ³  λΆˆν•„μš”ν•œ 폴리필을 μ œκ±°ν•˜λŠ” 데 μ€‘μš”ν•©λ‹ˆλ‹€.
https://babeljs.io/docs/babel-preset-env#usebuiltins
BrowserslistλŠ” ν”„λ‘œμ νŠΈμ—μ„œ 지원해야 ν•˜λŠ” λΈŒλΌμš°μ € λ²”μœ„λ₯Ό μ •μ˜ν•˜κ³ , Babelκ³Ό PostCSS와 같은 도ꡬ가 이λ₯Ό 기반으둜 μ½”λ“œλ₯Ό μ΅œμ ν™”ν•˜λ„λ‘ μ§€μ›ν•©λ‹ˆλ‹€. μ΄λŠ” 폴리필 및 트랜슀파일링 μ „λž΅μ„ μ‘°μ •ν•˜λŠ” 데 핡심적인 역할을 ν•©λ‹ˆλ‹€.
https://github.com/browserslist/browserslist
polyfill.ioλŠ” User-Agent 헀더λ₯Ό 기반으둜 ν•„μš”ν•œ ν΄λ¦¬ν•„λ§Œ μ œκ³΅ν•˜λŠ” μ„œλΉ„μŠ€μž…λ‹ˆλ‹€. μ΄λŠ” λΈŒλΌμš°μ €λ³„λ‘œ μ΅œμ ν™”λœ 폴리필 μ„ΈνŠΈλ₯Ό μ œκ³΅ν•˜μ—¬ λ²ˆλ“€ 크기λ₯Ό 쀄이고 μ„±λŠ₯을 ν–₯μƒμ‹œν‚€λŠ” 데 도움이 λ©λ‹ˆλ‹€.
https://polyfill.io/