يعد تعديل أداء المنتج جزءًا مهمًا من دورة تطوير Microsoft. يعد ضبط الأداء أيضًا أحد المجالات الرئيسية التي يجب على المطورين الاهتمام بها. بعد سنوات من التطوير، تعلمت الصناعة الكثير حول كيفية تحسين أداء برامج Win32.
إحدى المشكلات التي يواجهها المطورون اليوم هي أنهم لا يفهمون تمامًا الأسباب التي تجعل صفحات DTHML وHTML تعمل بسرعة أو ببطء. وبطبيعة الحال، هناك بعض الحلول البسيطة - مثل عدم استخدام صور بحجم 2 ميجابايت. لقد استخدمنا بعض التقنيات الأخرى المثيرة للاهتمام لتحسين أداء صفحات DHTML ونأمل أن تساعدك في تحسين أداء صفحاتك.
أستخدم هنا مثالاً لبرنامج لإنشاء جدول. يتم استخدام التابعين document.createElement() و element.insertBefore() لإنشاء جدول يحتوي على 1000 صف (صف). يحتوي كل صف على عمود واحد (خلية). المحتوى الموجود في الخلية يسمى "النص". ما مدى سوء هذا الرمز؟ ما هو مقدار مساحة التعديل التي يتمتع بها مثل هذا البرنامج الصغير؟ يرجى الاطلاع على المقدمة.
في البداية، كتبت برنامجًا اعتقدت أنه سيكون سريعًا، وحاولت تجنب بعض المشكلات ذات المستوى المنخفض، مثل عدم تحديد المتغيرات بشكل صريح، أو استخدام VBScript وJavaScript في نفس الوقت في صفحة واحدة. البرنامج كالتالي:
<html>
<الجسم>
<النص البرمجي>
فار tbl، tbody، tr، td، text، i، max؛
max = 1000;
tbl = document.createElement("TABLE");
tbl.border = "1";
tbody = document.createElement("TBODY");
tbl.insertBefore(tbody, null);
document.body.insertBefore(tbl, null);
ل(i=0;i<max;i++) {
tr = document.createElement("TR");
td = document.createElement("TD");
text = document.createTextNode("Text");
td.insertBefore(text, null);
tr.insertBefore(td, null);
tbody.insertBefore(tr, null);
}
</script>
</الجسم>
</html>
قم بتشغيل هذا البرنامج على جهاز ذو ذاكرة PII233/64 ميجابايت/NT4.0/IE5.0. يتم تحميل الصفحة من هذا الجهاز. الوقت من بدء تحميل الصفحة إلى هدوء الصفحة تمامًا (تم تشغيل جميع الأحداث واكتمل عرض الشاشة) هو 2328 مللي ثانية، وهو أيضًا خط الأساس لهذا الاختبار (أسميه Test1).
في هذه الصفحة، هناك عملية تستغرق وقتًا طويلاً للغاية وهي الرجوع بشكل متكرر إلى الكائنات العامة، مثل "المستند"، و"النص الأساسي"، و"النافذة"، وما إلى ذلك. إن الإشارة إلى كل هذه المتغيرات العالمية المماثلة هي أكثر تكلفة بكثير من الإشارة إلى متغير محلي واحد.
لذلك قمت بمحاولة التحسين الأولى: تخزين المستند (Cache) document.body في المتغير المحلي "theBody":
أضف الكود التالي:
var theBody = document.body;
ثم قم بتعديل هذا السطر:
document.body.insertBefore(tbl, null);
قم بتغييره إلى:
theBody.insertBefore(tbl, null);
عرض العينة الثانية
لم يؤثر هذا التعديل على الوقت الإجمالي كثيرًا، بل اختصر 3 مللي ثانية فقط. ولكن تبين أنه إذا كان هناك أيضًا كائن document.body في الحلقة وتم تعديل مرجعه، فستكون الفوائد كبيرة.
بعد ذلك، قمت بتخزين كائن المستند مؤقتًا - في الاختبار الذي أجريناه، تمت الإشارة إلى كائن المستند إجماليًا 3002 مرة. الكود المعدل هو كما يلي:
<html>
<الجسم>
<النص البرمجي>
فار tbl، tbody، tr، td، text، i، max؛
الحد الأقصى = 1000؛
var theDoc = document;
var theBody = theDoc.body
tbl = theDoc.createElement("TABLE");
tbl.border = "1";
tbody = theDoc.createElement("TBODY");
tbl.insertBefore(tbody, null);
theBody.insertBefore(tbl, null);
ل(i=0;i<max;i++) {
tr = theDoc.createElement("TR");
td = theDoc.createElement("TD");
text = theDoc.createTextNode("Text");
td.insertBefore(text, null);
tr.insertBefore(td, null);
tbody.insertBefore(tr, null);
}
</script>
</الجسم>
</html>
عرض العينة الثالثة.
وقت التشغيل هذا هو 2100 مللي ثانية فقط، مما يوفر حوالي 10% من الوقت. أدى استخدام المتغيرات المحلية بدلاً من الرجوع مباشرةً إلى كائن المستند إلى توفير متوسط قدره 0.4 مللي ثانية في كل مرة.
إحدى الطرق الشائعة لتحسين الأداء هي تعيين سمة "التأجيل" في علامة <SCRIPT> عندما لا يلزم تشغيل البرنامج النصي على الفور. (البرنامج النصي المباشر غير موجود في كتلة دالة، لذلك سيتم تنفيذه أثناء عملية التحميل.) بعد تعيين السمة "التأجيل"، لا يتعين على IE الانتظار حتى يتم تحميل البرنامج النصي وتنفيذه. بهذه الطريقة سيتم تحميل الصفحة بشكل أسرع. بشكل عام، هذا يعني أيضًا أنه من الأفضل وضع البرامج النصية الفورية في كتل الوظائف والتعامل مع الوظيفة في معالج التحميل للمستند أو الكائن الأساسي. تكون هذه الخاصية مفيدة عندما تكون هناك بعض البرامج النصية التي يلزم تنفيذها بناءً على إجراءات المستخدم - مثل النقر فوق زر أو تحريك الماوس إلى منطقة معينة. ولكن عندما تكون هناك بعض البرامج النصية التي يجب تنفيذها أثناء أو بعد تحميل الصفحة، فإن فوائد استخدام سمة التأجيل ليست كبيرة.
ما يلي هو النسخة المعدلة من التعليمات البرمجية باستخدام سمة التأجيل:
<html>
<body onload="init()">
<تأجيل البرنامج النصي>
وظيفة الحرف الأول () {
فار tbl، tbody، tr، td، text، i، max؛
الحد الأقصى = 1000؛
var theDoc = document;
var theBody = theDoc.body
tbl = theDoc.createElement("TABLE");
tbl.border = "1";
tbody = theDoc.createElement("TBODY");
tbl.insertBefore(tbody, null);
theBody.insertBefore(tbl, null);
ل(i=0;i<max;i++) {
tr = theDoc.createElement("TR");
td = theDoc.createElement("TD");
text = theDoc.createTextNode("Text");
td.insertBefore(text, null);
tr.insertBefore(td, null);
tbody.insertBefore(tr, null);
}
}
</script>
</الجسم>
</html>
عرض العينة الرابعة
زمن هذا الاختبار هو 2043 مللي ثانية. وهذه زيادة بنسبة 12% مقارنة بالاختبار الأساسي وأعلى بنسبة 2.5% عن الاختبار السابق.
طريقة التحسين التي نتحدث عنها أدناه مفيدة جدًا بالطبع، ولكنها أكثر إزعاجًا بعض الشيء. عندما تحتاج إلى إنشاء عنصر ثم إدراجه في بنية تشبه الشجرة، فمن الأفضل إدراجه مباشرة في الجذع - بدلاً من إدراجه أولاً في شجرة فرعية كبيرة ثم إدخال الشجرة الفرعية الكبيرة في الجذع. على سبيل المثال، إذا قمت بإنشاء جدول يحتوي على عمود واحد في كل صف وبعض النص في العمود، فيمكنك القيام بذلك:
1. إنشاء <TR>
2. إنشاء <TD>
3. إنشاء عقدة TextNode
4. إدراج TextNode في <TD >
5 . أدخل <TD> في <TR>
6. أدخل <TR> في TBODY
عندما يكون أبطأ من الطريقة التالية:
1. أنشئ <TR>
2. أنشئ <TD>
3. أنشئ عقدة نصية
4. أدخل <TR> أدخل في TBODY
5. أدخل <TD> في <TR>
6. أدخل TextNode في <TD>
تستخدم الاختبارات الأربعة المذكورة أعلاه الطريقة السابقة. استخدمنا الطريقة الأخيرة للاختبار الخامس. الكود كالتالي:
<html>
<body onload="init()">
<تأجيل البرنامج النصي>
وظيفة الحرف الأول () {
فار tbl، tbody، tr، td، text، i، max؛
الحد الأقصى = 1000؛
var theDoc = document;
var theBody = theDoc.body
tbl = theDoc.createElement("TABLE");
tbl.border = "1";
tbody = theDoc.createElement("TBODY");
tbl.insertBefore(tbody, null);
theBody.insertBefore(tbl, null);
ل(i=0;i<max;i++) {
tr = theDoc.createElement("TR");
td = theDoc.createElement("TD");
text = theDoc.createTextNode("Text");
tbody.insertBefore(tr, null);
tr.insertBefore(td, null);
td.insertBefore(text, null);
}
}
</script>
</الجسم>
</html>
عرض العينة الخامسة
يستغرق 1649 مللي ثانية فقط. يعد هذا تحسنًا بنسبة 25% مقارنة بالاختبار الأخير وأسرع بنسبة 30% تقريبًا من خط الأساس.
تم إجراء التعديلات اللاحقة باستخدام أوراق الأنماط المعدة مسبقًا. عرض عمود الجدول الذي يستخدم ورقة أنماط معدة مسبقًا أو يتم تعيينه من خلال علامة <COL> عندما لا يكون هناك علامة <COL>، يتم توزيع عرض كل عمود بالتساوي. نظرًا لعدم الحاجة إلى إعادة حساب حجم كل عمود، وما إلى ذلك، فإن استخدام ورقة الأنماط يؤدي فعليًا إلى تحسين الأداء، خاصة عندما يكون عدد الأعمدة في الجدول كبيرًا.
رمز إضافة ورقة أنماط (CSS) بسيط للغاية، كما يلي:
tbl.style.tableLayout = "fixed";
عرض النموذج السادس
نظرًا لأن الجدول الموجود في اختبارنا يحتوي على عمود واحد فقط، فقد أدى هذا التغيير إلى تحسين أداء الصفحة بنسبة 1.6% فقط. إذا كان هناك المزيد من الأعمدة، فإن زيادة الأداء ستكون أكبر.
أدى الاختباران الأخيران إلى تغيير طريقة إدراج النص في الجدول. في الاختبارات السابقة، قمنا أولاً بإنشاء TextNode ثم أدخلناه في TD. في Test7، بدلًا من ذلك، نحدد النص المضمن عبر النص الداخلي. الكود المعدل هو:
td.innerText = "Text";
شاهد العينة السابعة،
والمثير للدهشة أن الفارق الذي أحدثه هذا التعديل كان هائلاً - تحسن في الأداء بنسبة 9% مقارنة بالمرة الأخيرة، وإجمالي تحسن في الأداء بنسبة 36% مقارنة بالنسخة الأصلية. يتراوح الوقت من أول 2323 مللي ثانية إلى آخر 1473 مللي ثانية.
الآن، يعلم الجميع تقريبًا أن استخدام element.innerHTML بطيء جدًا لمعرفة مدى بطئه، قمت بإجراء اختبار أخير: إدراج النص باستخدام InternalHTML بدلاً من InternalText. وهذا يقلل بشكل كبير من الأداء. وصل الوقت إلى 3375 مللي ثانية، وهو أبطأ بنسبة 80% من الاختبار الأخير وأبطأ بنسبة 45% من الاختبار الأساسي. من الواضح أن لغة HTML الداخلية تستغرق وقتًا طويلاً للغاية.
ضبط أداء صفحة HTML يشبه ضبط أداء تطبيق Win32؛ فأنت بحاجة إلى معرفة ما هو بطيء وما هو سريع. آمل أن تساعدك هذه الطرق في تحسين أداء الصفحة.