JavaScript Visualized: πŸš€βš™οΈ the JavaScript Engine

Posted on September 03, 2020Β  - Β 4 min read

reference: https://dev.to/lydiahallie/javascript-visualized-the-javascript-engine-4cdf

JavaScriptλŠ” λλ‚΄μ€λ‹ˆλ‹€ (μ €ν•œν… μ•„λ‹ˆμ§€λ§Œμš”), ν•˜μ§€λ§Œ 머신이 μ‹€μ œλ‘œ μ—¬λŸ¬λΆ„μ΄ μž‘μ„±ν•œ μ½”λ“œλ₯Ό μ–΄λ–»κ²Œ 이해할 수 μžˆμ„κΉŒμš”? JavaScript 개발자둜 μš°λ¦¬λŠ” 보톡 컴파일러λ₯Ό μš°λ¦¬κ°€ 직접 닀루지 μ•ŠμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜, JavaScript μ—”μ§„μ˜ κΈ°λ³Έ λ™μž‘μ„ μ•„λŠ” 것과, 인간 μΉœν™”μ μΈ JavaScript μ½”λ“œλ₯Ό μ–΄λ–»κ²Œ μ²˜λ¦¬ν•˜κ³  기계가 κ·Έκ±Έ μ΄ν•΄ν•˜λŠ”μ§€ μ•„λŠ” 것은 λΆ„λͺ…νžˆ 도움이 될 κ²ƒμž…λ‹ˆλ‹€!πŸ₯³

Note: 이 ν¬μŠ€νŠΈλŠ” Node.js와 ν¬λ‘œλ―Έμ›€ λΈŒλΌμš°μ € μ‚¬μš©λ˜λŠ” V8 엔진을 기반으둜 μž‘μ„±λ©λ‹ˆλ‹€.


HTML νŒŒμ„œκ°€ μ†ŒμŠ€λ₯Ό ν¬ν•¨ν•˜λŠ” scriptνƒœκ·Έλ₯Ό λ°œκ²¬ν•©λ‹ˆλ‹€. 이 μ†ŒμŠ€μ˜ μ½”λ“œλŠ” λ„€νŠΈμ›Œν¬, μΊμ‹œ λ˜λŠ” μ„€μΉ˜λœ μ„œλΉ„μŠ€ μ›Œμ»€λ‘œλΆ€ν„° λ‘œλ“œλ©λ‹ˆλ‹€. μš”μ²­λœ 슀크립트의 응닡은 λ°”μ΄νŠΈ 슀트림 디코더가 처리λ₯Ό ν•˜λŠ” λ°”μ΄νŠΈ μŠ€νŠΈλ¦Όμž…λ‹ˆλ‹€. λ°”μ΄νŠΈ 슀트림 λ””μ½”λ”λŠ” λ‹€μš΄λ‘œλ“œλœ λ°”μ΄νŠΈ μŠ€νŠΈλ¦Όμ„ λ””μ½”λ“œ ν•©λ‹ˆλ‹€.

1 || λ„€νŠΈμ›Œν¬, μΊμ‹œ λ˜λŠ” μ›Œμ»€λ‘œ λ„˜μ–΄μ˜¨ μŠ€ν¬λ¦½νŠΈλŠ” UTF-16 λ°”μ΄νŠΈ 슀트림으둜 λ‘œλ“œλ˜κ³ , λ°”μ΄νŠΈ 슀트림 λ””μ½”λ”λ‘œ μ „λ‹¬λ©λ‹ˆλ‹€.


λ°”μ΄νŠΈ 슀트림 λ””μ½”λ”λŠ” λ””μ½”λ“œλœ λ°”μ΄νŠΈ 슀트림으둜 토큰을 μƒμ„±ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ 0066은 f둜 λ””μ½”λ“œλ˜κ³ , 0075λŠ” u둜, 006eλŠ” n으둜, 0063은 c둜, 0074λŠ” t둜, 0069λŠ” i둜, 006fλŠ” o둜, 006eλŠ” n으둜 λ””μ½”λ“œλ˜λ©° 곡백이 λ”°λΌμ˜΅λ‹ˆλ‹€. function이 λ§Œλ“€μ–΄μ‘Œμ£ ! μ΄λŠ” JavaScriptμ—μ„œ μ˜ˆμ•½λœ ν‚€μ›Œλ“œκ³  μ΄λ ‡κ²Œ μƒμ„±λœ 토큰은 νŒŒμ„œμ—κ²Œ μ „λ‹¬λ©λ‹ˆλ‹€ (그리고 pre-parserλ₯Ό gifsμ—μ„œ 닀루진 μ•Šμ•˜μ§€λ§Œ λ‚˜μ€‘μ— μ„€λͺ…ν•  κ±°μ˜ˆμš”). λ‚˜λ¨Έμ§€ λ°”μ΄νŠΈ μŠ€νŠΈλ¦Όλ„ λ™μΌν•œ λ°©μ‹μœΌλ‘œ λ™μž‘ν•©λ‹ˆλ‹€.

2 || λ°”μ΄νŠΈ 슀트림 λ””μ½”λ”λŠ” λ°”μ΄νŠΈλ₯Ό ν† ν°μœΌλ‘œ λ””μ½”λ“œ ν•©λ‹ˆλ‹€. ν•΄λ‹Ή 토큰은 νŒŒμ„œμ— μ „λ‹¬λ©λ‹ˆλ‹€.


엔진은 2개의 νŒŒμ„œλ₯Ό μ΄μš©ν•©λ‹ˆλ‹€: pre-parser와 parserμ£ . μ›Ή μ‚¬μ΄νŠΈλ₯Ό λ‘œλ“œν•˜λŠ” μ‹œκ°„μ„ 쀄이기 μœ„ν•΄ 엔진은 μ¦‰μ‹œ ν•„μš”ν•˜μ§€ μ•Šμ€ μ½”λ“œμ— λŒ€ν•œ νŒŒμ‹±μ„ λ―Έλ£Ήλ‹ˆλ‹€. parserκ°€ μ¦‰μ‹œ ν•„μš”ν•œ μ½”λ“œλ₯Ό μ²˜λ¦¬ν•˜λŠ” λ™μ•ˆ pre-parserλŠ” λ‚˜μ€‘μ— μ‚¬μš©λ  μ½”λ“œλ“€μ„ μ²˜λ¦¬ν•©λ‹ˆλ‹€! νŠΉμ • ν•¨μˆ˜κ°€ μ‚¬μš©μžμ˜ λ²„νŠΌ 클릭에 μ˜ν•΄μ„œλ§Œ ν˜ΈμΆœλœλ‹€λ©΄, κ·Έ μ½”λ“œλŠ” μ›Ή μ‚¬μ΄νŠΈκ°€ λ‘œλ“œ 되자마자 μ¦‰μ‹œ μ»΄νŒŒμΌν•  ν•„μš”λŠ” μ—†λŠ”κ±°μ£ . 이후 μ‚¬μš©μžκ°€ λ²„νŠΌμ„ ν΄λ¦­ν•˜κ³  ν•΄λ‹Ή μ½”λ“œλ₯Ό μš”μ²­ν•˜λ©΄ νŒŒμ„œλ‘œ μ „λ‹¬λ©λ‹ˆλ‹€.

νŒŒμ„œλŠ” λ°”μ΄νŠΈ 슀트림 λ””μ½”λ”λ‘œλΆ€ν„° 받은 토큰을 기반으둜 λ…Έλ“œλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. 이런 λ…Έλ“œλ“€λ‘œ 좔상 ꡬ문 νŠΈλ¦¬κ°€ λ§Œλ“€μ–΄μ§‘λ‹ˆλ‹€. λ˜λŠ” AST(Abstract Syntax Tree)라고도 ν•©λ‹ˆλ‹€. 🌳

3 || νŒŒμ„œλŠ” 토큰을 기반으둜 λ…Έλ“œλ₯Ό μƒμ„±ν•˜κ³  좔상 ꡬ문 트리λ₯Ό λ§Œλ“­λ‹ˆλ‹€.


λ‹€μŒμ€ 인터프리터 μ°¨λ‘€μž…λ‹ˆλ‹€! μΈν„°ν”„λ¦¬ν„°λŠ” ASTλ₯Ό 따라가며 AST에 ν¬ν•¨λœ 정보λ₯Ό 기반으둜 λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. λ°”μ΄νŠΈ μ½”λ“œ 생성 μž‘μ—…μ΄ μ™„μ „νžˆ λλ‚˜λ©΄, ASTλŠ” μ§€μ›Œμ§€κ³ , λ©”λͺ¨λ¦¬ 곡간 λ˜ν•œ λΉ„μ›Œμ§‘λ‹ˆλ‹€. λ§ˆμ§€λ§‰μœΌλ‘œ 기계가 μ²˜λ¦¬ν•  수 μžˆλŠ” 뢀뢄이 μžˆμŠ΅λ‹ˆλ‹€! πŸŽ‰

4 || μΈν„°ν”„λ¦¬ν„°λŠ” ASTλ₯Ό 따라가며 λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.


λ°”μ΄νŠΈ μ½”λ“œλŠ” 이미 λΉ λ₯΄μ§€λ§Œ, 더 빨라질 수 μžˆμŠ΅λ‹ˆλ‹€. 이런 λ°”μ΄νŠΈ μ½”λ“œκ°€ 싀행될 λ•Œ 정보가 같이 μƒμ„±λ©λ‹ˆλ‹€. 이걸둜 νŠΉμ • λ™μž‘μ΄ 자주 λ°œμƒν•˜λŠ”μ§€μ— λŒ€ν•œ 여뢀와 μ‚¬μš©λœ λ°μ΄ν„°μ˜ νƒ€μž…μ„ 감지할 수 μžˆμŠ΅λ‹ˆλ‹€. μ—¬λŸ¬ 뢄은 ν•¨μˆ˜λ₯Ό ꡉμž₯히 많이 호좜 해왔을 κ²λ‹ˆλ‹€: 더 λΉ λ₯΄κ²Œ 싀행될 수 μžˆλ„λ‘ μ΅œμ ν™”λ₯Ό ν•  μ‹œκΈ°μž…λ‹ˆλ‹€! πŸƒπŸ½β€β™€οΈ

λ°”μ΄νŠΈ μ½”λ“œλŠ” μƒμ„±λœ νƒ€μž… ν”Όλ“œλ°±(type feedback)κ³Ό ν•¨κ»˜ μ΅œμ ν™” 컴파일러(optimizing compiler)μ—κ²Œ μ „λ‹¬λ©λ‹ˆλ‹€. μ΅œμ ν™” μ»΄νŒŒμΌλŸ¬λŠ” λ°”μ΄νŠΈ μ½”λ“œμ™€ νƒ€μž… ν”Όλ“œλ°±μ„ κ°–κ³  κ°€μž₯ μ΅œμ ν™”λœ 기계 μ½”λ“œλ₯Ό λ§Œλ“€μ–΄λƒ…λ‹ˆλ‹€. πŸš€

5 || μ΅œμ ν™” 컴파일러둜 λ°”μ΄νŠΈ μ½”λ“œμ™€ νƒ€μž… ν”Όλ“œλ°±μ„ 전달받아 κ°€μž₯ μ΅œμ ν™”λœ 기계 μ½”λ“œλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.


JavaScriptλŠ” 동적 νƒ€μž… μ–Έμ–΄λ‘œ λ°μ΄ν„°μ˜ μœ ν˜•μ΄ λŠμž„μ—†μ΄ λ³€ν™”ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” λ§Œμ•½ 맀번 νŠΉμ • 값이 가진 데이터 νƒ€μž…μ„ 확인해야 ν•œλ‹€λ©΄ JavaScript 엔진이 κ·Ήλ„λ‘œ 느렀질 수 μžˆλ‹€λŠ” κ±Έ λ§ν•˜μ£ .

μ½”λ“œλ₯Ό 해석할 λ•Œ μ†Œμš”λ˜λŠ” μ‹œκ°„μ„ 쀄이기 μœ„ν•΄ λ§Œλ“€μ–΄μ§„ μ΅œμ ν™”λœ 기계 μ½”λ“œλŠ” λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” λ™μ•ˆ 엔진이 이전에 봀던 κ²½μš°μ— λŒ€ν•΄μ„œλ§Œ 처리λ₯Ό ν•©λ‹ˆλ‹€. λ§Œμ•½ 같은 데이터 νƒ€μž…μ„ λ°˜ν™˜ν•˜λŠ” νŠΉμ • μ½”λ“œ 뢀뢄이 κ³„μ†ν•΄μ„œ λ°˜λ³΅λœλ‹€λ©΄, 처리 속도λ₯Ό 높이기 μœ„ν•΄ κ°„λ‹¨νžˆ μ΅œμ ν™”λœ 기계 μ½”λ“œλ₯Ό μž¬μ‚¬μš© ν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ JavaScriptλŠ” 동적 νƒ€μž…μ΄κΈ° λ•Œλ¬Έμ—, 같은 μ½”λ“œ λΆ€λΆ„μ—μ„œ κ°‘μžκΈ° λ‹€λ₯Έ νƒ€μž…μ˜ 데이터가 λ°˜ν™˜λ˜λŠ” 일이 λ°œμƒν•  μˆ˜λ„ 있죠. 그런 일이 λ°œμƒν•œλ‹€λ©΄, λ¨Έμ‹  μ½”λ“œλŠ” μ΅œμ ν™”λ₯Ό μ·¨μ†Œν•˜κ³ , 엔진은 λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μƒμ„±ν•˜λŠ” λ‹¨κ³„λ‘œ λ˜λŒμ•„ κ°‘λ‹ˆλ‹€.

νŠΉμ •ν•œ ν•¨μˆ˜κ°€ 100번 호좜이 λ˜μ—ˆκ³  μ§€κΈ‰κΉŒμ§€ 항상 λ™μΌν•œ 값을 λ°˜ν™˜ν–ˆλ‹€κ³  해보죠. μ΄λŠ” 101번째 ν˜ΈμΆœμ—μ„œλ„ ν•΄λ‹Ή 값을 λ°˜ν™˜ν•  것이라고 κ°€μ •ν•  수 μžˆμ„κ±°μ˜ˆμš”.

μ•„λž˜μ™€ 같은 sum ν•¨μˆ˜κ°€ μžˆλ‹€κ³  ν•©λ‹ˆλ‹€. μ§€κΈˆκΉŒμ§€λŠ” 항상 μˆ«μžκ°’μΈ 인수둜 호좜 λ˜μ–΄μ™”μŠ΅λ‹ˆλ‹€:

the javascript engine 6

이건 숫자 3을 λ°˜ν™˜ν•©λ‹ˆλ‹€! λ‹€μŒ 번 호좜 μ‹œμ—λ„, 두 개의 숫자 κ°’μœΌλ‘œ ν˜ΈμΆœν•  거라고 κ°€μ •ν•  수 있겠죠.

λ§Œμ•½ 그게 사싀 이라면, 동적 νƒ€μž…μ— λŒ€ν•œ μ‘°νšŒκ°€ ν•„μš” 없이 μ΅œμ ν™”λœ 기계 μ½”λ“œλ₯Ό μž¬μ‚¬μš©ν•˜κΈ°λ§Œ ν•˜λ©΄ λ©λ‹ˆλ‹€. 그게 μ•„λ‹ˆλΌ 가정이 ν‹€λ Έλ‹€λ©΄, μ΅œμ ν™”λœ 기계 μ½”λ“œ λŒ€μ‹  μ›λž˜μ˜ λ°”μ΄νŠΈ μ½”λ“œλ‘œ 되돌릴 κ²λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, λ‹€μŒ ν˜ΈμΆœμ—μ„œ, 숫자 λŒ€μ‹  λ¬Έμžμ—΄μ„ μ „λ‹¬ν–ˆλ‹€κ³  해보죠. JavaScriptλŠ” 동적 νƒ€μž…μ΄κΈ° λ•Œλ¬Έμ— μ–΄λ–€ μ—λŸ¬ 없이도 μ²˜λ¦¬κ°€ κ°€λŠ₯ν•©λ‹ˆλ‹€!

https://res.cloudinary.com/practicaldev/image/fetch/s--GtrihoCc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zugnjsg813urbj6vr4iy.png

즉, 숫자 2κ°€ λ¬Έμžμ—΄λ‘œ λ³€ν™˜λ˜κ³  ν•¨μˆ˜λŠ” λ¬Έμžμ—΄ "12"λ₯Ό λ°˜ν™˜ν•  κ±°λΌλŠ” 말이죠. μ΄λ ‡κ²Œ 되면 ν•΄μ„λœ λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” λ‹¨κ³„λ‘œ λ˜λŒμ•„κ°€κ³  νƒ€μž… ν”Όλ“œλ°±μ„ κ°±μ‹ ν•˜κ²Œ λ©λ‹ˆλ‹€.


이번 ν¬μŠ€νŠΈκ°€ 도움이 λ˜μ…¨κΈΈ λ°”λžλ‹ˆλ‹€! 😊 λ¬Όλ‘ , 이번 ν¬μŠ€νŠΈμ— 닀루지 λͺ»ν•œ μ—”μ§„μ˜ λ‚˜λ¨Έμ§€ λΆ€λΆ„λ“€(JavaScript Heap, Call Stack λ“±)도 많이 μžˆμŠ΅λ‹ˆλ‹€λ§Œ λ‚˜μ€‘μ— 닀루도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€! JavaScript의 내뢀에 관심이 μžˆμœΌμ‹œλ‹€λ©΄ V8은 μ˜€ν”ˆ μ†ŒμŠ€μ΄κΈ° λ•Œλ¬Έμ— λ‚΄λΆ€ λ™μž‘μ— λŒ€ν•œ 쒋은 λ¬Έμ„œκ°€ μžˆμœΌλ―€λ‘œ ν•΄λ‹Ή λ¬Έμ„œλ₯Ό 쑰사해 λ³΄μ‹œλŠ” κ±Έ κΆŒν•΄λ“œλ €μš”! πŸ€–