Skip to content

ما هو Virtual DOM ؟

ما هو Virtual DOM ؟

29 ماي 2017 | 00:00

كثر الحديث في العامين الماضيين، بالتحديد منذ ظهور مكتبة React.js، عن Virtual DOM وعن دوره الكبير والفعال في جعل التحديثات والتغييرات التي تتم على تطبيقات الويب أحادية الصفحة Single Page Applications أكثر سرعة وانسيابية.

الإشكالية

في تطبيقات الويب الحديثة أصبحنا نتكلم كثيرا عن معالجة DOM لتحديث صفحات التطبيق وبعث الروح فيها. الإشكال هنا أن معالجة DOM بطيئة مقارنة مع عمليات الجافاسكريبت الأخرى.

تخيل أنه لدينا لائحة <ul> تضم 10 عناصر، إذا قمنا بتغيير أو حذف عنصر واحد فقط فإن معظم إطارات عمل الجافاسكريبت التي لا تعتمد على ال Virtual DOM تقوم بإعادة بناء اللائحة كاملة وإظهارها للمستخدم بعد تغيير عنصر واحد فقط، أي أن 9 عناصر بقيت كما هي ولم يكن من داع أبدا لمعالجتها مادام التغير يشمل عنصر واحد فقط. لن تلاحظ انخفاظا في أداء التطبيق إذا كان يحتوى على عدد محدود فقط من العقد Nodes، ولكن في التطبيقات الكبيرة والمعقدة، التي تحتوي على الآف العناصر، قد يكلفها كل هذا الجهد، المبدول في معالجة عقد لم يتم إجراء أي تحديث عليها من طرف المستخدم، ثمنا غاليا يظهر جليا في انخفاض الأداء والسرعة وكذا في سلالستها.

Virtual DOM

في DOM الحقيقي أو الأصلي، يتم تقديم عنصر أو عقدة معينة على هذا النحو :

<ul id="my-list">
  <li>Item 1</li>
  <li>Item 2</li>
  <ul></ul>
</ul>

وفي كل مرة يتم إضافة عنصر <li> مثلا لهذه القائمة، يتم البحث عن العنصر <ul> ويتم إضافة العنصر الجديد <li> إليه :

document.getElementById('my-list').appendChild(myNewNode);

عملية البحث المتكررة هذه تسبب مشاكل في الأداء للتطبيق كلما زاد حجمه وتضاعف عدد عناصر HTML فيه. لهذا جاء ال DOM الوهمي على شكل واجهة موازية ل DOM الأصلي Real DOM ولكن على شكل كائنات جافاسكريبت، وهذا مثال لما يمكن أن يكون عليه ال Virtual DOM :

Let domNode = {
tag: 'ul'
attributes: { id: 'my-list' }
children: [
// هنا عناصر <li>
]
};

هذا شكل القائمة السابقة في ال Virtual DOM، ولو أردنا القيام بإضافة عنصر جديد إليها فسيتم ذلك بهذه الطريقة :

domNode.children.push('<li>Item 3</li>');

هنا القائمة <ul> تم تقديمها على شكل كائن جافاسكريبت سميناه domNode، والوصول إلى هذا الكائن وتحديثه في الجافاسكريبت أسرع بكثير من عملية البحث عن القائمة <ul> بواسطة document.getElementById. هناك فرق كبير في السرعة والأداء!

الجميل مع ال Virtual DOM كذلك أنه لا يتم إجراء أي تغييرات على واجهة المستخدم إلا إذا طلب منه ذلك، عن طريق الدالة render مثلا في React.js، أي أن العمليات كلها تتم في الذاكرة العشوائية وعندما يحين وقت تحديث الصفحة يقوم ال Virtual DOM بمقارنة نفسه مع حالته التي كان عليها قبل إجراء التغييرات فيعرف بذلك التحديثات التي سيقوم بها على مستوى ال DOM الأصلي، أي أنه يقوم فقط بتحديث العناصر التي يجب عليها أن تحدث :) تسمى هذه العملية Diffing.

Virtual DOM Diffing

وهذا ملخص للعملية برمتها :

  1. المستخدم يقوم بإضافة عنصر جديد للقائمة <ul>.
  2. يتم إضافة هذا العنصر <li> للكائن الذي يمثل القائمة في ال Virtual DOM.
  3. ال Virtual DOM يقوم بمقارنة نفسه مع حالته البدئية قبل إضافة العنصر <li>.
  4. ال Virtual DOM يجد بأن التغيير الوحيد حصل على مستوى العنصر <li> الجديد المضاف.
  5. يتم دمج هذا التغيير، وفقط هذا التغيير، في ال DOM الأصلي.
  6. يظهر التغيير على الشاشة للمستخدم.

تظهر فائدة ال Virtual DOM بشكل واضح في المشاريع الكبيرة والمعقدة، إنه إحدى نقاط القوة الرئيسية في إطار العمل React.js الذي طورت به الواجهات الأمامية لموقع فيسبوك والمواقع الأخرى التابعة له، وهذا ما حدى بعدد من المنافسين الآخرين (Vue.js, Ember.js) لتبني هذه الفكرة والإستفادة من قوتها.


عيسى محمد علي
عيسى محمد علي
مطور ويب متخصص في الواجهات الأمامية، أحب التدوين وإغناء المحتوى التقني للغة الضاد وهذا كان السبب الرئيسي في إنشائي لمدونة توتومينا.