Điều gì xảy ra trong quá trình điều hướng
Đây là phần 2 của loạt bài gồm 4 phần trên blog, tìm hiểu về cách hoạt động bên trong của Chrome. Trong bài đăng trước, chúng ta đã xem xét cách các quy trình và luồng xử lý các phần khác nhau của trình duyệt. Trong bài đăng này, chúng ta sẽ tìm hiểu sâu hơn về cách mỗi quy trình và luồng giao tiếp để hiển thị một trang web.
Hãy xem xét một trường hợp sử dụng đơn giản của việc duyệt web: bạn nhập một URL vào trình duyệt, sau đó trình duyệt sẽ tìm nạp dữ liệu từ Internet và hiển thị một trang. Trong bài đăng này, chúng ta sẽ tập trung vào phần mà người dùng yêu cầu một trang web và trình duyệt chuẩn bị hiển thị một trang – còn gọi là điều hướng.
Quá trình này bắt đầu bằng một quy trình trình duyệt

Như chúng ta đã đề cập trong phần 1: CPU, GPU, Bộ nhớ và cấu trúc đa quy trình, mọi thứ bên ngoài thẻ đều do quy trình trình duyệt xử lý. Quá trình trình duyệt có các luồng như luồng giao diện người dùng vẽ các nút và trường nhập của trình duyệt, luồng mạng xử lý ngăn xếp mạng để nhận dữ liệu từ Internet, luồng bộ nhớ kiểm soát quyền truy cập vào các tệp và nhiều luồng khác. Khi bạn nhập URL vào thanh địa chỉ, dữ liệu đầu vào của bạn sẽ được xử lý bằng luồng giao diện người dùng của quy trình trình duyệt.
Một thành phần điều hướng đơn giản
Bước 1: Xử lý dữ liệu đầu vào
Khi người dùng bắt đầu nhập vào thanh địa chỉ, điều đầu tiên mà luồng giao diện người dùng hỏi là "Đây có phải là cụm từ tìm kiếm hay URL không?". Trong Chrome, thanh địa chỉ cũng là một trường nhập dữ liệu tìm kiếm, vì vậy, luồng giao diện người dùng cần phân tích cú pháp và quyết định xem sẽ chuyển bạn đến một công cụ tìm kiếm hay đến trang web mà bạn yêu cầu.

Bước 2: Bắt đầu chỉ đường
Khi người dùng nhấn enter, luồng giao diện người dùng sẽ bắt đầu một lệnh gọi mạng để lấy nội dung trang web. Vòng quay tải sẽ hiển thị ở góc của một thẻ và luồng mạng sẽ đi qua các giao thức thích hợp như tra cứu DNS và thiết lập Kết nối TLS cho yêu cầu.

Tại thời điểm này, luồng mạng có thể nhận được tiêu đề chuyển hướng máy chủ như HTTP 301. Trong trường hợp đó, luồng mạng sẽ giao tiếp với luồng giao diện người dùng mà máy chủ đang yêu cầu chuyển hướng. Sau đó, một yêu cầu URL khác sẽ được bắt đầu.
Bước 3: Đọc câu trả lời

Khi phần nội dung phản hồi (trọng tải) bắt đầu đến, luồng mạng sẽ xem xét vài byte đầu tiên của luồng nếu cần. Tiêu đề Content-Type của phản hồi sẽ cho biết đó là loại dữ liệu nào, nhưng vì tiêu đề này có thể bị thiếu hoặc không chính xác, nên tìm nạp loại MIME sẽ được thực hiện tại đây. Đây là một "việc khó khăn" như đã nhận xét trong mã nguồn. Bạn có thể đọc nhận xét để xem các trình duyệt khác nhau xử lý các cặp loại nội dung/trọng tải như thế nào.
Nếu phản hồi là tệp HTML, thì bước tiếp theo sẽ là truyền dữ liệu đến quy trình trình kết xuất, nhưng nếu đó là tệp zip hoặc một số tệp khác, thì tức là đó là yêu cầu tải xuống, vì vậy, chúng cần truyền dữ liệu đến trình quản lý tải xuống.

Đây cũng là nơi diễn ra quy trình kiểm tra SafeBrowsing. Nếu miền và dữ liệu phản hồi có vẻ khớp với một trang web độc hại đã biết, thì luồng mạng sẽ cảnh báo để hiển thị một trang cảnh báo. Ngoài ra, quy trình kiểm tra Cross Origin Read Blocking (CORB) sẽ diễn ra để đảm bảo dữ liệu nhạy cảm trên nhiều trang web không được đưa vào quy trình kết xuất.
Bước 4: Tìm quy trình kết xuất
Sau khi tất cả các bước kiểm tra hoàn tất và luồng Mạng tự tin rằng trình duyệt sẽ chuyển đến trang web được yêu cầu, luồng Mạng sẽ thông báo cho luồng giao diện người dùng rằng dữ liệu đã sẵn sàng. Sau đó, luồng giao diện người dùng sẽ tìm một quy trình kết xuất để tiếp tục kết xuất trang web.

Vì yêu cầu mạng có thể mất vài trăm mili giây để nhận được phản hồi, nên một phương thức tối ưu hoá sẽ được áp dụng để đẩy nhanh quá trình này. Khi luồng giao diện người dùng đang gửi yêu cầu URL đến luồng mạng ở bước 2, luồng này đã biết trang web mà họ đang điều hướng đến. Luồng giao diện người dùng cố gắng chủ động tìm hoặc bắt đầu một quy trình kết xuất song song với yêu cầu mạng. Bằng cách này, nếu mọi thứ diễn ra như dự kiến, thì quá trình kết xuất sẽ ở trạng thái chờ khi luồng mạng nhận được dữ liệu. Quá trình chờ này có thể không được sử dụng nếu thao tác điều hướng chuyển hướng trên nhiều trang web, trong trường hợp đó, bạn có thể cần một quy trình khác.
Bước 5: Cam kết điều hướng
Giờ đây, dữ liệu và quy trình kết xuất đã sẵn sàng, IPC sẽ được gửi từ quy trình trình duyệt đến quy trình kết xuất để thực hiện thao tác điều hướng. Lớp này cũng truyền luồng dữ liệu để quá trình kết xuất có thể tiếp tục nhận dữ liệu HTML. Sau khi quy trình trình duyệt nghe được thông báo xác nhận rằng quá trình xác nhận đã xảy ra trong quy trình kết xuất, quá trình điều hướng sẽ hoàn tất và giai đoạn tải tài liệu sẽ bắt đầu.
Tại thời điểm này, thanh địa chỉ sẽ được cập nhật và chỉ báo bảo mật cũng như giao diện người dùng cài đặt trang web sẽ phản ánh thông tin trang web của trang mới. Nhật ký phiên hoạt động cho thẻ sẽ được cập nhật để các nút quay lại/tiến sẽ chuyển đến trang web vừa được truy cập. Để hỗ trợ khôi phục thẻ/phiên khi bạn đóng thẻ hoặc cửa sổ, nhật ký phiên sẽ được lưu trữ trên ổ đĩa.

Bước bổ sung: Đã tải xong ban đầu
Sau khi điều hướng được thực hiện, quá trình kết xuất sẽ tiếp tục tải tài nguyên và hiển thị trang. Chúng tôi sẽ trình bày chi tiết về những gì xảy ra ở giai đoạn này trong bài đăng tiếp theo. Sau khi quá trình kết xuất "hoàn tất" quá trình kết xuất, quá trình này sẽ gửi một IPC trở lại quy trình trình duyệt (đây là sau khi tất cả các sự kiện onload
đã kích hoạt trên tất cả các khung trong trang và đã hoàn tất quá trình thực thi). Tại thời điểm này, luồng giao diện người dùng sẽ dừng vòng quay đang tải trên thẻ.
Tôi nói "kết thúc" vì JavaScript phía máy khách vẫn có thể tải thêm tài nguyên và hiển thị các thành phần hiển thị mới sau thời điểm này.

Chuyển đến một trang web khác
Bạn đã hoàn tất phần điều hướng đơn giản! Nhưng điều gì sẽ xảy ra nếu người dùng đặt một URL khác vào thanh địa chỉ lần nữa? Quy trình của trình duyệt cũng trải qua các bước tương tự để chuyển đến trang web khác.
Nhưng trước khi có thể làm như vậy, trình xử lý cần kiểm tra với trang web hiện đang hiển thị xem họ có quan tâm đến sự kiện beforeunload
hay không.
beforeunload
có thể tạo cảnh báo "Rời khỏi trang web này?" khi bạn cố gắng rời khỏi hoặc đóng thẻ.
Mọi thứ bên trong một thẻ, bao gồm cả mã JavaScript, đều do quy trình kết xuất xử lý. Vì vậy, quy trình trình duyệt phải kiểm tra với quy trình kết xuất hiện tại khi có yêu cầu điều hướng mới.

Nếu thao tác điều hướng được bắt đầu từ quy trình trình kết xuất (chẳng hạn như người dùng nhấp vào một đường liên kết hoặc JavaScript phía máy khách đã chạy window.location = "https://newsite.com"
), thì trước tiên, quy trình trình kết xuất sẽ kiểm tra trình xử lý beforeunload
. Sau đó, thao tác này sẽ trải qua quy trình tương tự như thao tác điều hướng do trình duyệt khởi tạo. Điểm khác biệt duy nhất là yêu cầu điều hướng được khởi động từ quy trình kết xuất hình ảnh sang quy trình trình duyệt.
Khi điều hướng mới được thực hiện đến một trang web khác với trang web hiện đang hiển thị, một quy trình kết xuất riêng biệt sẽ được gọi để xử lý điều hướng mới trong khi quy trình kết xuất hiện tại vẫn được giữ lại để xử lý các sự kiện như unload
. Để biết thêm thông tin, hãy xem tổng quan về các trạng thái vòng đời của trang và cách bạn có thể liên kết với các sự kiện bằng API Vòng đời trang.

Trong trường hợp của Trình chạy dịch vụ
Một thay đổi gần đây đối với quy trình điều hướng này là việc giới thiệu worker dịch vụ. Trình chạy dịch vụ là một cách để ghi proxy mạng trong mã ứng dụng của bạn; cho phép nhà phát triển web có nhiều quyền kiểm soát hơn đối với nội dung cần lưu vào bộ nhớ đệm cục bộ và thời điểm nhận dữ liệu mới từ mạng. Nếu bạn đặt trình chạy dịch vụ để tải trang từ bộ nhớ đệm, thì bạn không cần yêu cầu dữ liệu từ mạng.
Điều quan trọng cần nhớ là worker dịch vụ là mã JavaScript chạy trong quy trình trình kết xuất. Nhưng khi yêu cầu điều hướng đến, làm cách nào để quy trình của trình duyệt biết rằng trang web có worker dịch vụ?

Khi một worker dịch vụ được đăng ký, phạm vi của worker dịch vụ sẽ được giữ lại làm tham chiếu (bạn có thể đọc thêm về phạm vi trong bài viết Vòng đời của worker dịch vụ). Khi một thao tác điều hướng xảy ra, luồng mạng sẽ kiểm tra miền theo phạm vi trình chạy dịch vụ đã đăng ký. Nếu một trình chạy dịch vụ được đăng ký cho URL đó, luồng giao diện người dùng sẽ tìm một quy trình kết xuất để thực thi mã trình chạy dịch vụ. Trình chạy dịch vụ có thể tải dữ liệu từ bộ nhớ đệm, giúp bạn không cần yêu cầu dữ liệu từ mạng hoặc có thể yêu cầu tài nguyên mới từ mạng.

Tải trước điều hướng
Bạn có thể thấy rằng hành trình đi và về này giữa quy trình trình duyệt và quy trình trình kết xuất có thể dẫn đến độ trễ nếu cuối cùng trình chạy dịch vụ quyết định yêu cầu dữ liệu từ mạng. Tải trước điều hướng là một cơ chế giúp tăng tốc quá trình này bằng cách tải tài nguyên song song với quá trình khởi động worker dịch vụ. Phương thức này đánh dấu các yêu cầu này bằng một tiêu đề, cho phép máy chủ quyết định gửi nội dung khác cho các yêu cầu này; ví dụ: chỉ gửi dữ liệu đã cập nhật thay vì toàn bộ tài liệu.

Tổng kết
Trong bài đăng này, chúng ta đã xem xét những gì xảy ra trong quá trình điều hướng và cách mã ứng dụng web của bạn (chẳng hạn như tiêu đề phản hồi và JavaScript phía máy khách) tương tác với trình duyệt. Khi biết các bước mà trình duyệt thực hiện để lấy dữ liệu từ mạng, bạn sẽ dễ dàng hiểu lý do các API như tải trước điều hướng được phát triển. Trong bài đăng tiếp theo, chúng ta sẽ tìm hiểu cách trình duyệt đánh giá HTML/CSS/JavaScript để hiển thị trang.
Bạn có thích bài đăng này không? Nếu bạn có câu hỏi hoặc đề xuất cho bài đăng sau này, tôi rất mong nhận được ý kiến của bạn trong phần bình luận bên dưới hoặc trên Twitter theo tên người dùng @kosamari.