Hướng dẫn understand what javascript can do in browser - hiểu javascript có thể làm gì trong trình duyệt

Ảnh của Markus Spiske trên unplash

Dưới đây là phần thứ hai trong cách trình duyệt hiển thị trang web của bạn, trong phần đầu tiên, chúng tôi tập trung vào HTML & CSS trong phần này, chúng tôi sẽ tập trung vào JavaScript.

Đây là phần đầu tiên nếu bạn bỏ lỡ nó.

Khi bạn truy cập một trang web bằng cách sử dụng bất kỳ trình duyệt nào. Trình duyệt của bạn thực hiện một HTTP Nhận yêu cầu tải trang HTML bao gồm một thẻ. Trình duyệt thực hiện một yêu cầu riêng để tải tập lệnh này.

Trình duyệt của bạn nhận được mã JS được thu nhỏ từ máy chủ. Công việc chính cho động cơ JavaScript bắt đầu ở đây.

Công cụ JavaScript có trách nhiệm xử lý mã JavaScript, các trình duyệt khác nhau có các động cơ JavaScript khác nhau.

Trong suốt bài viết này, tôi sẽ tập trung vào động cơ V8. V8 được sử dụng trong trình duyệt Google Chrome và nó cũng là công cụ chính cho NodeJS.

Đây là một cái nhìn tổng quan về các bước mà chúng tôi đang thực hiện bất cứ khi nào chúng tôi thực hiện một đoạn mã JavaScript.

Hãy cùng bước đi, để hiểu những gì đang xảy ra dưới mui xe.

Mã thông báo

Trong bước đầu tiên này, động cơ chuyển đổi chuỗi mã thành một mảng mã thông báo. Động cơ đi qua ký tự mã theo ký tự và từng chữ để phân loại từng nhân vật.

Ví dụ: nếu bạn có một dòng mã như thế này let x = 10;, động cơ sẽ chuyển đổi nó thành một mảng mã thông báo như thế này

[K(LET, “let”, 0), T(WHITESPACE, “ “, 0),
T(IDENTIFIER, “x”, 0), T(WHITESPACE,” “, 0),
T(ASSIGN, “=”, 2), T(WHITESPACE, “ “, 0),
T(SMI, “10”, 0), T(SEMICOLON, “;”, 0)]

Lưu ý tôi sẽ không giải thích mảng mã thông báo này ở đây, nhưng nếu bạn nghiên cứu lý thuyết trình biên dịch có thể bạn thấy nó quen thuộc với bạn. I will not explain this array of tokens here, but if you studied compiler theory maybe you find it familiar to you.

Sau đó, động cơ bắt đầu bước thứ hai để tạo ra cây cú pháp trừu tượng (AST) bằng cách sử dụng mảng mã thông báo này.

Phân tích cú pháp

Động cơ V8 bắt đầu chuyển đổi mảng mã thông báo này thành một cây cú pháp trừu tượng, cấu trúc dữ liệu này đại diện cho mã của chúng tôi. Một trong những điều quan trọng nhất trong bước phân tích cú pháp là động cơ xác định phạm vi của từng biến.

Ví dụ: nếu chúng ta có một chức năng như thế này

function add(x, y) {
return x + y;
}

Động cơ sẽ chuyển đổi nó thành AST như thế này:

— — AST — -
FUNC at 12
. KIND 0
. SUSPEND COUNT 0
. NAME “add”
. PARAMS
. . VAR (0x7fbd5e818210) (mode = VAR) “x”
. . VAR (0x7fbd5e818240) (mode = VAR) “y”
. RETURN at 23
. . ADD at 32
. . . VAR PROXY parameter[0] (0x7fbd5e818210) (mode = VAR) “x”
. . . VAR PROXY parameter[1] (0x7fbd5e818240) (mode = VAR) “y”

Bạn có thể thấy AST cho bất kỳ mẫu mã nào bằng công cụ V8 bằng lệnh này:

$ d8 -- print-ast 

Và đây là hình dung cho điều này AST:

Sau đó, động cơ bắt đầu tạo mã byte là mã thực thi.

Trình thông dịch / trình biên dịch cơ sở

Đây là nơi phần khó hiểu nhất bắt đầu, JavaScript là ngôn ngữ được biên dịch nhưng nó khác với những gì chúng ta biết về ngôn ngữ được biên dịch cổ điển như ngôn ngữ C. C là ngôn ngữ được đánh máy một cách thống kê là một so sánh nhanh giữa hai điều này

AOT

Trước khi biên dịch, trong loại này, việc biên dịch là một quy trình riêng biệt và nó chỉ xảy ra một lần, kết quả của quá trình này là một tệp thực thi mà bạn có thể chạy nó.head Of Time compilation, In this type, the compilation is a separate process and it happens only once, the result of this process is an executable file you that can run it.

Jit

Chỉ trong quá trình biên dịch thời gian, nó không phải là một quy trình riêng biệt, nó xảy ra trong thời gian chạy. Trong bước này, động cơ biên soạn từng dòng và thu thập thông tin (đây được gọi là hồ sơ của Hồi giáo) về mã để sử dụng nó sau trong bước sắp xếp lại.ust In Time compilation, it’s not a separate process, it happens during the runtime. In this step the engine compiles line by line and collects info(this is called “profiling”) about the code to use it later in the recompilation step.

V8 có một thành phần chịu trách nhiệm cho phần này được gọi là đánh lửa, IFYouchecked mã nguồn V8 Bạn sẽ tìm thấy bytecodegenerator là một phần của thành phần đánh lửa tạo ra mã byte. Trong quá trình này, công cụ JavaScript thực hiện một quy trình gọi là hồ sơ để thu thập một số thông tin về mã để sử dụng nó sau này trong bước tối ưu hóa.Ignition, ifyou checked the V8 source code you will find the BytecodeGenerator which is part of the Ignition component that generates the Byte-code. during this process the JavaScript engine does a process called profiling to collect some information about the code to use it later in the optimization step.

Bạn có thể thấy mã byte cho bất kỳ mẫu mã nào bằng lệnh này:

$ d8 -- print-bytecode 

Ở bước này, mã JavaScript đang chạy. Các bước tiếp theo sẽ chỉ để tối ưu hóa.

Hồ sơ

Hồ sơ là một phần của bước phiên dịch, thông tin động cơ về mã như các loại dữ liệu và đánh dấu chức năng nóng sau đó lưu trữ thông tin này trong vector phản hồi.Feedback Vector.

Hàm nóng có nghĩa là chức năng này được sử dụng nhiều lần, sau đó động cơ đánh dấu chức năng này là nóng.

Bạn có thể thấy những dữ liệu này bằng lệnh này

$ d8 — prof 

Để biết thêm thông tin về hồ sơ xem cuộc nói chuyện này

https://www.youtube.com/watch?v=u7zRSm8jzvA​

Trình biên dịch tối ưu hóa

Turbofan là trình biên dịch tối ưu hóa bên trong V8, dựa trên thông tin mà đánh lửa thu thập nó, Turbofan bắt đầu tối ưu hóa các chức năng nóng để có hiệu suất tốt hơn. Turbofan phụ thuộc vào bộ nhớ đệm nội tuyến để lưu chức năng được tối ưu hóa này để sử dụng nó thay vì chức năng ban đầu. is the optimization compiler inside V8, based on the info that Ignition collected it,TurboFan starts to optimize the hot functions for better performance. TurboFan depends on inline caching to save this optimized function to use it instead of the original function.

Ảnh của Franziska Hinkelmann

Bất cứ khi nào bộ đệm nội tuyến này không hợp lệ, động cơ trở lại để thực thi mã byte thay vì mã được tối ưu hóa này, điều này được gọi là deoptimization.deoptimization.

Tránh giảm độ deoptimization

Có rất nhiều mẹo và thủ thuật để tránh bước tối đa hóa này để có hiệu suất tốt hơn cho trang web của bạn như

  1. Cố gắng làm cho mã của bạn trông giống như các ngôn ngữ được gõ tĩnh.
  2. Tránh các mảng Holly.