Tìm hiểu về V8 Engine trong Chrome và Node.js
Mở đầu
- Qua bài viết - Khám phá kiến trúc trình duyệt web: Các thành phần chính và chức năng, chúng ta đã biết được rằng
Javascript Engine
là một thành phần củaRuntime Enviroment
. Có nhiệm vụ phân tích, biên dịch và thực thi mã Javascript. V8
cũng là mộtJavascript Engine
được sử trong trình duyệtChrome
hayNode.js
.
Chrome hay Node.js được gọi là
Javascript Runtime Enviroment
.
V8 Engine: Các thành phần chính và chức năng
V8 Engine
có các thành phần cơ bản sau:
![]() |
---|
Sơ đồ về các thành phần của V8 Engine và cơ chế hoạt động |
1. Parser (Bộ phân tích cú pháp)
- Chuyển mã
JavaScript
từ chuỗi văn bản thành cấu trúc dữ liệu màV8 engine
có thể hiểu. - Quá trình này gồm 2 bước:
Bước | Chi tiết thực thi |
---|---|
1. Lexical Analysis (Tokenizer/Lexer) | Chia mã nguồn thành các token (như từ khóa, toán tử, biến...). |
2. Syntax Analysis (Parser) | Xây dựng AST (Abstract Syntax Tree - Cây cú pháp trừu tượng) từ các token. |
- Một ví dụ:
js
let x = 4 + 5;
AST
sau khi đã được chuyển đổi từ mã nguồn ở trên:
VariableDeclaration
├── Identifier (x)
├── Assignment (=)
├── BinaryExpression (+)
├── Number (4)
├── Number (5)
2. Ignition Interpreter (Trình thông dịch)
- Đọc
AST
và chuyển đổi thànhBytecode (dạng mã trung gian tối ưu)
sau đó thực thi các đoạn mãBytecode
này.
3. TurboFan (JIT Compiler)
- Nếu một đoạn mã chạy nhiều lần,
V8
xác định nó là mã quan trọng, cần được tối ưu hóa. TurboFan
sẽ biên dịch các đoạn mãBytecode
quan trọng này thànhmã máy tối ưu hóa
để tăng tốc thực thi.- Một số ví dụ về cách
TurboFan
chuyển đổi thànhmã máy tối ưu hóa
:
3.1. Nhúng trực tiếp các hàm nhỏ (Inlining)
- Nếu một hàm được gọi nhiều lần,
TurboFan
có thể nhúng toàn bộ mã của hàm vào nơi gọi thay vì thực hiện một lệnh gọi hàm tốn thời gian.
js
function add(a, b) {
return a + b;
}
function calc(x, y) {
return add(x, y) * 2;
}
- Trước tối ưu hóa:
calc(x, y)
phải gọiadd(x, y)
, gây quá tải (overhead). - Sau tối ưu hóa:
TurboFan
sẽ thayadd(x, y)
bằngx + y
, tránh gọi hàm.
3.2. Loại bỏ mã không cần thiết (Dead Code Elimination)
- Nếu một biến hoặc đoạn mã không ảnh hưởng đến kết quả,
TurboFan
sẽ loại bỏ nó.
js
function test() {
let x = 10;
let y = x + 5;
return x; // y không được sử dụng => loại bỏ y khi biên dịch
}
TurboFan
sẽ loại bỏy
, giúp mã chạy nhanh hơn.
3.3. Loop Unrolling (Tối ưu vòng lặp)
- Nếu vòng lặp có số lần lặp nhỏ và cố định,
TurboFan
có thể triển khai vòng lặp thành các lệnh tuần tự để tránh kiểm tra điều kiện lặp nhiều lần.
js
for (let i = 0; i < 3; i++) {
console.log(i);
}
Sau tối ưu hóa:
js
console.log(0);
console.log(1);
console.log(2);
4. Garbage Collector (Bộ thu gom rác)
- Dọn dẹp bộ nhớ bằng cách xóa các đối tượng không còn được sử dụng.
V8 Engine
dùng thuật toánMark-and-Sweep
:
Bước | Thực thi |
---|---|
Mark (Đánh dấu) | Xác định đối tượng nào vẫn đang được tham chiếu |
Sweep (Dọn dẹp) | Giải phóng bộ nhớ của đối tượng không còn tham chiếu |
ví dụ:
js
function genarate() {
let obj = { name: "Viblo" };
}
genarate(); // obj bị xóa khỏi bộ nhớ sau khi hàm genarate() kết thúc
5. Call Stack
Call Stack
là một cấu trúc dữ liệu dùng để quản lý lời gọi hàm trong quá trình thực thi mãJavaScript
.- Hoạt động theo nguyên tắc
LIFO (Last In, First Out)
- nghĩa là hàm nào vào sau thì sẽ được thực thi trước, sau đó hàm đã thực thi sẽ bị loại khỏi Stack. - Ví dụ:
js
function first() {
console.log("First function");
}
function second() {
first();
console.log("Second function");
}
function third() {
second();
console.log("Third function");
}
third();
Cách Call Stack hoạt động |
---|
1. third() được đưa vào Call Stack. |
2. second() được gọi trong third() , nên nó cũng được đẩy vào Stack. |
3. first() được gọi trong second() , nên nó cũng được đẩy vào Stack. |
4. console.log("First function") thực thi → "First function" in ra màn hình. |
5. first() hoàn thành, bị loại khỏi Call Stack. |
6. console.log("Second function") thực thi → "Second function" in ra. |
7. second() hoàn thành, bị loại khỏi Call Stack. |
8. console.log("Third function") thực thi → "Third function" in ra. |
9. third() hoàn thành, bị loại khỏi Call Stack. |
6. Heap Memory
Heap Memory
là vùng nhớ dùng để lưu trữ dữ liệu động như:Object, Array, Function
.- Giúp lưu trữ dữ liệu một cách lâu dài hơn.
js
let x = 1; // Lưu trong Stack (giá trị nguyên thủy)
let obj = { a: 1 }; // Lưu trong Heap (đối tượng)
Kết luận
- Qua bài viết, chúng ta đã tìm hiểu về
V8
mộtJavascript Engine
trong trình duyệtChrome
,Node.js
. - Nắm rõ được các khái niệm tổng quan về cấu tạo của
V8 Engine
cũng như vai trò, chức năng của từng thành phần. - Từ giờ khi viết Javascript, các bạn sẽ cảm thấy tự tin và có một cách nhìn rõ ràng hơn về cách ngôn ngữ này được xử lý và thực thi 🥰.
All rights reserved