Virtual DOM
Bài đăng này đã không được cập nhật trong 3 năm
Intro
Gần đây, có lẽ ai cũng nghe nhiều về Virtual DOM và React JS. Vậy Virtual DOM là gì? Tại sao phải quan tâm đến nó và có gì không ổn với Standard DOM?
DOM (Standard DOM) là gì?
Trước khi nói về Virtual DOM, chúng ta cần tìm hiểu sơ qua về DOM. DOM là viết tắt của chữ Document Object Model, dịch tạm ra là mô hình các đối tượng tài liệu. DOM có dạng một cây cấu trúc dữ liệu, hay nói rõ hơn là 1 “rừng cây” có nhiều “cây”, được dùng để truy xuất các tài liệu dạng HTML và XML. Lấy ví dụ từ 1 tài liệu HTML:
<table>
<tbody>
<tr>
<td>Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr>
<td>Over the River, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
Tài liệu này có thể được đồ thị hoá thành:
Tên "Document Object Model" được chọn vì DOM là 1 mô hình đối tượng (object model) thực sự theo định nghĩa của thiết kế hướng đối tượng: tài liệu được mô hình hoá thành đối tượng và đối tượng này ko chỉ bao gồm cấu trúc của tài liệu mà cả hành vi của tài liệu đó. Nói một cách rõ khác, các node trong biểu đồ trên không thể hiện cấu trúc dữ liệu mà thể hiện các đối tượng có định dạng và chức năng.
Ngày nay thì DOM API gần như đã đa nền tảng và đa trình duyệt. Chúng ta có thể tác động đến DOM bằng việc sử dụng Javascript và CSS. Chúng ta có thể tìm các node và thay đổi chi tiết của chúng, xoá hoặc thêm vào 1 node mới.
Vậy vấn đề nằm ở đâu?
Vấn đề
DOM chưa bao giờ được thiết kế cho việc xây dựng giao diện người dùng động (dynamic UI)
Chúng ta có thể dùng Javascript hay 1 thư viện nào đó như Jquery. Nhưng Jquery chỉ giúp cải thiện một phần nhỏ. Hãy nghĩ đến các trang mạng lớn như Facebook, Twitter hay Pinterest. Chỉ cần sau một vài đoạn kéo xuống thì số node sẽ tăng lên rất nhiều lần (Facebook: 17k+ node, Twitter 30k+ node cho một vài thao tác kéo) và việc xử lý chúng là cả một vấn đề lớn. Bạn có thể tinh chỉnh cũng như dùng một số mẹo để quản lý code của bạn nhưng cuối cùng thì vẫn là các trang tràn ngập code rối như spaghetti.
Hiện tại thì W3C đang trong quá trình phát triển Shadow DOM - tập hợp các cây DOM và các các cây này tương tác lẫn nhau (vấn đề này tôi sẽ nói rõ ở các bài tiếp theo). Trong khi chờ W3C đưa ra một quy định cụ thể về Shadow DOM, một lựa chọn khác là Virtual DOM.
Virtual DOM là gì?
Virtual DOM được xây dựng như 1 lớp nằm trên DOM. Virtual DOM cung cấp một phương tiện bổ trợ cho DOM và hệ thống các sự kiện (events system), thay vì tác động trực tiếp đến DOM. Cụ thể hơn, Virtual DOM được sử dụng để tái thể hiện (re-render) hiệu quả DOM bằng cách sử dụng thuật toán tìm sự khác biệt và chỉ tái thể hiện những thành phần bị thay đổi. Việc này giúp việc thực hiện vô cùng nhanh. React giữ lại 2 phiên bản của 1 Virtual DOM: nguyên bản và bản được cập nhật.
Ví dụ, đây là 2 cây Virtual DOM được chuyển vào một hàm của React, sau đó chúng được so sánh và trả lại luồng thay đổi của DOM
React Virtual DOM dùng như thế nào?
React chia ra 5 loại Virtual DOM chính:
- ReactElement / ReactElement Factory
- ReactNode
- ReactComponent / ReactComponent Class
ReactElement
ReactElement có 4 tính chất là type, props, key và ref. ReactElement không có hàm thực hiện nào. Có thể tạo ReactElement như sau:
var root = React.createElement('div');
Muốn tạo một cây trong DOM, bạn tạo ReactElement và gán nó với Standard DOM:
React.render(root, document.getElementById('example'));
Nếu muốn gán các thuộc tính cho DOM, bạn có thể định nghĩa ở tham số thứ 2 và các ReactElement con ở tham số thứ 3
var child = React.createElement('li', null, 'Text Content');
var root = React.createElement('ul', { className: 'my-list' }, child);
React.render(root, document.getElementById('example'));
Nếu sử dụng JSX thì các ReactElement đã được tạo sẵn.
var root = <ul className="my-list">
<li>Text Content</li>
</ul>;
React.render(root, document.getElementById('example'));
Factories
Factories đơn giản là hàm để tự động tạo ra các ReactElement. Ví dụ:
function createFactory(type) {
return React.createElement.bind(null, type);
}
var div = React.createFactory('div');
var root = div({ className: 'my-div' });
React.render(root, document.getElementById('example'));
ReactNode
ReactNode có thể là:
- ReactElement
- string (ReactText)
- number (ReactText)
- Mảng các ReactNodes (ReactFragment)
ReactComponent
ReactComponent là một Javascript Class (hoặc constructor function)
var MyComponent = React.createClass({
render: function() {
...
}
});
Một số framework khác ứng dụng lý thuyết Virtual DOM
- Elm — “Blazing Fast HTML”
- Mercury — “A truly modular frontend framework”
- Om — “ClojureScript interface to Facebook's React”
- Mithril — “A Javascript Framework for Building Brilliant Applications”
- Ractive — “The diamond age of web development”
- TagTree — “A React-like UI framework in Dart”
- WebSharper.UI.Next — “A new generation of reactive web applications.
Kết luận
Virtual DOM là một kĩ thuật và một tập hợp của các thư viện, thuật toán cho phép nâng cao khả năng của front-end tránh việc xử lý trực tiếp trên DOM mà thay vào đó chỉ làm việc với đối tượng JS mô phỏng nhỏ nhẹ hơn.
Ý tưởng về Virtual DOM là không mới nhưng cách thực hiện không hề dễ. Sử dụng thư viện như React có thể tăng đáng kể hiệu năng hoạt động của ứng dụng và khá dễ để làm quen.
Tham khảo
- https://facebook.github.io/react/docs/glossary.html
- http://madhukaudantha.blogspot.com/2015/04/reactjs-and-virtual-dom.html
- http://fluentconf.com/fluent2014/public/schedule/detail/32395
- http://jbi.sh/what-is-virtual-dom/
- http://wiredcraft.com/blog/why-we-may-ditch-angularjs-for-react/
- http://tonyfreed.com/blog/what_is_virtual_dom
All rights reserved