- vừa được xem lúc

[JavaScript nâng cao] JavaScript Engine và cách trình duyệt của chúng ta chạy JavaScript

0 0 11

Người đăng: Lam Vu Hoang

Theo Viblo Asia

JavaScript Engine giống như phiên dịch viên của chúng ta vậy, nó giúp chúng ta giao tiếp với máy tính.
Bạn và máy tính nói và hiểu 2 ngôn ngữ hoàn toàn khác nhau, bạn có thể hiểu tiếng Anh, Việt, Nga, vân vân. Nhưng máy tính chỉ hiểu 0 và 1. Vậy nên cần có một thứ đứng ở giữa giúp cho máy tính hiểu bạn yêu cầu nó làm gì.
Giả sử bạn muốn máy tính hiển thị cho bạn danh sách ảnh mấy em gái xinh chẳng hạn, và bạn chẳng có gì ngoài 1 file gaixinh.js. Bạn không thể nói với cái máy tính là "Ê, cho t xem ảnh mấy em gái xinh đê".
Lúc này JS Engine ra đời, nó giúp biên dịch file .js của bạn thành ngôn ngữ mà máy tính có thể hiểu.
Có rất nhiều loại JS Engine được viết bởi nhiều lập trình viên khác nhau. Bạn có thể xem danh sách các JS Engine này tại đây. Chúng được gọi là ECMAScript engine (lý do tại sao có cái tên này mình sẽ nói ở một bài khác). Engine mà chúng ta dùng phổ biến nhất hiện nay là V8 Engine của Google, được viết bằng C++, dùng trong Chrome của chúng ta. Vậy tại sao các lập trình viên lại viết ra các engine này?
Để nói về vấn đề này thì chúng ta cùng nhau quay lại những năm V8 Engine mới ra đời.
Trước khi Google cho ra mắt V8 Engine thì các JS Engine trước đó có thể nói khá là...cùi. Google lúc đó đang cho chạy Google Maps, mà các bạn biết thằng Google Maps xử lý rất nhiều logic phức tạp liên quan đến đồ hoạ như phóng to, thu nhỏ, chỉ đường,... Dẫn đến nó chạy khá là lag trên các trình duyệt kể cả Chrome (vì sử dụng JS Engine cùi bắp). Và thế là V8 Engine ra đời, mục đích đầu tiên là phục vụ cho thằng Google Maps chạy mượt, tiếp đến là các sản phẩm trong hệ sinh thái của Google thời đó cũng mượt theo đặc biệt là Google Search (sản phẩm chính của Google thời đó) → doanh thu của Google tăng.

Vậy thì JavaScript Engine hoạt động như thế nào?

Để hiểu được cách hoạt động của JS Engine, bạn sẽ cần nắm được các khái niệm sau:

Interpreter (thông dịch)

Hãy cùng nhau xem đoạn code sau:

function calculator(x, y) { return x + y;
}
for (let i = 0; i < 1000; i++) { calculator(30, 20)
}

Trình tự đoạn code này chạy sẽ là: Khởi tạo function calculator() → Chạy vào hàm for loop và chạy function calculator 1000 lần Các bạn sẽ thấy mỗi lần hàm calculator được chạy, nó sẽ tính lại x + y và trả về kết quả là 50. Và cái trình duyệt của chúng ta sẽ phải gánh gãy lưng vì cái hàm này chạy 1000 lần. Đương nhiên trong thực tế không có ai sử dụng vòng for như kia cả, nhưng vẫn sẽ có rất nhiều trường hợp tương tự. Interpreter là cơ chế chạy tuần tự của JS, nó sẽ đọc từng dòng và thực hiện tuần tự từ trên xuống, không có bất kỳ sự tối ưu nào. Vì thế mới có thêm một thứ được gọi là Compiler.

Compiler (biên dịch)

Compiler sẽ quét toàn bộ file js, do phải quét toàn bộ file js nên việc khởi chạy của thằng Compiler khá chậm, không nhanh như Interpreter. Compiler sẽ giúp tìm ra chỗ nào chưa được tối ưu và xử lý lại. Quay lại đoạn code bên trên, Compiler thấy hàm calculator chạy đến lần thứ 3 vẫn trả ra kết quả là 50, nên từ lần thứ 4 thay vì phải tính lại x + y thì nó trả luôn ra text là 50, vậy là từ những lần sau hàm calculator sẽ thực thi như này:

function calculator(x, y) { return 50;
}

Vậy là khỏi cần tính lại cho mệt. Giờ bạn thử đoán xem, JavaScript sử dụng thông dịch hay biên dịch?
Câu trả lời là cả 2. Thực ra bản chất JavaScript chỉ là ngôn ngữ thông dịch, nhưng nhờ có V8 Engine mà giờ đây JS như được buff thêm sức mạnh, 2 đứa kết hợp lại gọi là JIT Compiler (Just in time Compiler). Giả sử JS chỉ có Interpreter mà không có Compiler thì ra sao, nó sẽ rất chậm, giống như mình đã giải thích ở trên, việc chạy tuần tự mà không có sự tối ưu sẽ khiến trình duyệt của chúng ta rất vất vả khi xử lý nhiều tác vụ phức tạp.
Vậy tóm lại quy trình chạy của JS Engine là như nào?
image.png Khi trình duyệt của chúng ta nhận được 1 đoạn code JS, nó sẽ kiểm tra xem đoạn code đấy có hợp lệ không (có đúng là JavaScript không hay bạn gõ code C# vào đấy), parser (trình phân tích cú pháp) sẽ chạy từng dòng code để kiểm tra tính hợp lệ. Nếu code của bạn hợp lệ, parser sẽ tạo ra một cấu trúc dữ liệu gọi là AST (Abstract Syntax Tree), thứ sẽ dịch code của bạn sang mã máy (machine code). Code sau khi được dịch sẽ không còn là code JS nữa, nhưng bộ xử lý của máy tính đã có thể đọc được code này. Bạn có thể vào đây để xem ví dụ trực quan hơn: https://astexplorer.net/ Sau khi AST xử lý, nó sẽ chuyển đến Interpreter. Interpreter sẽ dịch chúng sang Bytecode image.png Trước khi đến được Compiler, code sẽ phải đi qua thứ được gọi là Profiler.
Profiler giống như một người QC vậy, nó sẽ theo dõi thằng Interpreter, chỗ nào chưa được tối ưu nó sẽ bảo với thằng Compiler là: "Chỗ này chưa ổn này cu, xử lý lại giúp tao cái". Và lúc này thằng Compiler vào việc. Compiler sau khi xử lý xong những đoạn code chưa được tối ưu thì tiếp tục dịch Bytecode sang Machine code để CPU của chúng ta có thể đọc được.
Và thế là xong, trình duyệt sẽ trả về kết quả mà chúng ta mong muốn từ đoạn code ta đưa vào.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Thủ thuật nhỏ để căn chỉnh image với object-fit

Chào các bạn,. Có lẽ trong hành trình code của các bạn thì không ít lần gặp vấn đề méo ảnh do fix cứng cả width, height của ảnh nhỉ? Hoặc kể cả khi bạn set value cho 1 thuộc tính weigth hoặc height còn thuộc tính còn lại để auto thì nhiều lúc ảnh cũng không được hiển thị toàn vẹn cho lắm.

0 0 49

- vừa được xem lúc

Tìm hiểu về CSS framework - Bulma

Mở đầu:. Mấy bữa nay đang lướt web thấy có giới thiệu framework bulma này, được mọi người giới thiệu gọn nhẹ và dễ sử dụng, nên mình mới tìm hiểu thử và hôm nay xin viết 1 bài viết giới thiệu sơ qua với các bạn.

0 0 36

- vừa được xem lúc

Một số mẹo vặt "hay ho" của ES6 có thể bạn chưa biết - Phần 4

Xin chào, ở 3 bài trước của series "Một số mẹo vặt "hay ho" của ES6", mình đã chia sẻ 1 số tips/tricks nhỏ với ES6, hy vọng ít nhiều nó sẽ có ích với các bạn khi áp dụng vào thực tế. Hôm nay, xin mời các bạn theo dõi phần 4 của series này.

0 0 46

- vừa được xem lúc

Tìm hiểu về Jest Mocks Test phía frontend

Giới thiệu. Chắc hẳn không ai phủ nhận rằng UnitTest là 1 phần quan trọng trong giai đoạn phát triển phần mềm, đảm bảo cho code được coverage tránh các bug không mong muốn.

0 0 36

- vừa được xem lúc

Convert từ SVG sang Icon Font như thế nào?

Chào các bạn. Như câu hỏi trên title của bài viết, hôm nay mình sẽ hướng dẫn các bạn cách convert 1 file svg 1 cách khá đơn giản và vô cùng tiện lợi cho các bạn. https://icomoon.io/app/#/select.

0 0 53

- vừa được xem lúc

Một vài thủ thuật làm việc với các dạng layout - Phần 4

. Chào mọi người, cũng đã lâu rồi mình không thấy nhau. Để tiếp tục với series's về các dạng layout hôm nay mình sẽ chia sẻ thêm một trick thú vị nữa về step layout.

0 0 46