JavaScript Engine
Chương 3: JavaScript Engine — Bên Trong Bộ Não Của JavaScript
1. Tổng Quan JavaScript Engine
JavaScript Engine là thành phần cốt lõi trong trình duyệt và các runtime khác (như Node.js) giúp chạy mã JavaScript. Nhiệm vụ của engine bao gồm:
Phân tích (parsing) mã nguồn JS
Biên dịch và tối ưu hoá mã
Quản lý bộ nhớ
Thực thi code
Các JavaScript Engine phổ biến:
V8 (Google): Chrome, Edge, Node.js
SpiderMonkey (Mozilla): Firefox
JavaScriptCore (Apple): Safari
Hermes (Meta): React Native
2. Stack, Heap và Memory Management
JavaScript chia vùng nhớ thành:
Call Stack: lưu trữ context khi hàm được gọi
Heap: vùng nhớ cho object, closure, array...
Object được lưu trên Heap vì chúng có kích thước thay đổi linh hoạt. Stack là vùng nhỏ nhanh, có cấu trúc LIFO.
3. Execution Context và Call Stack
Khi JavaScript thực thi:
Tạo Global Execution Context
Khi hàm được gọi, context mới được đẩy vào Call Stack
Khi hàm kết thúc, context được pop ra
Mỗi Execution Context gồm:
Variable environment (biến, closure)
Scope chain
this
4. Event Loop và Concurrency Model
JavaScript là ngôn ngữ single-threaded, nhưng hỗ trợ mô hình asynchronous non-blocking I/O nhờ vào Event Loop:
Call Stack thực thi synchronous code
Asynchronous code (đặt trong callback, promise) được đẩy vào Task Queue / Microtask Queue
Event Loop đẩy task vào stack khi stack rỗng
5. Microtask vs Macrotask
Macrotask Queue: setTimeout, setInterval, I/O
Microtask Queue: Promise.then, MutationObserver
Luôn xử lý Microtask Queue trước khi chuyển sang Macrotask tiếp theo.
console.log('Start');
setTimeout(() => console.log('Timeout'), 0);
Promise.resolve().then(() => console.log('Promise'));
console.log('End');
Output:
Start
End
Promise
Timeout
6. Just-In-Time Compilation (JIT)
JIT là kỹ thuật biên dịch trung gian:
JavaScript được parse -> bytecode
Bytecode được thực thi ngay (Interpreter)
Code hay dùng được tối ưu hoá và compiles sang machine code (via JIT Compiler)
Hai vòng JIT trong V8:
Ignition: interpreter tạo bytecode nhanh
TurboFan: optimizer tối ưu hoá mã runtime
7. Hidden Classes & Inline Caching
Hidden Classes:
Engine tạo hidden class khi object được khai báo
Khi các object cùng "hình dạng", chúng chia sẻ chung hidden class
Inline Caching:
Ghi nhớ kiểu truy cập properties để tăng tốc
function access(obj) {
return obj.count;
}
access({ count: 1 }); // Hot path
Việc thay đổi kiểu object runtime khiến optimizer mất hiệu quả (de-optimization).
8. Garbage Collection (GC)
JavaScript Engine sử dụng GC để tự động thu hồi bộ nhớ:
Thuật toán Mark-and-Sweep: đánh dấu object có thể truy cập được -> xóa những cái còn lại
let obj = { name: 'JS' };
obj = null; // Object bị thu gom
Cần tránh retain reference trong closure vô ý hoứng!
9. Tổng Quan Về Engine Phổ Biến
V8
Chrome, Node.js
JIT, Inline Cache
SpiderMonkey
Firefox
Debugging Tools
JavaScriptCore
Safari
Bytecode + JIT
Hermes
React Native
Tối ưu mobile
10. Kinh Nghiệm Tối Ưu Dựa Vào Engine
Tránh thay đổi structure object runtime (deopt)
Không trồn nhiều kiểu trong array
Dùng closure có kiểm soát
Biết rõ chi phí async / sync / memory
Kết Luận
Hiểu rõ cách Engine hoạt động là nền tảng quan trọng cho bất kỳ senior developer nào. Nó giúp bạn tối ưu hoá, debug và lý giải nhiều hành vi kỳ lạ trong JS.
Last updated