Cây cú pháp trừu tượng javascript

Xin chào các bạn đến với bài thứ 14 trong sê-ri và khám phá Javascript cũng như các thành phần của nó. Trong quá trình xác minh và tìm hiểu các thành phần cốt lõi, tác giả cũng chia sẻ một số nguyên tắc mà họ đang sử dụng để xây dựng SessionStack, một ứng dụng Javascript hướng đến sự mạnh mẽ, hiệu năng cao và ổn định

Expansion

Chúng ta đều biết rằng những thứ lộn xộn có thể hợp thành 1 thứ lớn hơn gọi là Javascript. Một đoạn mã không chỉ có thể chuyển qua mạng mà nó còn phải được phân tích cú pháp, biên dịch sang mã byte và cuối cùng là thực thi. Trong các bài viết trước, chúng ta đã thảo luận về những thứ không xác định như engine JS, runtime, callstack cũng như engine V8 được sử dụng chủ yếu trong Chrome và NodeJS. Tất cả đều đóng vai trò quan trọng trong toàn bộ quá trình thực thi của Javascript. Chủ đề mà chúng ta sẽ tìm hiểu hôm nay cũng không quan trọng. chúng ta sẽ nghiên cứu xem làm thế nào mà đa số các engine JS phân tích văn bản thành một thứ gì đó có ý nghĩa đối với máy móc, những gì xảy ra sau đó và làm thế nào để nhà phát triển web như chúng ta có thể tận dụng

Ngôn ngữ lập trình hoạt động như thế nào?

Sau đó quay lại 1 chút và xem ngôn ngữ cài đặt thế nào cho chương trình hoạt động. Không cần biết bạn đang sử dụng ngôn ngữ gì, bạn sẽ luôn cần một phần mềm có thể đọc mã nguồn và khiến máy tính thực hiện một điều gì đó. Phần mềm này có thể là thông tin dịch vụ hoặc trình biên dịch

Không cần biết bạn đang sử dụng ngôn ngữ thông dịch (Javascript, Python, Ruby) hay ngôn ngữ biên dịch (C#, Java, Rust), luôn luôn có 1 điểm chung giữa chúng. phân tích cú pháp mã nguồn từ văn bản gốc thành một cấu trúc dữ liệu được gọi là Cây cú pháp trừu tượng (AST)

Các AST không thể chỉ mã nguồn dưới dạng cấu trúc mà chúng còn đóng vai trò quan trọng trong phân tích ngữ nghĩa, chính là nơi mà trình biên dịch xác nhận tính toán đúng đắn và cách sử dụng phù hợp của chương trình cũng như các chương trình . Về sau, AST được sử dụng để sinh mã bytecode hoặc mã máy

Ứng dụng AST

AST không chỉ được sử dụng trong thông dịch trình và biên dịch ngôn ngữ, chúng còn có nhiều ứng dụng trong thế giới máy tính. Một trong số đó được sử dụng bởi chúng tôi là mã phân tích tĩnh. Các nhà phân tích tĩnh mã không thực thi mã, họ cần hiểu cấu trúc của mã. Ví dụ. bạn muốn triển khai một công cụ tìm kiếm sự giống nhau giữa các mã kiến ​​trúc để từ đó bạn có thể tái cấu trúc để giảm sự lặp lại. Bạn có thể làm công việc này bằng cách so sánh chuỗi bình thường nhưng cách phát triển khai thì khá cơ bản và giới hạn

Một cách tự nhiên, nếu bạn có hứng thú phát triển khai một công cụ thì bạn không cần phải viết riêng cho nó 1 cái trình phân tích cú pháp. Có rất nhiều triển khai mã nguồn mở có sẵn khả năng tương thích toàn diện với thông số kỹ thuật của Ecmascript. Ví dụ. Esprima và Acorn. Cũng có rất nhiều công cụ có thể giúp ta với sản phẩm nhận được từ trình phân tích cú pháp, hay còn gọi là AST. Các AST cũng được sử dụng nhiều trong phần khai thác của bộ chuyển đổi mã. Ví dụ. bạn cần triển khai bộ chuyển mã để chuyển mã Python thành Javascript. Ý tưởng cơ bản là ta cần một bộ chuyển mã Python để sinh ra cây AST - thứ mà ta cần để có thể sinh ra mã Javascript sau này

Bạn có thể tự hỏi, làm thế nào để được như vậy? . Trước khi phân tích cú pháp, nó có thể hiển thị dưới dạng văn bản đi kèm theo một số quy định luật định nhất để hình thành nên 1 ngôn ngữ. Sau khi phân tích cú pháp, nó có thể hiển thị bên dưới dạng kiến ​​trúc dạng cây chứa chính xác cùng 1 thông tin với văn bản đầu vào. Vì thế, bạn có thể luôn luôn có thể quay ngược lại và quay lại định dạng biểu diễn văn bản

phân tích cú pháp Javascript

Giờ thì cùng tìm hiểu cây AST được xây dựng như thế nào. Đầu tiên ta có một Javascript menu đơn giản như sau

1
2
3
4
5
6
7
8
function foo(x) {
if (x > 10) {
var a = 2;
return a * x;
}

return x + 10;
}

Trình phân tích cú pháp sẽ tạo ra cây AST như sau

Cây cú pháp trừu tượng javascript

Lưu ý rằng vì mục đích dễ nhìn và đẹp nên hình trên chỉ là phiên bản tối thiểu của sản phẩm thực sự từ trình phân tích cú pháp. Cây AST thật sẽ phức tạp hơn rất nhiều. Tuy nhiên, mục đích của chúng ta là có ý tưởng cơ bản về việc mã nguồn sẽ biến thành cái gì trước khi nó được thực hiện. Nếu bạn muốn xem cây AST thứ thiệt trông như thế nào thì bạn có thể vào đây. Đó là 1 công cụ trực tuyến, bạn chỉ cần nhập mã Javascript vào và nó sẽ sinh ra cây AST cho đoạn mã đó

Bạn sẽ tự hỏi tại sao chúng ta cần biết về cách hoạt động của trình phân tích cú pháp Javascript. Sau tất cả thì nó thuộc về trách nhiệm của trình duyệt. Và về mặt nào đó thì đúng là như thế. Tuy nhiên, bạn có thể xem hình bên dưới, đó là biểu đồ biểu thị tổng thời gian phân phối cho từng bước trong quá trình thực thi mã Javascript. Hãy nhìn kỹ hơn và thử xem có được gì thú vị không

You have found was not? . Trung bình thì trình duyệt chiếm khoảng 15-20% tổng thời gian thực thi để phân tích cú pháp Javascript. Những con số này không phải là thiết lập. Chúng là số liệu thống kê từ những ứng dụng và trang web có thật đang sử dụng Javascript theo cách này hay cách khác. Giờ thì 15% có vẻ như không nhiều lắm, nhưng tin tôi đi, nó có giá đấy. Một ứng dụng SPA tiêu chuẩn sẽ tải khoảng cách 0. 4MB mã Javascript và trình duyệt tiêu hủy xấp xỉ 370ms để phân tích cú pháp

Thêm một lần nữa, bạn sẽ nói rằng nó thật đáng sợ bao nhiêu thời gian cả. Unknown con number too small. Tuy nhiên hãy nhớ kỹ rằng đây chỉ là thời gian cần thiết để phân tích mã Javascript thành cây AST. Không bao gồm thời gian thực thi chính nó hay bất kỳ tiến trình nào diễn ra trong khi tải trang (ví dụ như kết xuất CSS & HTML). Và tất cả các thông số này mới chỉ có thể hiển thị cho máy tính để bàn. Khi chúng ta đi sâu hơn trên thiết bị di động, mọi thứ sẽ trở nên phức tạp hơn nhiều. Thời gian dành cho việc phân tích cú pháp trên thiết bị di động thường có thể nhiều hơn 2-5 lần so với trên máy tính để bàn

Đồ thị có thể hiện thời gian phân tích cú pháp của 1 mã gói Javascript 1MB trên rất nhiều thiết bị di động & máy tính để bàn thuộc nhiều phân khúc khác nhau

Hay nữa nào? . Bạn có thể dễ dàng hiểu được những điều ảnh hưởng như thế nào đến trang web/wepapp của bạn. Tất cả những gì bạn cần là mở công cụ phát triển của trình duyệt và để nó đo thời lượng thời gian dành cho phân tích cú pháp, biên dịch và mọi diễn biến thứ cấp trên trình duyệt để truy cập khi trang web được tải hoàn toàn

Thật không may, không có công cụ dev nào cho trình duyệt di động. Nhưng đừng lo lắng, điều này không có nghĩa là bạn không thể làm được gì. Đây là lý do để những công cụ như DeviceTiming tồn tại. Nó có thể giúp bạn đo lường sự ngẫu nhiên trong thời gian phân tích cú pháp và thực thi các đoạn mã trong môi trường kiểm tra giám sát. Nó hoạt động bằng cách gói gọn mã cục bộ với đoạn mã đo lường, bởi vì thế nên mỗi lần trang web của bạn được truy cập từ các thiết bị khác nhau, bạn có thể đo lường thời gian phân tích cú pháp và thực thi

Điều tốt là công cụ Javascript đã làm được rất nhiều thứ nhằm tránh cách công việc thừa thãi và tối thiểu hóa hơn nữa. Dưới đây là 1 số thứ mà các công cụ của những trình duyệt đã làm

Ví dụ với V8, nó thực hiện truyền phát tập lệnh & bộ nhớ đệm mã. Truyền phát tập lệnh có nghĩa là các đoạn mã bất đồng bộ & bị trì hoãn sẽ được phân tích cú pháp trong 1 tiến trình riêng ngay khi quá trình tải xuống bắt đầu. Nó giúp quá trình phân tích cú pháp gần như hoàn thành ngay lập tức sau khi đoạn mã (script) được tải xuống xong. Kết quả là các trang sẽ tải nhanh hơn khoảng 10%

Code Javascript thường được biên dịch thành bytecode mỗi khi có một lượt truy cập trang. Tuy nhiên, mã byte cục bộ này lại bị loại bỏ khi người dùng truy cập vào trang khác. Điều này xảy ra do mã được biên dịch phụ thuộc rất nhiều vào trạng thái và ngữ cảnh của máy tại thời điểm biên dịch. Đây là lý do Chrome 42 giới thiệu bộ nhớ đệm mã byte (bộ đệm mã byte). Đây là một kỹ thuật lưu trữ mã đã biên dịch tại địa phương để khi người dùng quay lại trang cũ trước đó thì tất cả mọi hoạt động như tải xuống, phân tích cú pháp, biên dịch… đều có thể bỏ qua. Nó cho phép Chrome tiết kiệm 40% thời gian phân tích & thực thi. Thêm nữa, kết quả của nó tiết kiệm pin nhiều hơn nếu chạy trên thiết bị di động

Trong Opera, engine Carakan có thể sử dụng lại kết quả biên dịch từ chương trình khác vừa mới được biên dịch gần đây. Không có bất kỳ yêu cầu cụ thể nào về việc mã phải đến từ cùng 1 trang hoặc tên miền. Kỹ thuật caching này thực sự rất hữu ích và có thể hoàn toàn bỏ qua bước biên dịch. Nó phụ thuộc vào hành vi tiêu chuẩn của người dùng và ngữ cảnh web. Mỗi khi người dùng thực hiện cùng một chuỗi hành động với một người dùng khách trên ứng dụng/trang web thì cùng một đoạn mã Javascript sẽ được tải xuống. Tuy nhiên, Opera đã sớm thay thế Carakan bằng Google V8

Bộ máy SpiderMonkey của Firefox không lưu cache bất kỳ thứ gì. Nó đại khái là chuyển qua sử dụng một thao tác giám sát để đếm xem 1 đoạn mã Javascript được thực thi bao nhiêu lần. Dựa trên số lượng này, nó xác định bất kỳ phần nào của mã đang nóng và cần được tối ưu hóa

Rõ ràng có một số người lựa chọn không làm gì cả. Maciej Stachowiak, nhà phát triển chính của Safari, chỉ định rằng Safari không thực hiện bất kỳ hoạt động cache nào cho bytecode đã biên dịch. Có vẻ như họ đã cân nhắc về công việc này nhưng không triển khai nó bởi vì nó chỉ nhỏ hơn 2% tổng thời gian thực hiện

Những hoạt động tối ưu hóa không trực tiếp ảnh hưởng đến câu chuyện phân tích cú pháp mã Javascript nhưng họ chắc chắn đang làm tốt nhất có thể để loại bỏ nó một cách hoàn toàn. Còn cách tối ưu hóa nào tốt hơn là tối ưu hóa hoàn toàn?

Có nhiều thứ chúng ta có thể làm để cải thiện ban đầu thời gian tải ứng dụng. Ta could not be minimum code Javascript is used. ít code, ít phân tích, ít thực hi. Để làm được điều này, ta cần đưa ra mã vừa đủ lượng cần thiết cho một công cụ tính năng có thể thay thế vì tải 1 điểm thiệt hại lớn và sử dụng nó vào mọi thứ. Ví dụ, mẫu PRPL có thuyết giảng về mô hình chuyển giao mã như vậy. Nói cách khác, ta có thể kiểm tra các phụ thuộc và xem liệu có thứ gì thừa mà không cần thiết phải làm mã chậm của chúng ta. Về phần này thì hi vọng là sẽ có 1 chủ đề riêng để nói về nó

Mục đích của bài viết này là để thảo luận về chúng ta - những nhà phát triển web - có thể làm được gì để giúp trình phân tích cú pháp Javascript có thể chạy nhanh hơn. Và chính ở đây, trình phân tích cú pháp Javascript hiện đại sử dụng các phỏng đoán để xác định xem một đoạn mã cụ thể có thể nào chuẩn bị được thực thi ngay hoặc quá trình thực thi sẽ bị tạm dừng và dịch chuyển lại trong một thời điểm khác

dựa trên các phỏng đoán, trình phân tích cú pháp sẽ làm hoặc là phân tích cú pháp háo hức (parse nhanh) hoặc là phân tích cú pháp lười biếng (phân tích cú pháp từ). Háo hức phân tích cú pháp chạy xuyên suốt các hàm nào cần được biên dịch thời gian. Nó thực hiện 3 công việc chính. xây dựng cây AST, xây dựng hệ thống cấp bậc (phân cấp) cho phạm vi và tìm tất cả các lỗi cú pháp

Lazy parsing thì ngược lại, nó chỉ được sử dụng cho các hàm chưa được biên dịch. Nó không xây dựng cây AST và cũng không tìm thấy lỗi cú pháp. Nó chỉ xây dựng hệ thống cấp bậc cho phạm vi và tiết kiệm điện được nửa thời gian nên với sự háo hức

Rõ ràng đây không phải là ý tưởng mới. Cả trình duyệt như IE9 cũng hỗ trợ tối ưu hóa mặc định mặc dù nó chạy hơi thô sơ nếu như vậy với cách mà trình phân tích cú pháp ngày nay hoạt động

Giờ thì cùng xem một ví dụ về cách nó hoạt động. Giả sử ta có đoạn mã sau

1
2
3
4
5
6
7
8
9
10
11
function foo() {
function bar(x) {
return x + 10;
}

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

console.log(baz(100, 200));
}

Giống như ví dụ trước, mã được đưa vào trình phân tích cú pháp để phân tích cú pháp và trả về cây AST. Do đó, đây là những gì thực hiện theo từng dòng

Định nghĩa hàm bar nhận 1 biến x và nó có 1 câu lệnh return trả về kết quả của phép cộng giữa x và 10

Định nghĩa hàm baz nhận 2 biến (x và y). It has 1 return command. Hàm này trả về kết quả của phép tính cộng giữa x và y

Baz function call with 2 đối số là 100 và 200

Tạo 1 lời gọi hàm đến bảng điều khiển. log with value is result of the call's function before that

Điều gì xảy ra như vậy? . đăng nhập. Chờ đã… có một số trình phân tích cú pháp đã làm đầy đủ không liên quan. That is task parse bar. in sao lại không liên quan? . Đây chỉ là một ví dụ đơn giản và có vẻ như không bình thường nhưng nó xuất hiện trên rất nhiều ứng dụng thực tế, có rất nhiều hàm được định nghĩa nhưng không bao giờ được sử dụng đến

Thay vì phân tích cú pháp thanh hàm, chúng ta có thể đánh dấu nó đã được khai báo nhưng không chỉ ra cụ thể nó có thể làm gì. Việc phân tích cú pháp sẽ diễn ra khi cần thiết ngay trước khi hàm được thực thi. Và dĩ nhiên là lazy parsing cũng vẫn cần thiết để tìm toàn bộ nội dung của hàm và tạo khai báo cho hàm đó. Nó không cần cột pháp bởi vì nó vẫn chưa được xử lý. Thêm nữa, bộ nhớ heap vẫn chưa được cấp phát (phần này cũng chiếm 1 lượng tương đối trong tài nguyên hệ thống). Nói ngắn gọn thì bỏ qua một số bước trên sẽ cải thiện đáng kể hiệu năng

Vì vậy nên nhìn lại ví dụ trên, ta có cây AST mới sẽ như thế này

Lưu ý rằng hàm thanh được khai báo và chấp nhận, nhưng chỉ có thế thôi. We don't doing anything with body of function. Trong trường hợp này, phần thân của hàm chỉ có 1 câu lệnh trả về. Tuy nhiên, trong hầu hết các ứng dụng thực tế, nó có thể lớn hơn rất nhiều, bao gồm nhiều câu lệnh return, điền điều kiện, vòng lặp, định nghĩa các biến và kể cả các hàm khai báo lồng nhau. Tất cả những thứ này sẽ gây ra thời gian cũng như tài nguyên hệ thống bởi vì hàm không bao giờ được gọi

Đây là một ý tưởng cực kỳ đơn giản nhưng trong thực tế công việc thì việc phát triển khai thác nó lại không đơn giản. Dưới đây là một ví dụ mà chắc chắn không phải là trường hợp nhất duy nhất. Toàn bộ phương thức sử dụng các hàm, vòng lặp, điều kiện, đối tượng, vân vân. Cơ bản là toàn bộ mã cần được phân tích cú pháp

Ví dụ một mô hình phổ biến để phát triển mô-đun Javascript

1
2
3
4
var myModule = (function() {
// toàn bộ logic của module
// return về module.
})();

Mô hình này dễ dàng được nhận ra bởi trình phân tích cú pháp Javascript hiện đại và là một dấu hiệu cho thấy mã bên trong có thể sử dụng phân tích cú pháp háo hức

Vì sao trình phân tích cú pháp không mặc định phân tích cú pháp lười biếng? . A lazy parse đã được thực hiện và ngay sau đó là háo hức phân tích cú pháp. Kết quả là tốc độ chậm hơn 50% khi so sánh với việc chỉ sử dụng 1 phân tích cú pháp háo hức

Đến lúc này ta đã có kiến ​​thức cơ bản về phía hậu trường, giờ thì thử xem chúng ta có giúp được gì cho bộ phân tích cú pháp không được. Ta có thể viết mã theo cách mà các hàm có thể được phân tích tại thời điểm phù hợp. Có một mẫu được sử dụng chung giữa các trình phân tích cú pháp. close package function in quote(). Đây luôn là một dấu hiệu đánh giá tích cực cho trình phân tích cú pháp hiểu rằng hàm sẽ được thực thi ngay lập tức. Nếu trình phân tích cú pháp bắt gặp một dấu mở ( và ngay sau đó là một hàm định nghĩa, nó sẽ phân tích cú pháp hàm háo hức đó. Chúng ta có thể giúp trình phân tích cú pháp bằng cách khai báo hàm một cách tường minh như vậy hàm sẽ được thực thi ngay lập tức

Giả sử ta có Javascript như sau

1
2
3
function foo(x) {
return x * 10;
}

Bởi vì không có dấu hiệu rõ ràng rằng hàm sẽ được thực thi ngay lập tức nên trình duyệt sẽ thực hiện lazy parse. Tuy nhiên, chúng ta biết rằng như vậy là không đúng nên ta có thể làm 2 việc

First, ta save function into in 1 variable

1
2
3
var foo = function foo(x) {
return x * 10;
};

Lưu ý rằng ta vẫn giữ lại tên hàm foo giữa từ khóa hàm và dấu mở khóa (. Điều này tuy không cần thiết nhưng bạn phải làm vì trong trường hợp xử lý biệt lệ, stacktrace sẽ hiển thị tên cụ thể của hàm thay vì một chữkhô khan

Trình phân tích cú pháp vẫn đang thực hiện phân tích cú pháp lười biếng. Ta có thể ngăn chặn điều này bằng cách thêm một chi tiết nhỏ. package function that back in the quote

1
2
3
function foo(x) {
if (x > 10) {
var a = 2;
return a * x;
}

return x + 10;
}
1

Tại thời điểm này, khi trình phân tích cú pháp thấy dấu mở trích dẫn ( ngay trước từ khóa hàm nó sẽ ngay lập tức thực hiện phân tích cú pháp háo hức

Sẽ hơi khó để quản lý bởi vì chúng ta sẽ cần phải biết trong trường hợp nào, trình phân tích cú pháp chọn phân tích cú pháp lười biếng hay háo hức. Thêm nữa ta cần phải suy nghĩ và tìm hiểu một hàm cụ thể nào đó có thể được gọi ngay lập tức hay không. Chúng ta chắc chắn không muốn làm như vậy. Ít nhất thì nó sẽ làm cho code khó đọc & khó hiểu hơn. Tools as Optimize. js có thể giúp ta rất nhiều. Mục đích duy nhất của nó là tối ưu hóa thời gian cho phép ban đầu mã Javascript. Chúng thực hiện phân tích mã tĩnh và chỉnh sửa lại để đóng các gói hàm nào cần được thực thi bên lề trong dấu trích dẫn (), trình duyệt sẽ có thể phân tích cú pháp háo hức và chúng tôi chuẩn bị sẵn sàng để thực thi

Chúng ta có thể tiếp tục mã bình thường và có mã đoạn mã sau

1
2
3
function foo(x) {
if (x > 10) {
var a = 2;
return a * x;
}

return x + 10;
}
3

Mọi thứ đều có vẻ tốt, hoạt động đúng như mong đợi và nhanh hơn nữa. Bởi vì có dấu mở ( trước khi khai báo hàm. Rất tuyệt. Dĩ nhiên rồi, trước khi đưa vào sản xuất ta cần giảm thiểu để tiết kiệm dung lượng. Đoạn mã sau là sản phẩm cuối cùng

function foo(x) {
if (x > 10) {
var a = 2;
return a * x;
}

return x + 10;
}
4_______1_______5

Một lần nữa, chúng có vẻ tốt phải không? . Nhưng có thiếu gì mà thiếu. Trình thu nhỏ đã giải mã dấu đóng gói bên ngoài hàm và thay vào đó thêm 1 dấu chấm than. ngay trước hàm. Điều này có nghĩa là trình phân tích cú pháp sẽ bỏ qua nó và thực hiện phân tích cú pháp lười biếng. Trên hết thì để có thể thực thi hàm nó sẽ thực hiện háo hức phân tích cú pháp ngay sau khi lười biếng phân tích cú pháp. Do đó, làm lại mã chạy chậm hơn. May mắn thay, chúng ta có những công cụ như Optimize. js giúp ta trong các trường hợp này. Truyền đoạn mã đã thu nhỏ vào Tối ưu hóa. js and here is the first result

function foo(x) {
if (x > 10) {
var a = 2;
return a * x;
}

return x + 10;
}
4_______1_______7

Giờ thì ta đã có thành phẩm tốt nhất. mã được rút gọn và trình phân tích cú pháp dễ dàng xác định được những hàm nào cần phân tích cú pháp háo hức hàm nào cần phân tích cú pháp lười biếng

Biên dịch trước (Pre-compilation)

Vì sao ta không thực hiện đầy đủ các bước này ở phía máy chủ. Tất nhiên, sẽ tốt hơn nếu chúng ta thực hiện 1 lần rồi triển khai kết quả cho tất cả khách hàng, thay vì bắt từng khách hàng phải thực hiện nó mỗi lần chạy. Thật ra thì có những thảo luận về công việc engine nên cung cấp một cách để thực thi những đoạn mã đã được biên dịch trước đó để đỡ tốn thời gian cho trình duyệt

Về bản chất thì ý tưởng chính là có một công cụ ở phía máy chủ có thể sinh ra bytecode rồi truyền trực tiếp về phía máy khách và thực thi. Nếu thực sự đúng như vậy thì thời gian khởi động ứng dụng phía client sẽ được cải thiện đáng kể. Nghe rất hấp dẫn, nhưng mọi việc không đơn giản như vậy

Điều này có thể gây ra hiệu ứng ngược, hiệu ứng lớn là ngược lại, vì hầu hết mã có thể cần phải được ký & xử lý vì các lý do bảo mật. Đội ngũ V8 đang làm việc nội bộ với nhau để tránh phân tích cú pháp lại để quá trình biên dịch trước sẽ có lợi như thế nào

Một vài mẹo vặt bạn có thể thực hiện để ứng dụng chạy nhanh hơn
  • Kiểm tra các phụ thuộc. Loại bỏ những thứ không cần thiết
  • Chia nhỏ mã thành nhiều phần nhỏ hơn vì tải nguyên 1 cục bộ
  • Trì hoãn quá trình tải Javascript nếu có thể. Bạn chỉ cần tải phần mã nào cần thiết dựa trên tuyến đường hiện tại mà thôi
  • Sử dụng dev tool & DeviceTiming để tìm hiểu những phần nào đang bị thắt cổ chai
  • Use tool as Optimize. js để giúp trình phân tích cú pháp quyết định khi nào nên phân tích cú pháp háo hức & lười biếng

SessionStack là công cụ hỗ trợ tái tạo lại mọi thứ xảy ra đối với người dùng cuối cùng tại thời điểm họ gặp phải vấn đề khi đang tương tác với ứng dụng web. Công cụ này không xây dựng lại phiên bản làm việc đó thành 1 video thật mà chỉ giả lập tất cả các sự kiện trong hộp cát môi trường trên trình duyệt. Điều này có ý nghĩa rõ ràng nhất, ví dụ như trong trường hợp cơ sở mã của trang hiện tại lớn và phức tạp

Những kỹ thuật trên là thứ mà nhóm tác giả gần đây đã kết hợp trong quá trình phát triển SessionStack. Những tối ưu hóa đó cho phép họ tải SessionStack nhanh hơn. SessionStack chạy càng nhanh nó càng có thể giải phóng tài nguyên của trình duyệt nhanh hơn và mang lại trải nghiệm một cách liên tục & tự nhiên cho người dùng khi họ tải và xem lại các phiên làm việc