بطء في تصفح المواضيع الطويلة
السلام عليكم
حاسوبي امكانياته متوسطة وانا دائما افتح برامج كثيرة اثناء تصفحي والعديد من الصفح وربما اشغل صوت
لكن لاحظت اني لااتسطيع النزول الي الاسفل في الصفح الطويلة مثل
بطء جداً بعد التحديث قمت بايقاف javascript ولاحظت الفرق اظن المشكلة من طريقة حساب الموقع في الصفحة اثناء النزول .
حاولت رؤية الكود المصدري لكنه لالسف اصدار minify لم استطع معرفة المشكلة تحديداً .
التعليقات
السلام عليكم،
قمت بتحسين الاداء والذاكرة، يرجى التجريب.
من باب الفائدة النظرية والاستمتاع العلمي، احب ان اناقشكم بالحل الذي استعملته وهو حاليا متعلق بال scroll، لكن كبداية هل انتم مهتمون بحساب التعقيد الرياضي للخوارزمية؟
من يقدم حلولا ولو نظرية، فسيكون له مفاجأة جميلة من فريق حسوب التقني، قد تكون منتهية بالتوظيف :)
قمت بتحسين الاداء والذاكرة، يرجى التجريب.
نعم اصبحت سريعة لكن يمكن ان تكون اسرع
هناك حل استخدمته من قبل عن طريق تاخير العمل لمدة 400 من الالف من الثانية باستخدام دالة setTimeout
وكنت اقوم بحفظه في متغير بحيث اذا تم النزول اكثر من مرة في زمن اقل من 400 من الالف من الثانية تعمل مرة واحدة مثال
window.addEventListener("scroll",function(){
if(typeof myVar !== "undefined")
window.clearTimeout(myVar)
myVar = setTimeout(function(){console.log("work one")},400);
});
ستلاحظ انها تعمل مرة واحدة فقط .
اعجبني هذا الحل وقد طبقته حالا، علما اني كنت افكر في شيء مختلف عن فكرة ال debouncing.
الآن لنفترض جدلا ان لديك ١٠٠ تعليق تحتاج لسبرهم كل فترة، هل لديك افكار كيف يمكن ان نجد التعليق الحالي الموافق لموضع النافذة باكبر سرعة خوارزمية ممكنة؟
جرب هذا
c_h = [];
c_top = $("#post-comments").offset().top;
for(var i=0;i<=$(".comment").length;i++) {
if($(".comment")[i]) c_h[i] = [$($(".comment")[i]).offset().top,$($(".comment")[i]).offset().top + $($(".comment")[i]).height()];
}
function getpost(){
var top = $(document).scrollTop() + $(".siteHeader").height();
if(c_top >= top) return 0;
if(c_h[c_h.length-1][1] <= top) return c_h.length;
for(i in c_h) if(c_h[i][0] >= top) return i;
}
window.addEventListener("scroll",function(){
if(typeof time_w !== "undefined")
window.clearTimeout(time_w)
time_w = setTimeout(function(){console.log(getpost())},400);
});
استخدمت jquery
كان يمكنني التقديم افضل لو كنت متفرغ :)
اريد حلا اسرع حسابيا، اتحدث عن :
بناءا على حلك، لو عندي ١٠٠ تعليق فساحتاج إلى ١٠٠ * ١٠٠ من التعقيد الحسابي، اي ١٠٠٠٠ عملية حسابية.
المشكلة تقع في هذا السطر تحديدا:
for(i in c_h) if(c_h[i][0] >= top) return i;
حيث سيتم تكراره مع كل معالجة للاحداث. فإذا افترضنا انه وبعد ال debouncing استطعنا خلق حدث لكل تعليق، فحينها لدينا ١٠٠ حدث، وتقريبا احتاج لمسح كل المصفوفة لكل حدث. ومنه ١٠٠*١٠٠
لم اجد حلاً رياضياً لكني وجدت فكرة يتم تقسيم التعليقات داخل مصفوفة كل 100px اي ستكون 4 تعليقات علي الاكثر داخل كل 100px ومسحها بدل من مسح ال100 تعليق فكرة مثل
c_h = {};
c_h.length = $(".commentMsg").length;
c_top = $("#post-comments").offset().top;
c_last = c_top + $("#post-comments").height();
for(var i=0;i<=$(".comment").length;i++) {
if(!$(".commentMsg")[i])
continue;
var c = $($(".commentMsg")[i]);
var from = parseInt(c.offset().top/100);
var to = parseInt(parseInt(c.offset().top+c.height())/100);
for(o=from;o<=to;o++){
(typeof c_h[o] != "object") && (c_h[o] = []);
c_h[o].push([c.offset().top,i+1]);
}
}
function getpost(){
var top = $(document).scrollTop() + $(".siteHeader").height();
if(c_top >= top) return 0;
if(c_last <= top) return c_h.length;
var id = parseInt(top/100);
for(i in c_h[id]) if(c_h[id][i][0] <= top) return c_h[id][i][1];
}
window.addEventListener("scroll",function(){
if(typeof time_w !== "undefined")
window.clearTimeout(time_w)
time_w = setTimeout(function(){console.log(getpost())},400);
});
مازال التعقيد من رتبة o(n^2). وهو تعقيد عالي الكلفة فانت قد تصل ل ٢٥٠٠ عملية حسابية. لكنه حل افضل بلا شك.
ما رأيك لو اصبح الحل من رتبة ١٠٠ * ٧ ، او O(nlogn)
حيث تستطيع ب log(n) من العمليات ان تبحث عن المراد، فاذا كان لديك ١٢٨ تعليق تستطيع الوصل للتعليق الصحيح ب ٧ خطوات فقط :)
لماذا لا تستخدم :
بفحص النص المصدري يبدو أن هناك وظيفة مرتبطة بحدث scroll تحسب موضع التعليق لعرضه في أعلى الصّفحة، والتي يجب أن تنفّذ في كل مرّة يُمرَّر فيها المستخدم الصّفحة، وهو أمر يظهر تأثيره على الأداء كلّما ازداد طول الصّفحة (عدد مرّات انطلاق الحدث يزداد).
ألا تظن أنّه من الأفضل إطلاق event كل مرة يمر المتصفح على تعليق ما بدل الاستماع إلى scroll والمقارنة هل وصل بعد أم لا؟