Kỹ thuật kỹ nghệ trình duyệt web (2021)
(browser.engineering)- Web Browser Engineering trình bày từ networking đến JavaScript, với định hướng tự tay tạo ra một trình duyệt web cơ bản nhưng hoàn chỉnh bằng vài nghìn dòng Python
- Lộ trình học đi từ tải trang, hiển thị tài liệu, chạy ứng dụng đến các tính năng trình duyệt hiện đại, lần lượt kết nối HTTP, HTML, CSS, DOM, bảo mật, pipeline dựng hình
- Phần đầu tập trung vào triển khai nền tảng trình duyệt như URL và yêu cầu HTTP, tạo cửa sổ và vẽ canvas, ngắt dòng văn bản và khoảng cách dòng
- Phần giữa và sau đó bao gồm xây dựng cây HTML, layout, áp dụng style, gửi biểu mẫu, phản hồi sự kiện, cookie và đăng nhập, cùng cả XSS và CSRF
- Phần cuối tiếp tục với compositing, event loop, hoạt ảnh GPU, cây trợ năng, iframe, invalidation và độ chính xác khi chỉnh sửa, giúp khảo sát rộng các thành phần triển khai của trình duyệt hiện đại
Tìm hiểu kiến trúc trình duyệt bằng cách tự triển khai
- Web Browser Engineering được xây dựng theo cách tự tay triển khai một trình duyệt cơ bản nhưng hoàn chỉnh để hiểu trình duyệt web hoạt động như thế nào
- Ngôn ngữ triển khai là Python, với quy mô tổng thể ở mức vài nghìn dòng
- Phạm vi trải dài từ networking đến JavaScript
- Bản in có thể mua tại Bookshop, B&N, Amazon
- Bản dịch đã có bản tiếng Hàn tại Hanbit, bản tiếng Nhật tại O’Reilly
- Có thể theo dõi cập nhật trên blog, Mastodon, Twitter, và cũng có diễn đàn thảo luận trên GitHub
Luồng mục lục
-
Phần mở đầu
-
Part 1: Loading Pages
- Downloading Web Pages: URL và yêu cầu HTTP
- Drawing to the Screen: tạo cửa sổ và vẽ canvas
- Formatting Text: ngắt dòng từ và khoảng cách dòng
-
Part 2: Viewing Documents
- Constructing an HTML Tree: phân tích và sửa đổi HTML
- Laying Out Pages: layout inline và block
- Applying Author Styles: phân tích và áp dụng CSS
- Handling Buttons and Links: hyperlink và chrome của trình duyệt
-
Part 3: Running Applications
- Sending Information to Servers: gửi biểu mẫu và web server
- Running Interactive Scripts: thay đổi DOM và phản hồi sự kiện
- Keeping Data Private: cookie, đăng nhập, XSS, CSRF
-
Part 4: Modern Browsers
- Adding Visual Effects: blending, clipping, compositing
- Scheduling Tasks and Threads: event loop và pipeline dựng hình
- Animating and Compositing: hoạt ảnh mượt mà với GPU
- Making Content Accessible: nhập liệu bằng bàn phím, phóng to/thu nhỏ, cây trợ năng
- Supporting Embedded Content: hình ảnh, iframe, scripting
- Reusing Previous Computation: invalidation, chỉnh sửa, độ chính xác
-
Kết lại và phụ lục
1 bình luận
Các ý kiến trên Hacker News
Một điểm hay của cuốn sách này là phần riêng nói về “những thứ không làm”
Layout thật sự khó, và chỉ xử lý bảng mà không có CSS cũng đã khó rồi. Khi thêm cả CSS vào, layout trở nên phức tạp đến mức gần như bất khả thi
Tôi tự hỏi liệu có ai có thể giữ toàn bộ đặc tả CSS cùng các hành vi liên quan trong đầu hay không. CSS+HTML+JavaScript hiện nay đã gần giống một ngôn ngữ công nghệ trang động (PDL), và có khả năng là một trong những phần mềm phức tạp nhất ngày nay
Nói thêm thì giải mã video được offload sang phần cứng nên không còn ngốn pin nhiều như trước
Ví dụ, tệp này chỉ triển khai context block/inline; tuy cũng có một chút boilerplate Rust, nhưng phần lớn là logic thực sự xử lý nhiều phần của đặc tả. Cả một thư mục đầy những tệp như thế này: https://github.com/servo/servo/blob/main/components/layout/f...
Dù vậy, vẫn có thể triển khai một layout engine. CSS không phải phép thuật; nó có đặc tả có thể được chuyển thành mã một cách cẩn thận. Cho những người bực bội vì CSS trông có vẻ tùy tiện xem loại mã này sẽ giúp họ hiểu rằng môi trường chạy cũng có logic của nó
Tất nhiên sẽ không thường xuyên bấm vào xem như khi xem triển khai của một thư viện, nhưng ở khía cạnh đó tôi nghĩ nó cũng không quá khác với những thứ như React
Thứ nhất, phần cốt lõi nhất của layout như CSS 2 được thiết kế khá lỏng lẻo, và các tính năng kỳ quặc tương tác với nhau theo những cách kỳ quặc. Chẳng hạn như float và clearance, gộp margin. Một số phần cốt lõi này được dự định dùng phổ quát cho mọi chế độ layout, nhưng lại không phù hợp lắm với các chế độ khác. Ví dụ margin và padding không có mục đích rõ ràng trong các phần tử grid
Thứ hai, nó không được module hóa tốt như JavaScript API. JavaScript API thường được triển khai độc lập, nhưng các module layout có thể lồng vào nhau theo nhiều cách nên tất cả đều ảnh hưởng lẫn nhau. Các đặc tả mới hơn như grid đang cố trở nên chặt chẽ hơn, nhưng vẫn có vấn đề căn bản là nhiều chế độ layout phải chia nhau một tài nguyên chung là màn hình 2D thực tế
Chắc chắn tôi không phải người duy nhất muốn có một ngôn ngữ layout đơn giản hơn CSS nhưng vẫn phản ánh các bài học của 20 năm qua, tối đa hóa tích giữa sự đơn giản và sức biểu đạt. Tôi tự hỏi liệu có dự án nào đang nghiêm túc thiết kế thứ như vậy không, hay mọi người đều đã chấp nhận CSS3 và chờ backend LLVM, hoặc đơn giản là quay về văn bản thuần túy
https://github.com/facebook/yoga
Layout không cần phải phức tạp đến vậy. Có hàng chục GUI framework với hệ thống layout đơn giản hơn, và chúng là đủ cho các ứng dụng mà mọi người dùng
Trông tuyệt đấy. Khoảng 15 năm trước, tôi bắt đầu làm một trình duyệt headless và duy trì nó trong vài năm
Tôi dùng SpiderMonkey làm trình thông dịch JavaScript và tự triển khai DOM. Nó chạy được mọi thứ như JavaScript mới nhất thời đó và AJAX, sau này còn thêm cả runtime Flash tùy chỉnh. Đó là một dự án gần như làm mọi thứ trừ việc vẽ lên màn hình, nên thật sự rất thú vị
Tôi rất muốn đọc cuốn sách này
Mình vui vì kỹ thuật trình duyệt giờ có vẻ đang trở thành một xu hướng
Hệ sinh thái thực ra đang ở trạng thái khá nghèo nàn, gần như chỉ do Google, Apple và Mozilla định nghĩa. Trong tương lai, mình muốn thấy có nhiều engine trình duyệt độc lập hơn
Lĩnh vực thú vị là công nghệ UI/tài liệu phi HTML. Typst trong một thread khác giống như một LaTeX tốt hơn, và Markdown cũng đã tạo ảnh hưởng lớn. Vẫn còn nhiều dư địa để tạo ra “HTML nhưng tốt hơn”. Nó cũng không nhất thiết phải là một định dạng markup. Typst và React HTML làm mờ ranh giới giữa code và dữ liệu, còn Jetpack Compose cho thấy cách dùng tính năng DSL của Kotlin để tạo ra thứ trông như mô tả UI nhưng thực ra là code
Tất nhiên, để làm vậy thì phải phân phối một ‘trình duyệt’ cho định dạng đó, hoặc tìm cách hiển thị nó trong trình duyệt hiện có. Dù vậy, việc biên dịch sang JavaScript/HTML/WASM là khả thi. Cũng có thể dùng một bộ công cụ GUI khả chuyển như JavaFX, đồng thời có được accessibility. Hoặc làm cả hai
Nếu tự định nghĩa ngôn ngữ UI của mình, bạn có thể thử nhiều thứ mà HTML làm không tốt. Tiêu biểu là tách nội dung khỏi style. HTML đã thử nhưng rốt cuộc không bao giờ làm được đúng nghĩa, còn XSL:T thì cố gắng hơn nhưng lại là một ngôn ngữ thuần hàm kỳ lạ dùng cú pháp XML. React khá giỏi trong việc biến JSON thành các hộp, nhưng giao thức nền bên dưới luôn là kiểu chắp vá tạm bợ, nên khó xây dựng công cụ hữu ích phía trên nó
Một ý tưởng khác là cũng có thể có một định dạng mặc định miễn nhiễm với XSS
Tuy nhiên mình muốn có lựa chọn thay thế cho HTML. Nếu mình làm trình duyệt, có lẽ mình sẽ tập trung thay thế HTML vì không chịu nổi nó, và cũng muốn thay JavaScript vì runtime quá nặng
Ví dụ một trình duyệt gần như không có JavaScript runtime và chỉ chạy WASM thì chắc sẽ khá buồn cười
Mình là một trong các tác giả của cuốn sách này. Cảm ơn những lời tốt đẹp, nếu có câu hỏi thì mình có thể trả lời
Mình tò mò về quá trình khiến các bạn chọn Python làm ngôn ngữ triển khai trình duyệt. Có vẻ JavaScript thông qua Node có thể đã mang lại trải nghiệm lập trình liên quan hơn
Bài viết giải thích vì sao tác giả chọn Python: https://browserbook.substack.com/p/why-python
Một phần có vẻ được biên dịch từ Python sang JavaScript, nên giờ chạy được ngay trong trình duyệt, tức là “trong chính cuốn sách”
https://browserbook.substack.com/p/compiling-python-to-js
Hy vọng sau khi đọc xong mình có thể quay lại và nói chuyện có ý nghĩa hơn
Thật sự rất hào hứng khi thấy những tài liệu như thế này được tạo ra
Trình duyệt trông như những hộp đen bí ẩn, không thể giải mã, và có lẽ Google cũng rất có khả năng muốn chúng được nhìn nhận như vậy. Nhưng nhìn vào nỗ lực và kết quả của các dự án như Ladybird, bức tường đó đang bắt đầu rạn nứt
Một ngày nào đó mình muốn tự nhảy vào và đóng góp để phá vỡ cái hào phòng thủ đó, và cuốn sách này có vẻ là một điểm khởi đầu tuyệt vời
Firefox đã tồn tại rồi. Chỉ là hầu như không ai dùng, và khi gặp website không chạy trên Firefox, người dùng đã học cách đơn giản là mở Chrome
Đóng góp cho các engine trình duyệt như Ladybird với hy vọng phá vỡ cái hào đó nghe thì vui, nhưng khó có thể nói chỉ riêng việc đó là đóng góp vào việc phá hào. Mình muốn biết điều gì mới thực sự có ích
Ngược lại, những người làm việc ở Chrome, Firefox, Safari và Ladybird đều có vẻ rất hào hứng khi nói về trình duyệt và cách chúng hoạt động. Thế giới phát triển trình duyệt nhỏ hơn bạn nghĩ, và các kỹ sư cũng thường xuyên chuyển qua lại giữa các công ty, nên có lẽ khó duy trì một “âm mưu” nào đó
Tuy nhiên đúng là tài liệu giáo dục thực sự còn thiếu. Vì vậy chúng tôi đã viết cuốn sách này, và đặc biệt cũng thiếu một bộ từ vựng chung để thảo luận về nội bộ trình duyệt ở các bước cốt lõi như layout và rasterization. Chris và tôi muốn dùng cuốn sách này để tạo ra nền tảng đó
Mình đang tìm một dự án thú vị để bắt đầu, và hiện đã đọc cuốn sách này rất vui. Mình đặc biệt thích vì lối viết rất cuốn hút
Cuốn truyện tranh này giải thích Chrome hoạt động thế nào cũng là tài liệu tốt để bắt đầu: https://www.google.com/googlebooks/chrome/med_00.html
Mình đang học về cấu trúc bên trong trình duyệt, và cuốn sách này rất tuyệt
Nó giúp xây dựng trực giác về cách trình duyệt hoạt động mà không cần đào sâu vào hàng triệu dòng code của Chrome
Không rõ có mã khuyến mãi dành cho HN không
Trước đây tôi từng dùng HTMLUnit [1] cùng với Jython [2] và khá hài lòng; trong tương lai, tôi rất quan tâm đến khả năng tự động tạo một phần mã của trình duyệt bằng các kỹ thuật sinh mã và kiểm chứng. Tôi tôn trọng các công cụ như Playwright/Cypress/Selenium, nhưng chưa từng thấy công cụ nào đem lại cảm giác tiện như HTMLUnit
[1] https://htmlunit.sourceforge.io/
[2] https://www.jython.org/
Đây là một cuốn sách hay. Tôi khuyên nên tách chương 9 thành hai chương
Phần chạy JavaScript bằng Duktape nên để thành một chương, còn phần tương tác với DOM và sự kiện nên để thành một chương riêng sau đó
Càng về sau các chương càng dài và đề cập đến những chủ đề nâng cao hơn; khi đọc sách, tôi khuyên nên vừa đọc vừa làm theo phần mã nguồn