معاذ الخلف M.Alkhalaf
معاذ الخلف M.Alkhalaf

@muath2

109 تغريدة 239 قراءة May 26, 2020
(عيديتكم أعزائي وكل عام وأنتم بخير🌹)
طورت موقعك أو تطبيقك وتفاجأت لما شغلته انه بطيييييء 🐌 وش الحل🧐 عشان يصير صاروخ 🚀😎؟ هذي سلسلة تغريدات راح أتكلم فيها عن عدة حلول استخلصتها من تجارب عديدة و تتمحور في معظمها حول #الكاش(نق) #caching كما في الصور (يسار قبل 🐢 و يمين بعد 🚀)
أول شي اسأل نفسك: مين قال ان موقعي بطيء 😡؟ بكل بساطة روح لأحد الموقعين التاليين واعمل قياس سرعة
developers.google.com
gtmetrix.com
(في الصور نتايج سرعة تويتر و قوقل 😅)
كلا الموقعين بيعطونك نصائح لتحسين السرعة ولكن للأسف هي نصائح محدودة، لذلك إقرأ باقي الثريد زين
السؤال الثاني: هل السرعة مهمة 🤔؟ مهمة جدا خصوصا للمواقع.
(١) دراسة قبل ١٠ سنوات تقريبا من أمازون وجدت ان كل ثانية تأخير في تحميل الصفحة تكلهم ١٠٪ من المبيعات 😰
robotics.stanford.edu
الدراسات بشكل عام تشير إلى أنه لابد أن يتحمل الموقع في اقل من ثانيتين وفوق ٥ ثاني وضعك مزري
(٢) ليس هذا فقط وإنما السرعة تؤثر على ترتيب موقعك في محركات البحث وخصوصا قوقل ولذلك تصنف ضمن الأشياء المهمة في عملية تحسين الموقع لمحركات البحث أو #SEO
(٣) تجربة المستخدم في التطبيق تجعل صبره ينفد أثناء تصفح الموقع اذا ضغط صورة، رابط أو زر وما شاف تغير في الصفحة خلال أقل من ثانية
السؤال الثالث: ايش المقاييس اللي تستخدمها؟
المقاييس معظمها تركز على النقطة رقم ١ في الصورة وهي سرعة عرض الصفحة للمستخدم في المتصفح (سواء في الجوال أو الديسكتوب) لأنها بكل بساطة زبدة الموضوع.
(١) الوقت حتى أول بايت Time to First Byte (TTFB) : كم الوقت الين المتصفح يشوف أول بايت
(٢) الوقت حتى يتم أول رسم من قبل المتصفح لمحتوى الصفحة First Contentful Paint
(٣) الوقت حتى يتمكن المستخدم من التفاعل من الصفحة First Input Delay (FID)
(٤) حجم الصفحة Page Size
(٥) عدد الركوستات Number of HTTP Requests
(٦) الوقت حتى تتحمل الصفحة بالكامل Fully Loaded Time
هناك العديد من المقاييس الأخرى طبعا وهذي مراجع لبعضها من قوقل
developers.google.com
مشكلة المقاييس هذي انها تعطيك انطباع خاطيء في التركيز على سرعة عرض الصفحة أو المنطقة رقم ١ في الصورة و تنسى بقية الأشياء أو ما خلف الكواليس والتي غالبا تكون الأهم.
طبعا في التطبيق الموضع أوضح
الحلول: أول وأسهل حل يلجأ له الكثير هو رفع مواصفات السيرفر. مشكلته (١) مكلف على المدى الطويل (٢) مو بالضرورة يحل المشكلة خصوصا اذا استخدام الموقع والتطبيق عالي. نفذ الحل هذا كحل سريع ولكن مباشرة اشتغل على حل جذري يشمل بعض أو كل الحلول المرقمة في الصورة
ليش رفع مواصفات السيرفر قد تكون فعاليته محدودة؟ لأنه غالبا مشكلة بطء المواقع تأتي من:
(١) عمليات القراءة والكتابة IO وخصوصا في قاعدة البيانات وليس من عمليات المعالجة processing
(٢) حجم الموارد الكبير (صور وفيديو، ملفات JS، ملفات CSS) وتكرار تحميلها بدون كاش، وأخص بذلك الصور
(٣) تأخر رسم rendering الصفحة لدى المستخدم على الرغم من تحميلها وذلك بسب الحجم الكبير لكود الجافاسكربت وعدم ترتيب عملية تحميله وتنفيذه.
(٤) بطء تنفيذ كود السيرفر في اللغات ال interpreted وعلى رأسها PHP و (javascript (NodeJS وهذي أكثر نقطة تتأثر بقوة المعالج ولكنها المشكلة الأضعف
ملخص: هذي المشاكل تتوزع بين الخادم أو الباك اند Server Side وبين العميل أو الفرونت اند والتطبيق Client Side ومعظمها يتمحور حول بطء عمليات ال IO (القراءة والكتابة من الهارديسك والتحميل من الشبكة) لذلك فإن رفع مواصفات السيرفر لوحده الأقل جدوى ويجب اللجوء لبقية الحلول التي سنشرحها
خلونا نبدأ بأسهل وأول الحلول اللي ممكن تسويها ويضبط مع الموقع والتطبيق وإن كان يؤثر على سرعة تحميل الموقع أكثر من سرعة التطبيق ألا وهو ال HTTP Caching. ايش المقصود بهذا المصطلح 🤔؟ خلونا أول نبدأ بشرح مفهوم الكاش عموما لأنه مفهموم مهم ومشهور في علوم الحاسب
developer.mozilla.org
تخيل نفسك تبغى تشتري بيبسي؟ ايش الخيارات؟ تقدر تشتري من البقالة جنبكم وتقدر من السوبر ماركيت وتقدر من المصنع. اي واحد بتختار؟ أكيد البقالة لأنها أقرب شي لبيتك وسهل تلقى البيبسي داخلها بدون بحث، علما انه صاحب البقالة تلقاه اشترى من السوبر ماركيت واللي من جهته اشترى من المصنع.
فكرة الكاش عموما بشكل مبسط مشابهة لهذا المثال وكل ما دخلنا في التفاصيل كل ما فهمتها بشكل أفضل ان شاء الله. الآن خل نشوف كيف يشتغل ال HTTP Cache. افترض ان المستخدم حاول يزور موقعك لأول مرة وخل ناخذ سيناريو مبسط كما هو في الصورة.
(١) البراوزر راح يطلب الموقع من السيرفر من خلال عدد من الطلبات HTTP requests.
(٢) السيرفر يستقبل كل طلب ويرد بالملف المطلوب سواء كانت HTML أو جافاسكربت أو ستايل أو صور أو غيرها من الموارد.
الآن لما يطلب البراوزر صفحة جديدة فالأفضل انه ما يطلب الملفات والصور اللي طلبها قبل إلا لو كانت تغيرت وكثير منها ما تتغير إلا بعد مرور فترة طويلة. مثلا صورة اللوقو للشركة يمكن تجلس سنة أو سنوات ما تتغير. نفس الشي لو صورة منتج ممكن ما تتغير أبدا (فكر فيها 🤔).
لذلك وفي هذه الحالة فالأفضل ان البراوزر يخزن الملفات هذي في جهاز المستخدم في أول زيارة لأول صفحة في الموقع (يكيش الملفات أو يخزنها في الكاش) وبعد كذا لما يحتاجها المستخدم فإنه يجيبها من الكاش في جهاز المستخدم وما يروح يطلبها من جديد من السيرفر. فقط يطلب الملفات الجديدة.
هذا اللي سميته في الصورة في رقم واحد private HTTP cache. (شوي وأشرح ليش private). طيب كيف تسويه؟ تستخدم Cache-Control في ال HTTP header كما في الصورة الثانية. وهذا رابط شرح كامل للموضوع
developer.mozilla.org
من تجربة، أكثر ما يثقل المواقع أثناء التصفح هو تنزيل الصور لذلك عمل HTTP Cache للصور مفيد جدا وسهل جدا. الأهمية تكون أعلى بكثير في التطبيق ولكن ال HTTP Cache ما يعمل لوحده و لازم تستخدم مكتبة للصور تقوم بعمل كاش مثل SDWebmages في الايفون
github.com
طبعا من خلال ال Cache Control تقدر تتحكم في عمل كاش للملف من عدمه وكذلك في عمر الكاش (max-age) واللي اذا انتهى خلاص يتم تنظيف الكاش وطلب الملف من السيرفر مرة أخرى.
ملخص: بتفعيل تقنية ال HTTP Cache راح نستفيد من الكاش في البراوزر بشكل اوتوماتيكي لكافة أنواع الملفات سواء html أو جافاسكربت أو ستايل أو ميديا (صور وفيديو) أو غيرها. في التطبيق غالبا نستفيد من الكاش للصور والفيديو وراح نحتاج مكتبة تدعم الكاش للصور مثلا.
ما خلصنا من ال HTTP Cache إلى الآن. باقي الكاش في ال CDN 👏 فما هي يا ترى ال CDN😇؟ ال Content Delivery Network أو شبكة توصيل المحتوى هي تقنية تقوم بتخفيف العبء على سيرفرك عبر تخزين مؤقت لبعض الملفات بحيث المستخدم ياخذها من ال CDN بدل ما ياخذها من سيرفرك. أقرب له وأريح لسيرفرك 👌
واحدة من أشهر شبكات ال CDN هي المقدمة من شركة Cloudflare cloudflare.com وعندهم اشتراك مجاني بالمناسبة. طبعا قوقل وامازون كلاود وغيرهم يقدمون خدمات CDN خاصة فيهم.
(١) ال CDN تعطيك طبقة ثانية من ال HTTP Cache وهو ال public cache لملفات موقعك موزعة على كافة أنحاء العالم.
(٢) تتميز سيرفرات ال CDN انها تستخدم أقرب سيرفر فيزيائيا من مستخدم موقعك وتستخدم خوارزميات معقدة لعمل نسخ من نفس البيانات في سيرفرات بمواقع مختلفة (وأنت مرتاح بدون ما تدوخ راسك).
(٣) الكاش في ال CDN يكون public يستفيد منه كل مستخدمي موقعك أو تطبيقك اللي في نفس المنطقة الجغرافية
(٤) بعض شبكات ال CDN مثل Cloudflare تقوم بعمل ضغط لملفات موقعك (ضغط zip لل HTML والجافاسكربت وغيرها ببلاش ولكن ضغط الصور لازم اشتراك) .
(٥) أيضا تقوم هذه الشبكات بتصغير ملفات الجافاسكربت والستايل minification وهذي تقنية ضغط خاصة بهذه النوعية من الملفات وممكن نتكلم عنها بعدين.
(٦) تقوم بعض هذه الشبكات مثل cloudflare وقبلها akamai بتوفير الحماية والأمن لموقعك من هجمات منع الخدمة DDOS وكذلك (باشتراك وليس مجانا) بتوفير جدار ناري للويب web firewall. وغيرها من الخدمات الكثيرة والتي لا تتعلق بالضرورة بسرعة الموقع فقط.
(٧) بعض شبكات ال CDN مثل Cloudflare يعطيك خاصية تصفح الموقع من الكاش لديه لمدة وجيزة في حال سيرفرك لم يستجب. افترض عدد من المستخدمين أكثر من تحمل سيرفرك قام بطلب الموقع؟ هذي الخصاية راح تفيد بشكل كبير لأن المستخدم راح يشوف صفحة الموقع "المكيشة" بدل ما يشوف صفحة بيضاء
نرجع لكلمة public لما قلنا انه ال CDN تسوي public HTTP cache. وش نقصد فيها؟ تخيل مستخدم موقع عنده صورة خاصة فيه مخزنها في موقعك و هو اللي يحتاج يشوفها فقط. هل تعمل لها كاش في ال CDN 😏؟
أولا: الموضوع يدخل في الخصوصية ، وثانيا: فقط المستخدم هذا يحتاج الصورة هذي لذلك يكفي تسوي لها كاش على البراوزر أو التطبيق الخاص فيه على جهازه لأنه الوحيد اللي راح يطلبها وعمل كاش لها على شبكة ال CDN ما له معنى (ما فهمت؟ وقف هنا وفكر زين وجرب كذا سيناريو وبتفهم ان شاء الله).
كيف نفعل الكاش في ال CDN؟
(١) نفعل ال public في ال Cache Control في ال header كما في الصورة. لاحظ انك تستطيع تضع عمر خاص لل public cache مختلف عن ال private cache باستخدام s-maxage
(٢) تشترك في شبكة CDN زي Cloudflare وتربطها بموقعك (لا تنسى تفعل ضغط الملفات أيضا)
(٣) تفعل خاصية ال public في ال cache control في ال google storage #cache-control" target="_blank" rel="noopener" onclick="event.stopPropagation()">cloud.google.com أو amazon s3 docs.aws.amazon.com اذا كنت تستخدمها علما أن لها CDN خاص فيها اوتوماتيكي وراح تفيدك كثير في الكاش للملفات و خصوصا للصور سواء موقع أو تطبيق
ملخص: تطرقنا إلى مفهوم شبكة ال CDN وكيفية تفعيلها والاشتراك فيها وكذلك كيفية الاستفادة منها بتفعيل الكاش العام public cache لملفات الموقع و التطبيق. تذكر أن ال CDN: تخفف العبء على سيرفرك وتستجيب بشكل أسرع لطلب المستخدم لقرب سيرفراتها منه فيزيائيا
بكذا انتهينا من ال http cache وهنا بعض الملاحظات:
(١) في مرحلة التطوير خلك حذر كثير في تفعيل ال http cache لأنه راح يدوخ راسك. حقيقة خلك حذر في تفعيل أي كاش عموما أثناء التطوير وخله آخر مرحلة وتأكد انك فاهم بالضبط كيف يشتغل بالتفصيل المهم (شف الرابط)
developer.mozilla.org
(٢) استخدام ال http cache (والكاش عموما) قد يتسبب في اخطاء برمجية صعبة جدا لذلك تأكد من اختباره بشكل جيد.
(٣) لما المستخدم للموقع أو التطبيق ينزل صورة ويكون مفعل لها الكاش ما راح يشوف الصورة الجديدة إلا لما ينتهي وقت تفعيل الكاش لأنه دايما راح يقراها من الكاش وليس من السيرفر
كل اللي سويناه إلى الآن هو تخفيف الحمل على السيرفر فقط بدون ما نعدل في الكود . وهذا كله تم بسهولة عبر استغلال تقنية http cache العريقة ومستخدمة من قبل الكثير ومخدومة بشكل ممتاز سواء من قبل المتصفحات بكافة أنواعها أو خوادم الويب (apache, nginx, ...) وأيضا شبكات وخدمات الكلاود.
ننتقل الآن إلى الطرف الآخر - السيرفر - وإلى النقطة رقم ٦ وهي object/DB cache. سابقا خففنا العبء على السيرفر وكذلك سرعنا الدانولود للمستخدم خصوصا للملفات الثقيلة مثل الصور. الآن هدفنا هو ال dynamic content أو المحتوى المتجدد والمتغير باستمرار والخطوة الأولى من قاعدة البيانات.
لو سألت أي واحد عنده خبرة جيدة في مواقع من الحجم المتوسط والكبير عن أكثر مكان يسبب بطء للخدمة راح يقول لك على طول "قاعدة البيانات" خصوصا في التطبيقات. الشي اللي راح نسويه هو تسريع عملية القراءة من قاعدة البيانات فقط وليس الكتابة وذلك من خلال تقنيات كاش خاصة لهذا الموضوع.
لاحظ ان هذا ليس الحل الوحيد ولكن هناك حلول أخرى أكثر تعقيدا من خلال توزيع عمليات القراء والكتابة على عدد من قواعد البيانات في عدد من السيرفرات database clustering ولكن هذا موضوع متقدم وقد أتطرق له في تغريدات أخرى كما أنه مهم للمواقع التي لديها عدد ضخم جدا من الزوار (ملايين).
راح نتكلم عن منتجين بتقنيتين بينهما تشابه كبير و يشتركان في هدف واحد لدينا وهو عمل كاش لقاعدة البيانات وهما
#memcached
memcached.org و
#redis
redis.io
كلا المنتجين يعملان من خلال تخزين البيانات مؤقتا في الذاكرة العشوائية RAM بدل الهارديسك
ايش الفايدة؟ الذاكرة العشوائية أو الميموري أسرع بكثير كثير كثير جدا جدا من الهارديسك ولكنها أيضا أغلى بكثير جدا جدا منه.
بالاضافة لتخزين البيانات في الميموري فإن طريقة قراءة البيانات في هذين المنتجين (يعني الاستعلام) سريعة جدا مقارنة بالداتابيز العادية. طيب كيف فكرة الاستخدام؟
الفكرة تتمحور حول انك كل ما جيت تقرأ بيانات من الداتابيز (بناء على ريكويست جاي للموقع أو التطبيق) فإنك تحاول تقرأ من الكاش حق الداتابيز أول وإذا ما لقيتها تروح تقرأ من الداتابيز نفسها. طبعا اذا بتكتب لازم تكتب في الداتابيز مباشرة و تحدث الكاش اذا كانت عملية تحديث update
في الصورة مثال على كود بايثون لمحاولة القراءة من الكاش ومن ثم اللجوء إلى القراءة من قاعدة البيانات في حال فشل عملية القراءة من الكاش وبعد ذلك تعبئة الكاش بالبيانات الجديدة. لاحظ انك تعطي الكاش مفتاح key وقيمة value وهو يخزن القيمة تبع المفتاح
ايش تحتاج لتفعيل هذا النوع من الكاش:
(١) تقوم بتركيب واعداد المنتج اللي يعجبك منهم على سيرفرك ( الشغل من الكوماند لاين ويبغى له تعب شوي). هذا مقال مطول للمقارنة بين الأثنين من علي بابا كلاود @Alibaba_Cloud/redis-vs-memcached-in-memory-data-storage-systems-3395279b0941" target="_blank" rel="noopener" onclick="event.stopPropagation()">medium.com
وهذا واحد ثاني من ستاك أوفرفلو stackoverflow.com
(٢) تركيب المكتبة المناسبة للغة البرمجة اللي تستخدمها للتخاطب مع أي من المنتجين اللي اخترت (تمام مثل ما انك تحتاج مكتبة للتخاطب مع قاعدة البيانات).
(٣) تصمم وتكتب الكود المناسب لعمل الكاش
هذي روابط دروس:
julien.danjou.info
codeforgeek.com
(٤) لو كنت تستخدم منتجات جاهزة مثل wordpress راح تلاقي plugins جاهزة للربط مع memcached خصوصا مثل wordpress.org وكذلك wordpress.org
(٥) زي ما قلت سابقا، خلك حذر في استخدام الكاش ودايما جرب واختبر زين قبل تتوهق 😅
كل اللي شفناه سابقا هو استخدام #memcached و #redis لعمل كاش للداتابيز. ولكن المنتجين هذولي نقدر نستخدمهم لأغراض أخرى للكاش. مثلا: لو كنت رابط مع API من طرف ثالث فانك تقدر تستخدمهم لعمل كاش لل API. أيضا تقدر تستخدمه لعمل كاش للملفات والصور في الميموري اذا احتجت.
بكل بساطة، المنتجين هذولي تعطيهم مفتاح key وقيمة value وهم راح يخزنونها زي ما هي في الميموري بغض النظر ايش مكونات القيمة (رد على استعلام من قاعدة البيانات أو ملف من الهارديسك أو رد من API ... الخ). ملاحظة أخيرة: redis يدعم التخزين على الهارديسك أيضا ولكن موضوع يطول شرحه.
أخيرا: لما تستخدم أحد المنتجين هذولي راح يصير فيه فايدة كبيرة جدا من رفع كمية الميموري لديك لأنها راح تزيد المساحة المتوفرة لتخزين الكاش. أيضا ممكن تعمل توزيع أو cluster لعدد من السيرفرات سواء memcached أو redis وتوزع العبء واللود بينها ويمكن هنا نلاحظ redis له ميزة أفضل
بسم الله نكمل اليوم ما بدأناه بالأمس. طبعا لم تنته القصة بالنسبة لتسريع عمل الاستعلامات في قاعدة البيانات حيث ما زال هناك المزيد من الامكانيات لعمل كاش للبيانات في الكلاينت سايد client side على جهاز وتطبيق العميل ولكن...!
ما سأتحدث عنه هنا يقتصر على تطبيقات الويب وتطبيقات الجوال فقط ومن الصعب تطبيقه على مواقع الويب. بشكل عام، سنلاحظ أن نقاشنا من الآن فصاعدا سيستعرض استخدام تقنيات مختلفة حسب نوعية المنتج لديك هل هو: (١) موقع ويب أو (٢) تطبيق ويب أو (٣) تطبيق جوال (سبق غردت عن الفرق بين رقمي ١ و ٢)
نعود لصورتنا وتحديدا رقمي ١ و ٢ في الصورة. عند استخدام تطبيق ويب فإنه بإمكانك تخزين بعض البيانات وعمل كاش محلي لها في البراوزر في مكان يسمى local storage. مثلا لو استخدمت reactjs يمكنك تخزين البيانات في redux store واللي راح تخزنها لك في ال local storage redux.js.org.
بالمقابل في تطبيق الجوال (وأيضا تطبيقات الويب حديثا) تستطيع تستخدم قاعدة البيانات الخفيفة والرشيقة والشهيرة SQLite sqlite.org والتي تستخدم بكثرة ومنذ سنوات. مهم التنويه إلى أن الغرض الأساسي من redux و SQLite وغيرها ليس لعمل كاش وإنما لتخزين بيانات وحالة state التطبيق
زي ايش البيانات اللي تقدر تعمل لها كاش محلي؟ مثلا لما المستخدم يتصفح المنتجات في تطبيقك فبإمكانك تخزين بيانات المنتجات - بعد ما تأتي من السيرفر بعد أول طلب - في البراوزر باستخدام redux بحيث لما يرجع المستخدم يتصفح من جديد تأتي البيانات من ال local storage بدل ما تأتي من السيرفر.
هذه العملية مشابهة تماما لما عملناه سابقا في الصور باستخدام ال http cache ولكن الفرق ان المسؤولية هنا تقع على عاتق مبرمج تطبيق الويب وليس على البراوزر. بالتأكيد ما كان ينطبق على الصور ينطبق هنا بمعنى وجوب الحذر من المبالغة في استخدام الكاش. ليش 😅؟
لاحظ انك جالس تبني نسخة "جزئية" مكررة وغير مكتملة - أو partial replica بمصطلح علم البيانات وهندستها - من قاعدة البيانات اللي في السيرفر على كل كلاينت. لذلك راح تدخل في دوامة ادارة المزامنة synchronization بين البيانات في السيرفر وفي الكلاينت.
en.wikipedia.org
بعبارة أخرى، مخزن البيانات المحلي في التطبيق راح يكون فيه بيانات خاصة بالتطبيق وحالة التطبيق (ما لها دخل في السيرفر ولا تتخزن هناك) وبيانات كاش مشتركة مع السيرفر ومهمتك مزامنة البيانات المشتركة مع السيرفر بين التطبيق وبين السيرفر. هنا نقاش جميل حول الموضوع stackoverflow.com
حسب تجربتي ونقاشي مع مطوري تطبيقات الجوال فإن هذه المشكلة تقع لدى الكثير من المطورين ومنذ فترة طويلة، بدون قصد و بدون فهم وادراك لسبب المشكلة وكيفية ايجاد حل جذري لها. السبب في ذلك انه لا مفر من وجود كمية ولو بسيطة جدا من البيانات المشتركة بين التطبيق وبين السيرفر (كاش بالغصب 😰)
قبل نقفل الموضوع أشير إلى أن بعض قواعد البيانات المدارة managed databases مثل فايرستور من فايربيس لديها ميزة ممتازة جدا في هذه الناحية وهي عمل الكاش والمزامنة بشكل اوتوماتيكي و real time بدون ما تقلق حالك وهنا مزيد من التفاصيل
#firebase #firestore
firebase.google.com
نكمل اليوم الجزء الأخير في هذه السلسلة. مثل ما ذكرنا سابقا، راح نفصل بين موقع الويب وتطبيق الويب وتطبيق الجوال. خلونا نرجع لموقع الويب. هناك في رقم ٥ عدة عمليات - على رأسها ال page cache - مهمة جدا لتسريع مواقع الويب وعلاقتها ضعيفة بسرعة أو بطء قواعد البيانات. فما هي؟
خلوني أول أذكر بكيفية تصفح موقع الويب. عندما يقوم المستخدم بتصفح موقعك يقوم البراوزر بارسال طلب للصفحة التي يريد المستخدم زيارتها. يتم استقبال الطلب عبر الويب سيرفر والذي يقوم - بالتعاون مع الأبلكيشن سيرفر - بالرد على هذا الطلب عبر ارسال ملف HTML يمثل الصفحة.
بعد ذلك يقوم البراوزر بقراءة ملف ال HTML وتنزيل كافة الملفات الأخرى المطلوبة بداخلة (جافاسكربت أو CSS أو صور أو غيرها) عبر طلبها من الويب سيرفر. نبدأ بملف ال HTML ونطرح السؤال: هل ملف ال HTML - الذي يطلبه البراوزر ويمثل الصفحة - يكون جاهز static أو يتم "تصنيعه" dynamic لكل طلب؟
في الحقيقة وفي معظم الأحيان فإن هذا الملف يتم تصنيعه بناء على المحتوى المطلوب عرضه داخل الصفحة. مثلا تخيل صفحة متجر الكتروني. بالتأكيد محتوى الصفحة يتغير باستمرار لعرض المنتجات الجديدة مثلا أو التخفيضات الجديدة ... الخ.
أيضا معظم منصات المحتوى CMS مثل ووردبريس ليس لديها ملف HTML جاهز وإنما يتم تصنيعه بناء على المحتوى المخزن في قاعدة البيانات. مهمة ال page cache هو تخزين نسخة جاهزة من هذه الصفحات - بعد تصنيعها - ولفترة معينة وغالبا في مجلد تابع للويب سيرفر
هذا الشيء يسمح للويب سيرفر بالرد السريع جدا على الطلب وذلك بإحضار الصفحة التي تم طلبها من ال page cache وكأنها صفحة جاهزة أو ثابتة static وبذلك يتم تجاوز تشغيل الكود (البطيء) لتجهيز الصفحة وتجاوز الذهاب لقاعدة البيانات أو حتى الكاش الخاص بقاعدة البيانات.
في الصورة إحصائيتان لووردبريس مع Nginx وبعض الخيارات الأخرى لعمل ال page cache (المصدر: spinupwp.com) توضحان الفائدة من هذه العملية في تسريع استجابة الموقع حيث تتجاوز السرعة ١٠ أضعاف (المقارنة تمت مع طلب بيانات الصفحة من قاعدة بيانات مباشرة بدون استخدام كاش لها).
تذكر أننا نرغب في أن يتم تحميل الصفحة في أقل من ثانيتين. هذه العملية تستخدم في الغالب للصفحات التي لا تحتوي محتوى خاص بمستخدم معين private content مثل الصفحة الرئيسية للموقع. طيب ماذا لو كان داخل الصفحة محتوى خاص بالمستخدم مثل سلة التسوق؟
هنا ندخل فيما يسمى بال private page cache بحيث يكون هناك كاش خاص لبعض الصفحات لكل مستخدم على حدة والموضوع راح يكون بالتأكيد أصعب. أيضا بالامكان التحايل عبر استخدام ajax للأجزاء التي تحتوي على المحتوى الخاص مثل السلة. اذا تستخدم ووردبريس فإن البلق انز الشهيرة للكاش تدعم ذلك.
جميل خلصنا عملية تسريع تحميل الصفحة عبر عمل ال page cache لملف ال HTML. ماذا عن تسريع تحميل الملفات الأخرى (الجافاسركبت وغيرها)؟ ليس هذا فقط، ولكن ماذا عن تسريع عملية عرض الصفحة 😇؟ قضية ان البراوزر يحمل الصفحة بسرعة شي و انه يعرض ويرسم render الصفحة بسرعة شي ثاني.
لو ترجع للمقاييس اللي تكلمنا عنها في البداية راح تجد ان كثير منها تقيس المخرج النهائي للمستخدم وزبدة الموضوع ألا وهو عرض الصفحة وامكانية التفاعل معها من قبل المستخم (لاحظ المشكلة هذي موجودة بشكل أقل في تطبيق الويب ومنعدمه تقريبا في تطبيق الجوال لذلك تحس بتجربة مستخدم مختلفة).
حتى أوضح أهمية الموضوع هذا: تخيل انك سرعت السيرفر وقاعدة البيانات وعملت لها كاش وكذلك عملت كاش للصفحات المهمة (وهذا هو غالبا الجزء الأصعب والأكثر فائدة)، كل هذا يفيد في سرعة تحميل الصفحة في البراوزر TTFB ولكن عملية رسم وعرض الصفحة شي ثاني مختلف ويحتاج شغل اضافي 😰. كيف؟
لما يطلب المستخدم صفحة يقوم البراوزر بالتالي:
(١) يطلب الصفحة من السيرفر بناء على العنوان URL
(٢) يستقبل ملف ال HTML ثم يقوم بقراءته وتفسيره ورسمه parse and render
(٣) عملية التفسير والرسم تتم عبر ستاندرد معروف في كل البراوزرات بحيث تبدأ من تاق ال <head> وتقوم بمعالجة كل تاق تمر عليه و كذلك تحميل (وتنفيذ؟) أي ملف سكربت أو ستايل تمر عليه حسب ترتيب التاقات. غالبا ال head يحتوي عمليات تشييك وتحميل للملفات فقط. المشكلة كل هذا يتم بدون رسم أي شي
بعد ما يخلص البراوزر من ال head تبدأ عملية الرسم بال body حيث يقوم البراوزر وبالترتيب برسم (render and paint HTML/DOM tree) كل تاق يمر عليه و تحميل أي ملف سكربت أو ستايل أو صور وميديا أو غيرها. الخوازرمية معقدة وفي قلب كل براوزر وهناك اختلافات للأسف من متصفح لآخر. طيب ايش تسوي؟
أولا: لازم تحاول انك تعرض (ترسم) الصفحة قبل تحميل أو تنفيذ ملفات الجافاسكربت. الكلام نفسه ينطبق على ملفات الستايل ولكنه أصعب وغالبا ما يسوى كثير. الصور التالية توضح الترتيب: رسم ال HTML (أخضر)، التوقف عن الرسم (رمادي)، تحميل السكربت (بنفسجي) وتنفيذه (أحمر) growingwiththeweb.com
ما فهمت. أشرح زيادة؟ (١) طريقة و (٢) مكان تحميل السكربت يؤثر على سرعة رسم الصفحة. (١) تقدر تحسن طريقة التحميل باستخدام تعليمات async و/أو الأحدث منها وهي defer مع تاق script عند تحميل ملف الجافاسكربت. (٢) حمل السكربت آخر ال body قبل </body> مالم يثبت العكس stackoverflow.com
أيضا اذا عندك سكربت ما يؤثر ويتداخل مع أي سكربت آخر استخدم async على طول وأنت مغمض (اضافة لوضع التاق في آخر ال body). في الغالب احرص انك تحترم سكربت ال jQuery وتضعه لوحده في ال head. طبعا أنت جرب الين تصل لأفضل نتيجة بس تذكر كل التحسينات هذي تؤثر بمقدار ثانية تقريبا 😂.
ثانيا: حاول تجمع كل ملفات الجافاسكربت في ملف واحد وكذلك ملفات الستايل تكون في ملف واحد حتى تقلل عمليات الطلبات أو الريكويسات http requests على سيرفرك. طبعا هذا ممكن يتعارض مع ترتيب الكود اثناء التطوير لذلك خلها آخر شي وجيد لو تؤتمتها أو تستخدم tool لعملها
ثالثا: احرص على عمل ضغط وتصغير لكافة الملفات سواء ال HTML أو الجافاسكربت والستايل وأكيد طبعا الصور. تصغير الملف minification تقنية تختلف كليا ومتوافقة تماما مع ضغط الملف compression وتستخدم مع الجافاسكربت والستايل أكثر شي. تذكر ان ال CDN ممكن تساعد في الضغط والتصغير اضافة للكاش
هذا مقال مطول من موزيلا حول ثانيا وثالثا أعلاه
developer.mozilla.org
رابعا: احرص على ضغط الصور وتحميلها حسب الحاجة lazy loading وهذي تتم باستخدام HTML أو مكتبات الجافاسكربت كما أن كثير من الثيمات وكذلك البلق انز للكاش في الووردبريس وغيرها تعمل الشيء هذا اوتوماتيكيا. التحميل حسب الحاجة معناه انه يتم تحميل الصورة فقط اذا ظهر مكانها أمام المتصفح.
أخيرا هذي بعض المكتبات و الووردبريس بلق انز لعمل الكثير مما تكلمنا عنه.
(١) تحميل حسب الحاجة عبر برمجة ال HTML والجافاسكربت sitepoint.com
(٢) هذي بعض الأدوات المشهورة لتجميع وتصغير الجافاسكربت
github.com
closure-compiler.appspot.com من قوقل
(خلك حذر جدا في التعامل مع البلق انز الخاصة بالكاش في ووردبريس وجربها تدريجي وعلى موقع اختبار. ياما ضربت لي ملفات😡)
(٣) بلق ان جاهز ومجاني ومشهور جدا للكاش للوردبريس wordpress.org
(٤) البلق ان الأشهر للكاش وتسريع الموقع لووردبريس ولكن غير مجاني
wp-rocket.me
(٥) بلقان للكاش مجاني (وفيه نسخة متقدمة بلفلوس) مع ويب سيرفر خاص فيه ومشهور مجاني أيضا (وفيه نسخة متقدمة بفلوس) مع التعليمات كاملة على ديجتال اوشن
marketplace.digitalocean.com
هذا رابط البلق ان لوحده لو تبي
wordpress.org
(٦) هذا بلق ان مشهور ومجاني لضغط الصور وتحسين أحجامها ولكن يستخدم سيرفراته لعملية الضغط (يعني بيودي الصور للسيرفس وفيها جزء بفلوس)
wordpress.org
هل خلصنا 😅؟ لا أكيد. معظم اللي سبق ينطبق فقط على مواقع الويب. تطبيقات الويب فيها الصفحة الأولى فقط اللي تقدر تطبق عليها ال page cache اضافة إلى انها بالكامل جافاسكربت فما لها معنى تؤخر تنفيذ الجافاسكربت 😂. تطبيقات الجوال أكيد ما فيها كاش للصفحة. لكن ... الاثنين عندهم API!
قبل نروح لل API خلونا نعرج بشكل سريع على تطبيقات الويب وتسريع تحميل الصفحة الأولى. ايش المشكلة في تطبيقات الويب؟ المشكلة انك راح تحمل ملف جافاسكربت ضخم يمكن يوصل حجمه ١ ميجا أو أكثر (بعد التصغير والضغط) يمثل التطبيق وهذا بياخذ أربعة أو خمس ثواني حتى تفتح الصفحة ويعمل التطبيق.
ايش الحل؟ أمامك حلين:
(١) تقسيم الملف إلى ملفات صغيرة عن طريق ال lazy loading لبعض أجزاء الجافاسكربت باستخدام تقنيات تسمى بال code splitting أو ال tree splitting. هنا تجد شرح كامل من reactjs لهذا الموضوع reactjs.org
هناك مكتبات تساعدك كثيرا في هذا الجانب ومن أشهرها github.com
(٢) تستخدم ما يسمى بال server side rendering وهذا هو الحل المفضل لدي لأنه يساعد كثيرا في تحسين فهم محركات البحث لموقعك وفهرسته SEO. الفكرة هنا انه يتم تنفيذ جزء من كود الجافاسكربت في السيرفر وتجهيز الصفحة الأولى للتحميل والعرض ومن ثم (وأثناء عرض الصفحة) يتم تحميل باقي السكربت
لعمل ذلك فأشهر فريموورك للاستخدام هو nextJS nextjs.org
يتبقى موضوع أخير يخص تطبيق الويب وهو عمل كاش في البراوزر خاص بتطبيق الويب (ممكن أيضا تستخدمه لموقع الويب من خلال ajax) وهو استخدام ال service worker. هذي تقنية تعتبر ركيزة أساسية ضمن تقنيات ال Progressive Web Apps ومستندة إلى تقنية أقدم في البراوزر وهي ال web worker فما فائدتها؟
سبق تكلمت عن الموضوع في تغريدات سابقة تقارن بين مواقع وتطبيقات الويب بتفصيل أكثر ولكن سأوجز هنا. هذا رابط يشرح ال web workers html5rocks.com واللي ظهرت للتغلب على مشكلة عدم وجود multi threading في البراوزر للجافاسكربت.
بعد كذا ظهر ال service worker ك web worker ولكن متخصص في الكاش داخل البراوزر. كاش لإيش؟ لكل شي وأي شي تبغاه وميزته تحت تحكمك بالكامل كمبرمج تطبيق ويب في جزئية الفرونت اند سواء تسخدم reactjs أو angularjs أو غيرها. عيبه: صعب جدا عن تجربة (مريرة) واذا تسجل في البراوزر صعب تحذفه 😭
هذي مقدمة من قوقل (عرابة تطبيقات الويب وال PWA) لاستخدام السيرفس ووركر developers.google.com وهذا أيضا فريموورك منهم developers.google.com
وهذا رابط من react create app يوضح واحدة من أشهر المشاكل اللي تواجه مبرمجي reactjs في استخدام السيرفر ووركر
github.com
أود أن أشير أيضا إلى أن ال service worker يدعم عمل كاش لل API requests داخل البراوزر 😱 من خلال Cache API وهذا شرح قوقل للموضوع web.dev
بالنسبة لي تقنية السيرفس ووركر تقنية رائعة جدا اذا قدرت تشغلها صح 😁 وراح يكون عندك فعلا تطبيق بكل معنى الكلمة كأنه تطبيق جوال
لا تنسى ان الكاش داخل البراوزر يتم بشكل اوتوماتيكي للملفات والصور سواء بنيت موقع أو تطبيق ويب وذلك عند استخدام HTTP Cache. السيرفس ووركر يفرق في انه بيعطيك تحكم كامل تحت يديك كمبرمج جافاسكربت ولكن عيبه يحتاج برمجة وزي ما قلنا يحتاج حذر شديد في برمجته واستخدامه
أخيرا: معظم زوار موقعك من الجوال ولازم تفهم ان قوقل تدعم تطبيقات الويب وبكل قوة لذلك تقنيات تطبيقا الويب ومنها السيرفس وورك كاش في البراوزر في الاندرويد بيشتغل كثير منها تمام. الحوسة كلها مع أبل والايفون وسفاري على الرغم انهم تحسنوا كثير بس الله يعينك على سفاري 😰
نختم هذه السلسلة من التغريدات بالحديث عن تسريع ال API وبالتحديد ال REST API. هذا الشيء طبعا راح يفيد تطبيق الويب وتطبيق الجوال بالدرجة الأولى وقد يفيد موقع الويب اذا كان يستخدم API.
أولا: ال REST API تتميز في انها تستخدم نفس تقنيات ال delivery (اذا صح التعبير ) اللي تستخدمها صفحات الويب في بروتوكول HTTP. لذلك ال HTTP cache راح يشتغل معها تمام. ولكن...! افهم زين كيف تستخدم ال REST API في الباك اند بالشكل الصحيح. كيف؟
تأكد انك تستخدم ال HTTP methods بالطريقة الصحيحة حسب تعريف بروتوكول ال HTTP لها بحيث ما تخلط بين عمليات القراءة والبحث وعمليات الكتابة والتحديث. الصورة المرفقة توضح مثال للاستخدام الصحيح لكل عملية. تتوقع أي العمليات اللي تقدر تعمل لها HTTP Cache؟
زي ما سوينا في الاستعلام من الداتابيز بحيث قمنا بعملية تسريع القراءة فقط من خلال الكاش راح نعمل نفس الشيء من خلال تسريع القراءة والبحث فقط عبر عمل كاش لطلبات وريكويستات ال GET. السؤال ايش اللي راح نعمل له كاش ووين؟ بناء على نقاشنا السابق فكر بنفسك أول في الجواب المنطقي 🤔
الجواب:
(١) اللي راح نعمل له كاش هنا هو ملفات ال JSON اللي تمثل الرد على طلب ال API وراح نعتمد ال URL مع ال query string كمفتاح لعملية الكاش. ممكن تستخدم أي بيانات تبغاها للمفاتيح ولكن تأكد ما يحصل تصادم collision بحيث تستخدم مفتاحين لنفس البيانات بالخطأ
(٢) تقدر تعمل كاش في API Gateway اذا هي تدعم ذلك (لم يسبق لي تجربة ذلك) وهذا رابط لكيفية عمل ذلك في amazon api gateway @bhargavshah2011/api-gateway-caching-3f86034ca491" target="_blank" rel="noopener" onclick="event.stopPropagation()">medium.com
(٣) تقدر تعمل كاش عبر كتابة كود خاص بذلك ويكون الكاش في الميموري باستخدام memcached مثلا وهذا مشابه لما ذكرناه سابقا بخصوص الكاش لعمليات القراءة من الداتابيز.
(٤) تقدر تستخدم ال HTTP Cache زي ماذكرنا سابقا ولكن خلك حذر في انك تقوم بتحديث الكاش بالشكل الصحيح علما انه ليس تحت تحكمك وانما قد يكون منتشر في متصفحات المستخدمين وال CDN. وهذا مقال مع ردود جميلة حول الموضوع restfulapi.net
وهذا أيضا مقال آخر
kennethlange.com
أخيرا نختم الحديث حول الكاش لل API بهذا المقال اللي يتكلم عن عمل كاش لل API وكذلك للداتابيز ويعطي روابط متعددة لمكتبات في فريموورك Django تدعم ذلك. اعتبره مثال عملي
dabapps.com
نختم نقاشنا في هذه السلسلة من حيث ابتدأنا وهو رفع مواصفات السيرفر والذاكرة. لا شك انه حتى وبعد عمل بعض أو جميع ما سبق فإنه وعند النمو الكبير لعدد المستخدمين ستضطر إلى رفع مواصفات السيرفر أو استئجار المزيد من السيرفرات وهذا لا مفر منه.
وهنا أنصحك باستخدام ال autoscaling والتي تسمح باستئجار سيرفر بمواصفات معينة ولكن اعطاء الصلاحية للشركة المزودة برفع مواصفات السيرفر في فترات معينة بسقف معين لكي تستجيب للطلب المتزايد والمفاجئ؟ في فترة معينة من اليوم أو موسم معين (دعاية عند مشهور مثلا) cloud.google.com
لاشك أن هناك الكثير من التفاصيل التي لم أتحدث عنها في كل نقطة من النقاط الموجودة في الرسمة المرفقة ولكن أترك ذلك للقارئ. أيضا لم نتطرق لكيفية تسريع عمليات قواعد البيانات قراءة وكتابة عبر استخدام تقنيات متقدمة لقواعد البيانات مثل #noSQL
DB ومثل ال #clustring وكذلك ال #sharding

جاري تحميل الاقتراحات...