πŸ‘¨β€πŸ’» Seungineer's GitHub Contribution

πŸ› οΈ Tool/FE

HTML 슀크립트 λ‘œλ”© μˆœμ„œμ˜ μ€‘μš”μ„±(#ν‹°μŠ€ν† λ¦¬ HTML에 script 적용이 μ•ˆ 될 λ•Œ)

seungineer = seungwoo + engineer 2024. 5. 23. 05:02

μ •κΈ€ λ™κΈ°λ“€μ˜ ν”Όλ“œλ°±μ„ λ°›μ•„μ„œ λΈ”λ‘œκ·Έλ₯Ό μˆ˜μ •ν•˜κ³ μž HTML νŽΈμ§‘μ„ ν•΄λ³΄μ•˜λ‹€. κΈ°μ‘΄μ—λŠ” μ‚¬μ΄λ“œλ°” HTML λ°•μŠ€μ— 있던 github contribution graphλ₯Ό λΈ”λ‘œκ·Έ μƒλ‹¨μœΌλ‘œ μ˜¬λ¦¬λŠ” 게 λͺ©μ !

μ‚¬μ΄λ“œλ°”μ˜ μš”μ†Œλ₯Ό λ‹¨μˆœνžˆ λΈ”λ‘œκ·Έ μƒλ‹¨μ˜ Header Div에 μœ„μΉ˜μ‹œν‚€λ©΄ λ˜κ² κ±°λ‹ˆ κ°„λ‹¨ν•˜κ²Œ μƒκ°ν–ˆλŠ”λ°, μ œλŒ€λ‘œ λ˜μ§€ μ•Šμ•˜λ‹€.

버그

μ‚¬μ΄λ“œλ°”μ— 있던 <script> ... </script>λ₯Ό κ·ΈλŒ€λ‘œ κ°€μ Έμ™€μ„œ <head> λ‚΄ μœ„μΉ˜μ‹œμΌ°μœΌλ‚˜ μŠ€ν¬λ¦½νŠΈκ°€ μ œλŒ€λ‘œ μž‘λ™ν•˜μ§€ μ•Šμ•˜λ‹€. μœ„ μ΄λ―Έμ§€μ²˜λŸΌ μš”μ†Œμ— κΈ°λ³Έ 문ꡬ둜 λ„£μ–΄λ‘” 'Loading data...'만 ν‘œμ‹œλ˜μ—ˆκ³ , scriptκ°€ μž‘λ™λ˜μ–΄ μš”μ†Œλ₯Ό μ•Œλ§žμ€ ν˜•νƒœλ‘œ μˆ˜μ •ν•΄μ€˜μ•Ό ν•˜λŠ”λ° κ·ΈλŸ¬μ§€ λͺ» ν•˜κ³  μžˆμ—ˆλ‹€.

디버그

이 문제의 원인은 슀크립트 λ‘œλ”© μˆœμ„œμ˜ λ¬Έμ œμ˜€λ‹€.

HTML λ¬Έμ„œλŠ” λΈŒλΌμš°μ €μ— μ˜ν•΄μ„œ νŒŒμ‹±λ˜μ–΄ DOM트리둜 λ³€ν™˜λœλ‹€. HTML λ¬Έμ„œλŠ” μœ„μ—μ„œ μ•„λž˜λ‘œ 순차적으둜 νŒŒμ‹± 되며, <script>λ₯Ό λ§Œλ‚˜κ²Œ 되면 νŒŒμ‹±μ„ μΌμ‹œ μ€‘μ§€ν•˜κ³ , ν•΄λ‹Ή 슀크립트λ₯Ό μ‹€ν–‰ν•œλ‹€. 이 μˆœμ„œλ₯Ό λͺ°λžμ–΄μ„œ 무지성(?)으둜 Head λ‚΄ μœ„μΉ˜μ‹œμΌ°μ—ˆλ‹€.

<script>
    GitHubCalendar(".calendar", "seungineer", { responsive: true, tooltips: false, global_stats: false}).then(function() {
    });
</script>

μž…λ ₯ν•˜κ³ μž ν–ˆλ˜ μŠ€ν¬λ¦½νŠΈλŠ” 'calendar' classλ₯Ό κ°–λŠ” μš”μ†Œλ₯Ό μ‘°μž‘ν•˜λŠ” 것이닀. 즉, Head λ‚΄ μŠ€ν¬λ¦½νŠΈκ°€ μœ„μΉ˜λ˜μ—ˆμ„ λ•ŒλŠ” νŒŒμ‹±μ΄ λ˜μ§€ μ•Šμ€ μƒνƒœμ—μ„œ μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λ˜μ–΄ μ–΄λ–€ 변화도 없이 λ„˜μ–΄κ°”μœΌλ©° νŒŒμ‹±μ΄ μ™„λ£Œλœ ν›„μ—λŠ” 슀크립트 νƒœκ·Έκ°€ μ‹€ν–‰λ˜μ§€ μ•Šμ•„μ„œ κΈ°λ³Έ 문ꡬ둜 λ„£μ–΄λ‘” 문자만 ν‘œμ‹œλœ 것이닀.

μ‹€μ œλ‘œ μœ„ μ΄λ―Έμ§€μ²˜λŸΌ </body> νƒœκ·Έ λ°”λ‘œ μ•žμ— <script> νƒœκ·Έλ₯Ό μœ„μΉ˜μ‹œν‚€μž μ •μƒμ μœΌλ‘œ calendar classλ₯Ό μˆ˜μ •ν•˜λŠ” 것을 확인할 수 μžˆμ—ˆλ‹€.


Script νƒœκ·Έ λ‘œλ”© μˆœμ„œ κ΄€λ ¨ κ°œλ…

슀크립트 νƒœκ·Έμ— λŒ€ν•΄ μ°Ύμ•„λ³Έ 김에 슀크립트 λ‘œλ”© μˆœμ„œκ°€ μ€‘μš”ν•œ μ΄μœ μ— λŒ€ν•΄ μ’€ 더 μ°Ύμ•„λ³΄μ•˜λ‹€.

  1. μ˜μ‘΄μ„± 문제 : B μŠ€ν¬λ¦½νŠΈμ—μ„œ A μŠ€ν¬λ¦½νŠΈμ— μ˜ν•΄ μ •μ˜λœ λ³€μˆ˜λ‚˜ ν•¨μˆ˜λ₯Ό ν•„μš”λ‘œ ν•  수 μžˆλ‹€. μ΄λ•Œ, A μŠ€ν¬λ¦½νŠΈκ°€ λ‘œλ“œλ˜μ§€ μ•Šμ€ μƒνƒœμ—μ„œ μ‹€ν–‰λœλ‹€λ©΄, μ—λŸ¬κ°€ λ°œμƒν•˜κ±°λ‚˜ μ˜€μž‘λ™ν•  수 μžˆλ‹€.
  2. DOM μš”μ†Œ : 였늘 κ²ͺμ—ˆλ˜ 문제둜, HTML λ¬Έμ„œμ˜ νŠΉμ • μš”μ†Œμ— μ‘°μž‘μ„ μ‹œλ„ν•˜κ±°λ‚˜, μŠ€ν¬λ¦½νŠΈκ°€ λ¬Έμ„œ 상단에 μœ„μΉ˜ν•΄ μžˆμ„ λ•Œ 자주 λ°œμƒν•  수 μžˆλŠ” λ¬Έμ œμ΄λ‹€.
  3. 동기식(Synchronous), 비동기식(Asynchronous)λ‘œλ”© : 동기식 λ‘œλ”©μ€ μœ„ μ‚¬λ‘€μ²˜λŸΌ μŠ€ν¬λ¦½νŠΈκ°€ μˆœμ„œλŒ€λ‘œ ν•˜λ‚˜μ”© μ‹€ν–‰λ˜λ©°, 슀크립트 λ‘œλ”© μ€‘μ—λŠ” HTML λ¬Έμ„œμ˜ λ‚˜λ¨Έμ§€ 뢀뢄이 λ‘œλ”©λ˜μ§€ μ•ŠλŠ”λ‹€. 비동기식 λ‘œλ”©μ€ μŠ€ν¬λ¦½νŠΈκ°€ backgroundμ—μ„œ λ‘œλ“œλ˜λ©°, νŽ˜μ΄μ§€μ˜ λ‹€λ₯Έ 뢀뢄이  λ‘œλ”©λ˜λŠ” 것을 λ°©ν•΄ν•˜μ§€ μ•ŠλŠ”λ‹€. κ·Έλ ‡λ‹€κ³  μ˜μ‘΄μ„± λ¬Έμ œκ°€ μ™„λ²½νžˆ μ²˜λ¦¬λ˜μ§€λŠ” μ•ŠλŠ”λ‹€.

이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œ

  1. 슀크립트 νƒœκ·Έ μœ„μΉ˜ μ‘°μ • : </body> νƒœκ·Έ λ°”λ‘œ μ•žμ— λ‘μ–΄μ„œ HTML λ¬Έμ„œκ°€ νŒŒμ‹±μ΄ λͺ¨λ‘ μ™„λ£Œλœ 후에 μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λ˜λ„λ‘ ν•˜μ—¬ DOM μš”μ†Œκ°€ λͺ¨λ‘ λ‘œλ“œλœ 후에 μ‹€ν–‰μ‹œν‚¨λ‹€.
  2. async, defer 속성 μ‚¬μš© : μŠ€ν¬λ¦½νŠΈκ°€ λΉ„λ™κΈ°μ μœΌλ‘œ λ‘œλ“œλ˜λ„λ‘ ν•œλ‹€.
    • async 속성: HTML λ¬Έμ„œμ˜ νŒŒμ‹± κ³Όμ •κ³Ό λ™μ‹œμ— μŠ€ν¬λ¦½νŠΈκ°€ λ‘œλ“œλ˜μ§€λ§Œ νŒŒμ‹± μ™„λ£Œ ν›„ μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λœλ‹€. λ‹€λ§Œ 슀크립트 μ‹€ν–‰ μˆœμ„œλŠ” 보μž₯λ˜μ§€ μ•ŠλŠ”λ‹€. 주둜 뢄석 툴과 같이 λ¬Έμ„œ νŒŒμ‹±κ³Ό μˆœμ„œμ— 크게 영ν–₯을 λ°›μ§€ μ•ŠλŠ” νƒœκ·Έμ— μ‚¬μš©ν•œλ‹€.
    • defer 속성: HTML λ¬Έμ„œμ˜ νŒŒμ‹± μ™„λ£Œ 후에 슀크립트 νƒœκ·Έκ°€ μ‹€ν–‰λœ μˆœμ„œλŒ€λ‘œ μ‹€ν–‰λœλ‹€. κ·Έλž˜μ„œ μ‹€ν–‰ μˆœμ„œκ°€ μ€‘μš”ν•œ μŠ€ν¬λ¦½νŠΈμ— μ ν•©ν•˜λ‹€.
  3. λͺ¨λ“ˆ λ‘œλ” λ˜λŠ” λ²ˆλ“€λŸ¬ μ‚¬μš©ν•˜κΈ° : μ›ΉνŒ©(webpack)μ΄λ‚˜ RequireJS 같은 λͺ¨λ“ˆμ„ μ‚¬μš©ν•˜μ—¬ 슀크립트의 μ˜μ‘΄μ„±μ„ 관리(μ˜λ„λœ μˆœμ„œλŒ€λ‘œ λ‘œλ“œ)ν•  수 μžˆλ‹€.

async, defer μ‚¬μš© μ˜ˆμ‹œ

<script async src="analytics.js"></script>

<script defer src="script1.js"></script>
<script defer src="script2.js"></script>