لقد أدى ظهور AJAX إلى تغيير كبير في وضع تشغيل عملاء تطبيقات الويب، فهو يسمح للمستخدمين بالتركيز على عملهم دون الاضطرار إلى تحمل تحديثات الصفحة المزعجة بشكل متكرر. من الناحية النظرية، يمكن لتقنية AJAX تقليل وقت انتظار عمليات المستخدم إلى حد كبير وتوفير حركة البيانات على الشبكة. ومع ذلك، هذا ليس هو الحال دائما. غالبًا ما يشتكي المستخدمون من انخفاض سرعة استجابة الأنظمة التي تستخدم AJAX.
شارك المؤلف في أبحاث وتطوير AJAX لسنوات عديدة وشارك في تطوير Dorado، وهي منصة AJAX ناضجة نسبيًا في الصين. وفقا لتجربة المؤلف، فإن السبب الجذري لهذه النتيجة ليس AJAX. في كثير من الأحيان يكون سبب الانخفاض في سرعة استجابة النظام هو تصميم الواجهة غير المعقول وعادات البرمجة غير الفعالة. سنقوم أدناه بتحليل العديد من الجوانب التي يجب الاهتمام بها أثناء عملية تطوير AJAX.
الاستخدام السليم لبرمجة العميل واستدعاءات الإجراءات عن بعد.
تعتمد البرمجة من جانب العميل بشكل أساسي على JavaScript. JavaScript هي لغة برمجة مفسرة، وكفاءة تشغيلها أقل قليلاً من كفاءة Java. وفي الوقت نفسه، تعمل JavaScript في بيئة مقيدة تمامًا مثل المتصفح. لذلك يجب أن يكون لدى المطورين فهم واضح للمنطق الذي يمكن تنفيذه من جانب العميل.
تعتمد كيفية استخدام البرمجة من جانب العميل في التطبيقات الفعلية على خبرة المطور وحكمه. لا يمكن فهم العديد من المشاكل هنا إلا. نظرًا للمساحة المحدودة، نلخص هنا تقريبًا الاحتياطات التالية:
تجنب الاستخدام المتكرر لاستدعاءات الإجراءات عن بعد قدر الإمكان، على سبيل المثال، تجنب استخدام استدعاءات الإجراءات عن بعد في أجسام الحلقة.
إذا أمكن، استخدم استدعاء الإجراء البعيد AJAX (استدعاء الإجراء البعيد غير المتزامن).
تجنب وضع عمليات البيانات ذات الوزن الثقيل على جانب العميل. على سبيل المثال: دفعات كبيرة من عمليات نسخ البيانات، والحسابات التي تتطلب كمية كبيرة من اجتياز البيانات، وما إلى ذلك.
تحسين طريقة تشغيل كائنات DOM.
في البرمجة من جانب العميل، غالبًا ما تكون العمليات على كائنات DOM هي الأكثر احتمالاً لاحتلال وقت وحدة المعالجة المركزية. بالنسبة لتشغيل كائنات DOM، غالبًا ما يكون فرق الأداء بين طرق البرمجة المختلفة كبيرًا جدًا.
فيما يلي ثلاث أجزاء من التعليمات البرمجية لها نفس النتائج تمامًا، وتتمثل وظيفتها في إنشاء جدول 10x1000 في صفحة الويب. ومع ذلك، فإن سرعات تشغيلها مختلفة إلى حد كبير.
/* رمز الاختبار 1 - الوقت المستغرق: 41 ثانية*/
var table = document.createElement("TABLE");
document.body.appendChild(table);
for(var i = 0; i < 1000; i++){
صف فار = table.insertRow(-1);
ل(فار ي = 0; ي < 10; ي++){
خلية فار = objRow.insertCell(-1);
cell.innerText = "( " + i + " , " + j + " )";
}
}
/* رمز الاختبار 2 - الوقت المستغرق: 7.6 ثانية*/
var table = document.getElementById("TABLE");
document.body.appendChild(table);
var tbody = document.createElement("TBODY");
table.appendChild(tbody);
for(var i = 0; i < 1000; i++){
فار الصف = document.createElement("TR");
tbody.appendChild(row);
ل(فار ي = 0; ي < 10; ي++){
فار الخلية = document.createElement("TD");
Row.appendChild(cell);
cell.innerText = "( " + i + " , " + j + " )";
}
}
/* رمز الاختبار 3 - الوقت المستغرق: 1.26 ثانية*/
var tbody = document.createElement("TBODY");
for(var i = 0; i < 1000; i++){
فار الصف = document.createElement("TR");
ل(فار ي = 0; ي < 10; ي++){
فار الخلية = document.createElement("TD");
cell.innerText = "( " + i + " , " + j + " )";
Row.appendChild(cell);
}
tbody.appendChild(row);
}
var table = document.getElementById("TABLE");
table.appendChild(tbody);
document.body.appendChild(table);
الفرق بين "رمز الاختبار 1" و"رمز الاختبار 2" هنا هو أنه يتم استخدام أساليب API مختلفة عند إنشاء خلايا الجدول. يكمن الاختلاف بين "رمز الاختبار 2" و"رمز الاختبار 3" في ترتيب المعالجة المختلف قليلاً.
لا يمكننا تحليل هذا الاختلاف الكبير في الأداء بين "رمز الاختبار 1" و"رمز الاختبار 2". ما هو معروف حاليًا هو أن InsertRow وinsertCell عبارة عن واجهات برمجة تطبيقات خاصة بالجدول في DHTML، وأن createElement وappendChild هما واجهات برمجة تطبيقات أصلية لـ W3C DOM. يجب أن يكون الأول عبارة عن تغليف للأخير. ومع ذلك، لا يمكننا أن نستنتج من هذا أن واجهة برمجة التطبيقات الأصلية لـ DOM أفضل دائمًا من واجهة برمجة التطبيقات الخاصة بالكائن. يوصى بإجراء بعض الاختبارات الأساسية على أدائها عندما تحتاج إلى الاتصال بواجهة برمجة التطبيقات (API) بشكل متكرر.
يأتي اختلاف الأداء بين "رمز الاختبار 2" و"رمز الاختبار 3" بشكل أساسي من الاختلاف في ترتيب البناء الخاص بهما. تتمثل طريقة "رمز الاختبار 2" في إنشاء كائن
بالتسلسل في الحلقة. تتمثل طريقة "رمز الاختبار 3" في إنشاء الجدول بأكمله في الذاكرة من الداخل إلى الخارج أولاً، ثم إضافته إلى صفحة الويب. والغرض من ذلك هو تقليل عدد المرات التي يعيد فيها المتصفح حساب تخطيط الصفحة قدر الإمكان. عندما نضيف كائنًا إلى صفحة ويب، يحاول المتصفح إعادة حساب تخطيط عناصر التحكم على الصفحة. لذلك، إذا تمكنا أولاً من إنشاء الكائن بأكمله المراد إنشاؤه في الذاكرة، ثم إضافته إلى صفحة الويب مرة واحدة. بعد ذلك، سيقوم المتصفح فقط بإعادة حساب التخطيط. لتلخيص ذلك في جملة واحدة، كلما قمت بتنفيذ appendChild لاحقًا، كلما كان ذلك أفضل. في بعض الأحيان، من أجل تحسين كفاءة التشغيل، يمكننا حتى التفكير في استخدام RemoveChild لإزالة عنصر التحكم الموجود من الصفحة، ثم إعادة وضعه مرة أخرى إلى الصفحة بعد اكتمال الإنشاء. تحسين سرعة تراكم السلاسل عند استخدام AJAX لإرسال المعلومات، قد أحتاج غالبًا إلى تجميع بعض السلاسل الكبيرة نسبيًا لإكمال إرسال POST من خلال XmlHttp. على الرغم من أن تقديم مثل هذا الكم الكبير من المعلومات قد يبدو غير لائق، إلا أنه في بعض الأحيان قد نضطر إلى مواجهة مثل هذه الحاجة. ما مدى سرعة تراكم السلاسل في JavaScript؟ لنقم بالتجربة التالية أولاً. قم بتجميع سلسلة بطول 30000. /* رمز الاختبار 1 - الوقت المستغرق: 14.325 ثانية*/ فار str = ""; لـ (var i = 0; i < 50000; i++) { str += "xxxxxx"; } استغرق هذا الكود 14.325 ثانية، ولم تكن النتائج مثالية. الآن نقوم بتغيير الكود إلى النموذج التالي: /* رمز الاختبار 2 - الوقت المستغرق: 0.359 ثانية*/ فار str = ""; لـ (var i = 0; i < 100; i++) { فار الفرعية = ""; لـ (var j = 0; j < 500; j++) { الفرعية += "xxxxxx"; } str += sub; } يستغرق هذا الرمز 0.359 ثانية! نفس النتيجة، كل ما نفعله هو تجميع بعض السلاسل الصغيرة أولاً ثم تجميعها في سلاسل أكبر. يمكن لهذا الأسلوب تقليل كمية البيانات المنسوخة في الذاكرة بشكل فعال في المراحل اللاحقة من تجميع السلسلة. بعد معرفة هذا المبدأ، يمكننا تفكيك الكود أعلاه للاختبار. يستغرق الكود أدناه 0.140 ثانية فقط. /* رمز الاختبار 3 - الوقت المستغرق: 0.140 ثانية*/ فار str = ""; لـ (var i1 = 0; i1 < 5; i1++) { فار str1 = ""; لـ (var i2 = 0; i2 < 10; i2++) { فار str2 = ""; لـ (var i3 = 0; i3 < 10; i3++) { فار str3 = ""; لـ (var i4 = 0; i4 < 10; i4++) { فار str4 = ""; لـ (var i5 = 0; i5 < 10; i5++) { str4 += "xxxxxx"; } str3 += str4; } str2 += str3; } str1 += str2; } str += str1; } ومع ذلك، فإن النهج المذكور أعلاه قد لا يكون الأفضل! إذا كانت المعلومات التي نحتاج إلى إرسالها بتنسيق XML (في الواقع، في معظم الحالات، يمكننا محاولة تجميع المعلومات المراد إرسالها بتنسيق XML)، فيمكننا أيضًا العثور على طريقة أكثر كفاءة وأنيقة - باستخدام كائنات DOM للتجميع شخصيات بالنسبة لنا سلسلة. تستغرق الفقرة التالية 0.890 ثانية فقط لتجميع سلسلة بطول 950015. /* استخدم كائنات DOM لتجميع المعلومات - الوقت المستغرق: 0.890 ثانية*/ فار xmlDoc; إذا (نوع المتصفح == BROWSER_IE) { xmlDoc = new ActiveXObject("Msxml.DOMDocument"); } آخر { xmlDoc = document.createElement("DOM"); } var root = xmlDoc.createElement("root"); لـ (var i = 0; i < 50000; i++) { var العقدة = xmlDoc.createElement("data"); إذا (نوع المتصفح == BROWSER_IE) { Node.text = "xxxxxx"; } آخر { Node.innerText = "xxxxxx"; } root.appendChild(node); } xmlDoc.appendChild(root var str); تجنب تسرب الذاكرة لكائنات DOM. |