logo

Đang load dữ liệu

logo devmaster

VIỆN CÔNG NGHỆ VÀ ĐÀO TẠO DEVMASTER

Đào tạo - Phần mềm - Cho thuê nhân sự

  • 0969.609.003
  • 0978.611.889
  • Trang chủ
  • Các khoá đào tạo
    • Chuyên đề WEB - PHP

      • Lập trình web với HTML5 - CSS3- JQuery - Bootstrap - Ajax - [36 giờ]
      • Lập trình web frontend - reactjs - [75 giờ]
      • Lập trình web với mã nguồn mở PHP&MYSQL - PHP FRAMEWORK [126 giờ]

      Chuyên đề Mobile

      • Lập trình Games/Apps trên nền tảng Android - [120 giờ]
      • Lập trình Games/Apps trên nền tảng IOS - [120 giờ]

      Chuyên đề JAVA

      • Ngôn ngữ lập trình hướng đối tượng với java - [40 giờ]
      • Lập trình ứng dụng với java - [100 giờ]
      • Lập trình web site với java framework (JPA, HIBERNATE, SPRING MVC, SPRINGBOOT) - [276 giờ]

      Chuyên đề NETWORK/SECURITY

      • Khoá học Quản trị hạ tầng mạng CCNA v6 - [72 giờ]
      • Khoá học quản trị hệ thống với Windows SERVER 2012- [72 giờ]
      • Chuyên gia bảo mật hệ thống CompTIA + - [110 giờ]

      Chuyên đề .NET

      • Nền tảng lập trình hướng đối tượng với C# - [40 giờ]
      • Lập trình ứng dụng WINDOWS FORM - [100 giờ]
      • Lập trình Web với ASP.NET MVC 5, WebAPI - [145 giờ]

      Chuyên đề khác

      • Ngôn ngũ lập trình C/C++ - [80 giờ]
  • Lập trình cho trẻ em
  • Dịch vụ
    • Đào tạo theo như cầu
    • Cung cấp thiết bị - Phần mềm
    • Tư vấn - Thiết kế mạng hạ tầng
    • Tư vấn - Triển khai dịch vụ mạng
    • Tư vấn - Tư vấn, triển khai giám sát hệ thống
    • Thực tập dự án
  • Lịch khai giảng
  • Tin tức
    • Tin tức và sự kiện
    • Tin hoạt động
    • Tin công nghệ
    • Hội thảo, workshop, Codecam
    • Thông tin việc làm
    • Cẩm nang chia sẻ kiến thức
  • Tiện ích
  • Liên hệ

Cẩm nang chia sẻ kiến thức

Jul - 2019

17

Original DOM vs. Shadow DOM vs. Virtual DOM

Cẩm nang chia sẻ kiến thức

Original DOM vs. Shadow DOM vs. Virtual DOM

Với các bạn tìm hiểu về Web Development, chắc hẳn không xa lạ gì với khái niệm DOM?Hay cụ thể hơn như là Original DOM nhỉ?

Ngoài các trang web nhỏ và vừa ra thì có bao giờ bạn tự hỏi, các trang web lớn như Facebook, Twitter, GMail, etc thì có cả một “rừng cây Amazon” trong source code HTMLcủa mình thì họ quản lý DOM Tree như thế nào không?

Và đương nhiên chỉ với DOM thôi thì các nhà phát triển web khó lòng xử lý hàng núi việc như thế. Từ đó ra đời khái niệm Virtual DOM và Shadow DOM.

Đúng như tiêu đề thì ở bài viết này các bạn hãy cùng mình tìm hiểu sâu hơn về Original DOM, Shadow DOM và Virtual DOM để có được cái nhìn đầy đủ hơn về chúng nhé.

Cùng bắt đầu thôi nào

Original DOM

Overview

Có thể bạn thừa biết, DOM là viết tắt của Document Object Modal.

DOM bao gồm:

  • Object-based representation of the HTML document

    Các phần tử trong DOM có cấu trúc được định nghĩa thành các đối tượng, có các phương thức, thuộc tính để có thể truy xuất dễ dàng.

    Chúng được coi như các node và được biểu diễn dưới dạng DOM Tree.

<html>             -> document node

<head>            -> element node - head

   <title>

     HTML DOM      -> text node

   </title>        -> element node - title

</head>

 

<body>            -> element node - body

</body>

 

</html>

 

  • DOM APIs

    HTML DOM cung cấp các APIs để duyệt và chỉnh sửa các node.

    Ví dụ cụ thể về APIs có thể kể tới như getElementById() dùng để truy xuất một phần tử theo id cũng hay removeChild() dùng để loại bỏ một phần tử con dựa vào phần tử cha của nó.

Shadow DOM

Overview

Mozilla đã tóm tắt 3 đặc điểm cơ bản về Shadow DOM:

Shadow DOM can be thought of as:

  • Isolated DOM
  • A “lite” version of the DOM
  • NOT of a full standalone document

Sở dĩ nói như vậy là do các stylesheet hay javascript từ bên ngoài không-thể-tác-động vào trong Shadow DOM được và ngược lại.

Ví dụ như ta có thẻ  như một custom element.

Cấu trúc của một shadow DOM

Với Shadow DOM chúng ta sẽ có thêm Shadow Root. Nội dung Shadow Root sẽ không được trình duyệt render mà thay vào đó là Shadow Host. Shadow Host được xem như một element bình thường nhưng nội dung bên trong nó (cả stylesheet) sẽ được đóng gói và độc lập với thế giới bên ngoài:

Tạo một shadow DOM

<style> p { color: green } </style>

 

<p id="sd-root">I am Shadow Root</p>

 

<script>

  const host = document.querySelector('#sd-root');

  const root = host.createShadowRoot();

  root.innerHTML = `

    

    <style> p { color: gray }</style>

    

    <p>Hello <strong>Shadow DOM</strong></p>

    

  `;

</script>

Bạn đoán xem, kết quả sẽ là gì nào . . .

Ở đây khi trình duyệt render xong chúng ta sẽ nhận được:

thay vì là

Khi Inspect phần tử lên ta sẽ thấy như thế này đây:

Như vậy, chúng ta sẽ có vài nhận xét như sau:

  • Style bên trong Shadow DOM dù conflict selector với bên ngoài nhưng không sao vì đặc tính của Shadow DOM (scoped style sheet)
  • Khi chúng ta truy xuất .innerHTML() của element #sd-root thì ta CHỈ lấy được đoạn text khởi tạo: “I am Shadow Root” và cũng không-thể-tác-động được gì vào bên trong Shadow Root, cụ thể chính là Shadow Host.

Okay, chúng ta đã rõ hơn về DOM:

  • Phần sáng của nó (hay thường được gọi là Light DOM) là cái chúng ta có thể tương tác được.
  • Phần tối của nó, cái bóng (Shadow DOM) chỉ phản ánh lên nó sẽ được render thế nào khi Light DOM thay đổi.
    Và theo lẽ đương nhiên, ta không-bao-giờ có thể chạm được vào cái bóng của một vật nào cả

DOM ngon vậy thì sao lại có Virtual DOM làm gì nhỉ ?

Mình cùng tìm hiểu tiếp nhé

Virtual DOM

Mặc dù concept này đã xuất hiện từ khá lâu rồi nhưng nó chỉ mới trở nên phổ biến khi được sử dụng trong các thư viện nổi tiếng như ReactJS, VueJS…

Overview

Đúng như tên gọi của nó, DOM-ảo. Ảo, có nghĩa là không thật

Virtual-DOM là một Object chứa các thông tin cần thiết để tạo ra một DOM (Document Object Model).

Virtual DOM có khả năng tính toán, cập nhật các node mà không cần sử dụng DOM APIs. Sau khi cập nhật trên DOM ảo, các thay đổi sẽ được thực hiện với Original DOM.

Như một vài đặc điểm mình đã nêu ở trên, Virtual DOM được xem như một cách hiệu quả để giải quyết vấn đề cập nhật trên DOM, không cần render lại toàn bộ cả DOM Tree.

Dưới đây là đặc tả một DOM Tree:

thành một Virtual DOM:

Trong thực tế, thay vì phải sử dụng toàn-bộ-object, chúng ta thường làm việc với các object-nhỏ-hơn tương ứng với các thành phần của Virtual DOM.

Cơ chế hoạt động

Ban đầu, một đối tượng có nhiệm vụ như một snapshot từ virtual DOM sẽ được tạo ra:

Bản copy này được sử dụng để tạo diff để so sánh với bản virtual DOM ban đầu, về cơ bản thì nó sẽ có dạng như thế này:

Từ đó, giúp Engine biết rằng phải update element nào trong original DOM, chúng chỉ thực hiện update khi có sự thay đổi.

Để thực hiện việc này chỉ cần sử dụng một vòng loop với diff cho dù là thêm một node mới hay update node cũ:

Sau đó, tiến hành cập nhật list, viết lại toàn bộ template, chạy lại hàm render(), hiển thị thay đổi ra ngoài view.

Mặc dù nói là toàn bộ template, song, chỉ những phần thực sự thay đổi mới được cập nhật. Các thay đổi được thực hiện cho đối tượng này sau đó được đối chiếu và sửa đổi đối với original DOM .

Why use Virtual DOM?

Speed

Trước đây mình nghĩ rằng lý do nói sử dụng Virtual DOM nhanh hơn Original DOM là do việc set attribute cho object nó nhanh hơn việc update DOM, nhưng không phải các bạn ạ.

Thực tế là việc cập nhật DOM chẳng tốn nhiều thời gian là bao so với việc cập nhật attribute cho object.

Điều thật sự ảnh hưởng tới speed performance ở đây là khi DOM thay đổi, Browserbuộc phải ngồi tính lại CSS, build layout, paint template…

Vì cấu trúc của DOM là tree structure , khi muốn thay đổi các element và các thẻ con của nó, ta phải thông qua các Reflow/Layout. Từ đó, các thay đổi được sẽ được re-painted. Càng nhiều các item phải reflow/repaint, web của bạn sẽ càng loadchậm

Hmmm…

Để hiểu sâu hơn vấn đề này, chúng ta hãy tìm hiểu thêm một khái niệm nữa đó là về cơ chế binding.

Data-binding

Khái niệm data-binding có thể hiểu đơn giản là:

Data-binding: Data in Model changes <=> View changes.

Data-binding trong DOM thật

Bây giờ ta lướt qua một chút các framework có cơ chế data-binding như BackboneJS, AngularJS, khi dữ liệu của Model Object thay đổi, nó sẽ:

  1. Xác nhận các event + các View Object liên quan
  2. Tác động vào các phần tử DOM trên View và phản ánh sự thay đổi dữ liệu đó.
Data-binding trong DOM ảo

Các framework sử dụng Virtual-DOM, Virtual-DOM vừa đóng vai trò là Model, vừa đóng vai trò là View

Như vậy, khi Virtual-DOM thay đổi, mọi sự thay đổi trên Model đã kéo theo sự thay đổi trên View và ngược lại.

Dù không tác-động-trực-tiếp vào các phần tử DOM ở View nhưng vẫn thực hiện được cơ chế data-binding. Điều này làm cho tốc độ ứng dụng tăng lên đáng kể.

BONUS: Virtual DOM trong ReactJS

Dù phần này có hơi mở rộng so với tiêu đề bài viết một chút , nhưng hôm rồi mình tình cờ đọc được một bài viết về cách ReactJS thao tác với DOM ảo khá thú vị nên bonus vào để chúng mình hiểu sâu hơn về Virtual DOM nhé ^^

Với một thư viện sử dụng DOM ảo như ReactJS, sau khi DOM thật được load lần đầu tiên, DOM ảo cũng được React tạo ra tương ứng với DOM thật bên trên. Trong React, nó cũng được gọi là một Component với tree structure gồm các Component con bên trong.

Lưu ý:

Khi có một state mới được set, React đánh dấu nó như là một dirty Component(nghĩa là mỗi khi chúng ta gọi tới setState() thì Component đó sẽ được đánh dấu là dirty)

Các event khi ta thao tác với DOM được React event listener lắng nghe. Do đó, khi có event nào, event đó sẽ được gửi tới React event listener và sau đó sẽ chạy một anonymous function()

Trong anonymous function(), chúng ta gọi tới this.setState() với một new state value. Sau khi this.setState() được chạy, Component đó được đánh dấu là dirty.

Okay, điều gì xảy ra tiếp theo:

Chạy qua Component lifecycle

Quan trọng nhất trong quá trình update ở đây chính là render(), sau khi xây dựng lại Component, DOM ảo được tạo lại và update DOM ảo để tìm ra sự khác biệt*(như phần Cơ chế hoạt động mình trình bày phía trên)*, từ đó tìm ra cụ thể element thay đổi, và sau đó cập nhật chỉ những element đó ở DOM thật.

Snapshots & Diffing

React lấy một snapshot của Virtual DOM (bản ghi trạng thái ngay lúc đó) ngay trước khi áp dụng bất kỳ bản cập nhật nào. Sau đó, nó sử dụng snapshot này để so sánh với một Virtual DOM được cập nhật trước khi thực hiện các thay đổi.

Khi cập nhật được cấp cho Virtual DOM (Virtual DOM sử dụng key, ref mà ở DOMkhông có và Virtual DOM được tạo mới sau mỗi lần render lại), quá trình tiếp theo React sử dụng thuật toán Diffing để so sánh và đối chiếu để biết được sự cập nhật được diễn ra ở đâu sau đó cập nhật nó mà bỏ qua những elements không liên quan.

Do đó, work-flow của React thao tác với DOM ảo khi có change detection:

  1. Xây dựng lại component
  2. Update DOM ảo
  3. Tìm sự thay đổi
  4. Update DOM thật

Nhờ có DOM ảo, React có thể tìm ra các node bị thay đổi và update ở DOM thật chỉ ở những cái node đó, thật thuận tiện và nhanh gọn phải không nào ^^

Như vậy là chúng ta đã điểm qua Original DOM, Shadow DOM hay Virtual DOM rồi. Hy vọng rằng bài viết này có thể giúp các bạn hiểu hơn về DOM và các vấn đề liên quan.

Nguồn: Devmaster Academy via Viblo 

 

 
 

Các bài viết cùng chủ đề

BÍ QUYẾT HỌC LẬP TRÌNH CHO CÁC BẠN ĐẦU NĂM HỌC MỚI ❤
BÍ QUYẾT HỌC LẬP TRÌNH CHO CÁC BẠN ĐẦU NĂM HỌC MỚI...
5 Phương pháp hay để mở rộng các dự án React của bạn một cách dễ dàng
5 Phương pháp hay để mở rộng các dự án React của b...
Lab06.1 - Data Access In ASPNET MVC 5
Lab06.1 - Data Access In ASPNET MVC 5
Lab05 - Data Validation and Annotation In ASPNET MVC 5
Lab05 - Data Validation and Annotation In ASPNET M...
Lab 04 - Model in ASP.NET MVC 5 - Phần tự thực hành
Lab 04 - Model in ASP.NET MVC 5 - Phần tự thực hàn...
Lab 04 - Model in ASP.NET MVC 5 - Bài 4.2
Lab 04 - Model in ASP.NET MVC 5 - Bài 4.2

Các khóa đào tạo chuyên đề

Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
Lập trình ứng dụng trên nền tảng android Lập trình ứng dụng trên nền tảng android
Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack

Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack
Lập trình ứng dụng với WINDOWS FORM Lập trình ứng dụng với WINDOWS FORM
Lập trình ứng dụng với JAVA (FORM) Lập trình ứng dụng với JAVA (FORM)
Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery
Lập trình frontend với reacjs (Full) Lập trình frontend với reacjs (Full)
Viện Công Nghệ Và Đào Tạo Devmaster

DEVMASTER ACADEMY

Địa chỉ: Tầng 6 - Tòa nhà VIỆN CÔNG NGHỆ
Số 25, Vũ Ngọc Phan - Láng Hạ - Đống Đa - Hà Nội

Hotline: 0969 609 003 | 0978 611 889

devmaster.contact@gmail.com

hna.tvchung@gmail.com

CÁC KHÓA HỌC CHUYÊN ĐỀ

  • Thiết kế và lập trình Website PHP, Laravel chuyên nghiệp - FullStack
  • Lập trình ứng dụng trên nền tảng android
  • Lập trình Ứng dụng với Công nghệ ASP.NET Core MVC, WebAPI, ReactJS - FullStack
  • Lập trình ứng dụng với WINDOWS FORM
  • Lập trình ứng dụng với JAVA (FORM)
  • Thiết kế và lập trình Ứng dụng với công nghệ Java (Java Framework springBoot, hibernate,...) - FullStack
  • Thiết kế và lập trình website với công nghệ HTML5, CSS3, Javascript, Bootstrapt 4, Jquery
  • Lập trình frontend với reacjs (Full)
Viện Công Nghệ Và Đào Tạo Devmaster

VIỆN CÔNG NGHỆ VÀ ĐÀO TẠO DEVMASTER - Học thực tế * Làm thực tế * Cam kết việc làm
Copyright by Ⓒ DEVMASTER 2015