التحميل الكسول في جافاسكربت
مدرج تحت قسم: دروس
تعبير التحميل الكسول أو Lazy Loading في العادة يستعمل في لغات البرمجة، ويطلق عند تأخير تحميل كائن أو عنصر ما لحين حاجته. أي معناه، أننا لا نحمل أي كائنات أو عناصر حتى ولو كان يستخدمها البرنامج في وقت لاحق، إلى حين حاجتنا أو استدعائنا لها في ذلك الوقت، وعندها يتم تسخير كل الموارد المطلوبة للتحميل والاستدعاء.
التحميل الكسول يستخدم في عدة لغات، ولكن في هذا المقال، سنرى كيف يمكننا استخدامه في لغة جافاسكربت على عدد من المكتبات المشهورة YUI ،jQuery ،MooTools، وكيف يمكنه أن يفيدنا.
من أهم استخدامات تقنية التحميل الكسول في لغة جافاسكربت، هي تأخير استدعاء الملفات الخارجية External Scripts، أو الصور، في مستند HTML إلى وقت حاجة المستخدم لها. على سبيل المثال، في الصفحات التي تحتوي صوراً كثيرة، يمكن استخدام هذه التقنية لتأخير تحميل الصور التي تكون في الأسفل والغير مرئية حالياً من قبل المستخدم لعدم كونها في مساحة الرؤية visible area للمتصفح إلى حين نزول المستخدم إليها لرؤيتها.
لماذا التحميل الكسول في جافاسكربت؟
هناك 3 أسباب حقيقة تفيد عند استخدام تقنية التحميل الكسول:
- تحسين سرعة تحميل الصفحة
- تخفيف حمل الصفحة
- تقليل استهلاك معدل نقل البيانات Bandwidth
عند طلب أي ملف سواء كان نصاً أو صورة، فهذا يعني أنه يتم عمل اتصال جديد مع الخادم، وعند الاتصال مع الخادم فإنه يتم استهلاك موارد للإتصال ومعدل نقل البيانات، مما يزيد من حجم ووقت تحميل الصفحة.
بعض الأمثلة التطبيقية لتحميل الصور تحميلاً كسولاً
في هذه الأمثلة التطبيقية، سأقوم بشرح طريقة تطبيق التحميل الكسول على الصور في مستندات HTML. وكما ذكرت سابقاً، التقنية ليست محدودة بالصور، ولكن لتوضيح المفهوم بطريقة جيدة اخترت أن أبين طريقة عملها بالصور.
المثال بدون استخدام التقنية
عرض
تحميل
هذا مثال يتم عرض عدد من الصور المأخوذة من فليكر بترخيص Creative Commons بدون استخدام أي تقنية للتحميل الكسول. وسيتم استخدام نفس المثال لاحقاً ولكن باستخدام التحميل الكسول لمعرفة الفرق بينهم في السرعة وحمل الصفحة.
مثال باستخدام مكتبة YUI
عرض
تحميل
تستخدم مكتبة ياهوو YUI 3 التحميل المتأخر للصور عن طريق أداة ImageLoader. وسنستخدم مثال تأخير تحميل الصور تحت الطيّة Below the fold.
إدراج المكتبة الأساسية
يجب علينا في البداية إدراج المكتبة الأساسية YUI، وعن طريقها يتم تحميل أداة ImageLoader، وسوف نقوم بإدراجها مباشرة من خوادم شركة ياهوو.
<script src="http://yui.yahooapis.com/3.0.0/build/yui/yui-min.js"></script>
تسجيل الصور
var foldGroup = new Y.ImgLoadGroup({ name: 'fold group', foldDistance: 25 });
foldGroup.registerImage({ domId: 'img1', srcUrl: 'http://developer.yahoo.com/yui/docs/assets/examples/exampleimages/small/museum.jpg' });
foldGroup.registerImage({ domId: 'img2', srcUrl: 'http://developer.yahoo.com/yui/docs/assets/examples/exampleimages/small/uluru.jpg' });
foldGroup.registerImage({ domId: 'img3', srcUrl: 'http://developer.yahoo.com/yui/docs/assets/examples/exampleimages/small/katatjuta.jpg' });
foldGroup.registerImage({ domId: 'img4', srcUrl: 'http://developer.yahoo.com/yui/docs/assets/examples/exampleimages/small/morraine.jpg' });
foldGroup.registerImage({ domId: 'img5', srcUrl: 'http://developer.yahoo.com/yui/docs/assets/examples/exampleimages/small/japan.jpg' });
نقوم بتسجيل الصور في مجموعة باسم fold group، ونقوم بتسجيل كل صورة على حسب المعرف domId في HTML ومصدر الصورة srcUrl. أما بالنسبة لشفرة HTML فستكون كالتالي:
<img src="" id="img1" width="500" height="333" alt="" /> <img src="" id="img2" width="500" height="333" alt="" /> <img src="" id="img3" width="500" height="333" alt="" /> <img src="" id="img4" width="500" height="333" alt="" /> <img src="" id="img5" width="500" height="333" alt="" />
هناك العديد من الخيارات التي يمكنكم التحكم بها، على سبيل المثال، متغير foldDistance يهتم بمقدار المسافة قبل الطيّة لبدء تحميل الصور، وقد حددناه بمقدار 25 بيكسل.
لدى هذه المكتبة في نظري قصور من ناحية قابلية الاستخدام، فهي تقوم بتسجيل وتحميل الصور باستخدام الجافاسكربت، ولكن ماذا لو كان المستخدم لديه الجافاسكربت معطلة؟
الجواب، لن يتم تحميلها! وهذا في الحقيقة قد يسبب بعض المشاكل، وسنرى كيف أن بعض المكتبات الأخرى قد تفوقت في هذا الجانب.
مثال باستخدام مكتبة jQuery
عرض
تحميل
استوحت من مكتبة ياهوو YUI للتحميل المتأخر، إضافة Lazy Load لمكتبة jQuery تقوم بعمل رائع للتحميل الكسول للصور، حيث أن طريقة استخدامها سهلة وبسيطة.
إدراج المكتبة الأساسية
سنقوم بإدراج المكتبة الأساسية jQuery مباشرة من خوادم شركة قوقل، وبعدها نقوم بإدراج إضافة Lazy Load.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script type="text/javascript" src="jquery.lazyload.js"></script>
بعد هذا نقوم بأخذ كل الصور الموجودة في مستند HTML، وتسجيلها في كائن lazyload().
$(function() {
$("img").lazyload();
});
الآن أصبحت كل الصور الغير مرئية (تحت الطيّة) في مستند HTML ستُحمّل لاحقاً عند نزول المستخدم إليها. وعند تعطيل الجافاسكربت، فلا يهم! لأن الصور ستحمل بالطريقة العادية.
لدى الإضافة العديد من الخيارات، فمثلاً يمكننا إضافة بعض التأثيرات قبل ظهور الصور كتأثير التلاشي FadeIn.
$(function() {
$("img").lazyload({
placeholder : "grey.gif",
effect : "fadeIn"
});
});
مثال باستخدام مكتبة MooTools
عرض
تحميل
لدى مكتبة MooTools للجافاسكربت أيضاً إضافة Lazy Load من تطوير David Walsh أحد مطوري لب MooTools.
إدراج المكتبة الأساسية
نقوم بإدراج المكتبة الأساسية MooTools أيضاً من خوادم شركة قوقل، وبعدها ندرج ملف إضافة Lazy Load السابق ذكرها.
<script src="http://ajax.googleapis.com/ajax/libs/mootools/1.2.3/mootools-yui-compressed.js"></script> <script src="lazyload.js"></script>
بعدها وبكل بساطة، عندما يكون مستند HTML جاهزاً، نقوم باستدعاء كائن LazyLoad().
window.addEvent('domready',function() {
var lazyloader = new LazyLoad();
});
مشكلة محرك ويبكيت WebKit
أمثلة مكتبات jQuery وMooTools يعانون من مشكلة في المتصفحات التي تعتمد على محرك WebKit كمتصفحات سفاري، وكروم، لأنها لا تدعم تقنية التحميل الكسول للصور. وهذا في تصميمها كما أوضح ديف هايت في مشكلة: #6656.
مقاييس كفاءة الأداء Benchmark
أردت أن أختبر ما إذا كانت هذه التقنية فعلاً تؤدي بنتيجة واضحة في تسريع حمل الصفحة أم لا، لذلك وضعت توقيتاً لكل اختبار لمكتبة جافاسكربت في مستند HTML، حيث كانت الطريقة بسيطة عبر إضافة الدالة التالية في بداية الصفحة:
var from_time = new Date();
from_time = from_time.getTime();
function benchmark_loading_time()
{
var to_time = new Date();
to_time = to_time.getTime();
var msecs = (to_time - from_time);
alert('تم تحميل الصفحة في ' + msecs + ' جزء من الثانية');
}
ومن ثم مناداتها عند الإنتهاء من تحميل مستند HTML في عنصر body باستخدام حدث عند التحميل “onload”، كالتالي:
<body onload="benchmark_loading_time()">
النتائج
لأكون عادلاً استخدمت آخر النسخ (عند تاريخ كتابة المقال) لمتصفحات فايرفوكس، انترنت اكسبلورر، وأوبرا، واستثنيت المتصفحات التي تعتمد على WebKit. وجربت فتح صفحة التجارب لكل مكتبة 10 مرات، ومن ثم أخذت المتوسط. وكانت بعض النتائج على غير المتوقع.
الطريقة العادية
YUI 3
MooTools
jQuery
تحميل الصور بطريقة عادية
نستطيع أن نرى أن متصفح أوبرا كان أبطىء المتصفحات في التحميل بالطريقة العادية بمتوسط 3468 جزء من الثانية، بينما نجد متصفح انترنت اكسبلورر يأتي أولاً بمتوسط سرعة 2271 جزء من الثانية. ومتوسط سرعة فايرفوكس كان 2353 جزء من الثانية.
تحميل الصور باستخدام ImageLoader مع مكتبة YUI 3
نلاحظ هنا تحسناً قليلاً باستخدام التحميل المتأخر لياهوو، حيث جاء متصفح فايرفوكس أولاً بمتوسط 1720 جزء من الثانية، بينما انترنت اكسبلورر جاء ثانياً بمتوسط 2289 حزء من الثانية. وأخيراً أوبرا بمتوسط 3289 جزء من الثانية.
تحميل الصور باستخدام Lazy Load مع مكتبة MooTools
هنا كان الفرق واضحاً، فباستخدام التحميل الكسول لمكتبة MooTools نرى فرقاً شاسعاً في وقت التحميل يصل إلى -60% في متصفح فايرفوكس، حيث نزل المتوسط إلى 930 جزءاً من الثانية، أما عن انترنت اكسبلورر وأوبرا فقد شهدا أيضا وقت أقصر في التحميل بمعدل -57% و –20% على التوالي.
تحميل الصور باستخدام Lazy Load مع مكتبة jQuery
كان التحميل الكسول لمكتبة jQuery الأبطىء في تحميل الصفحة، حيث كان هدفنا هو تقليل وقت تحميل الصفحة، فارتدت النتيجة بعكس ما كنت أتصور. زاد وقت تحميل الصفحة عن ماكانت عليه باستخدام الطريقة العادية لتحميل الصور بمقدار +14% في متصفح أوبرا، وأيضاً في انترنت اكسبلورر +13%، وفايرفوكس +9%.
الخلاصة
كما رأينا كيف يمكننا التقليل من استهلاك معدل نقل البيانات Bandwidth، وتخفيف حمل الصفحة وتسريعها باستخدام أدوات بسيطة لجعل الصور تُحمّل لاحقاً. ولكن هناك بعض السلبيات أيضاً، فكما ذكرت مشكلة محرك WebKit مع مكتبات jQuery وMooTools، ولكن تبقى في نظري أفضل من مشكلة تسجيل الصور باستخدام الجافاسكربت التي تستخدمها مكتبة YUI.
أيضاً أثبتت مكتبة MooTools تفوقها في السرعة والأداء عند استخدام تقنية التحميل الكسول على نظرائها. مع العلم أنها أكبر المكتباب من ناحية المساحة 65 KB، بينما مكتبة jQuery وYUI 3 مساحتهم 55.9 KB و14.9 KB على التوالي. وأيضاً دهشت بنتائج متصفح أوبرا البطيئة في تحميل الصور بالطريقة الكسولة.







طريقة جميلة جداً , لفتت إنتباهي في بعض المواقع , كُلما نزلت بالمتصفح إلى الأسفل كلما جلب لي المزيد من البرامج ! حقيقةً لم أتعمق كثيراً بلغة Javascript لأني لم أجد المصادر الكافية للأسف ! و كذلك تعاملي مع المكتبات مثل الــ jQuery خجول أيضاً ! لا أدري لماذا أخاف من التعامل مع المكتبات سواءً في الــ PHP أو في لغات غيرها .
أتمنى وجود مصادر عربية لتعليم الجافا سكربت و التعامل مع المكتبات .
تحياتي
فراس اللو
فعلاً لاحظتها في عدد من المواقع، وكنت أفكر إن كانت حركة متعمّدة منهم.. إذاً فهو التحميل الكسول..
استفدت من الطريقة فعلاً.. وكذلك من المقارنة، أحببتها..
ستكون مفيدة كثيراً عند تطبيقها على ألبوم الصور الذي أعمل عليه، وكذلك موقع الطبخ..
كالعادة، سأعود لأخبرك بالنتيجة فور انتهائي منها إن شاء الله..
بالمناسبة، يفترض برابط المقال في نهاية كل مثال أن يعيدنا لموضوعك هذا.. إلا أنه لا يفعل..
@فراس اللو
المصادر موجودة ولكنها قليلة مقارنة بالمصادر الأجنبية، ربما علينا الاجتهاد أكثر في هذا الجانب لتقديم المزيد بإذن الله.
@المبدع العربي
وأنا في انتظارك :) وشكراً على التنبيه، قد تم إصلاح الروابط.
السلام عليكم
أخي عبدالرحمن , مشكور على التوضيح , لاحظت الحركه في عدة مواقع أجنبية , وقد أستخدمها في المستقبل القريب.
لكن عندي سؤال “سخيف” نوعاً ما ,, هل ممكن تجنب هذه الحركه بأي إضافة للمتصفح؟
لأني متعود إني أفتح أكثر من 6~10 تبويبات في المتصفح في نفس الوقت , أفتح صفحه وأقرأ الثانية لغاية ينتهي التحميل للصفحة بالكامل السابقه وهكذا ,, ولكن مع التحميل الكسول !!!!! لا يمكن
وشكراً
@أبورعد..
يمكنك تعطيل Javascript من المتصفح
بارك الله فيك
اعجبني موضوعك الجميل و المميز
أسلوبك مشوّق و محفز لمتابعة القراءة دون الشعور بالملل
لدي إستفسار بسط إن أمكن إفادتي بجواب شافي
هل يمكن إستخدام هذة التقنية مع نظام المنتديات vBulletin
بإنتظار ردك ..
تحية طيبة