اذهب إلى المحتوى

كل الأنشطة

تحدث تلقائيًا

  1. الساعة الماضية
  2. لا يقولك 'git' is not recognized as an internal or external command, operable program or batch file.
  3. هل عند كتابة الأمر التالي يظهر لك رقم الإصدار لـ GIT ؟ git -v
  4. صمم قالب للفاتورة واجلب بياناته من ورقة أخرى بدالة بحث مثلvlookup أو index match
  5. الـgit كان يشتغل سابقًا في الـ cmd لكن فجأة لم يعد يتعرف عليه على أنه يعمل في git-cmd وجربت التحقق من تغيرات البيئة ولم يجد ذلك نفعًا
  6. اليوم
  7. الحمدلله ان المشكله حلت قد تكون المشكلة كانت بسبب تداخل أو تعارض في الأذونات بين المجلدات الفرعية والمجلد الأساسي. يمكنك استخدام الأوامر مثل ls -l للتحقق من الأذونات ومالك الملفات بشكل دوري خاصة بعد التحديثات أو التغييرات الكبيرة.
  8. عند تنفيد السطر الاول حلت المشكلة غريب، كانت الصلاحيات في الفولدر 777 من البداية
  9. لحساب عدد ساعات العمل وعدد أيام العمل لكل موظف في Power BI باستخدام البيانات الموجودة في الصورة، يمكنك اتباع الخطوات التالية: 1. **استيراد البيانات**: - تأكد من استيراد الجدول في Power BI. 2. **إضافة أعمدة جديدة**: - أضف عمودين جديدين، أحدهما لتسجيل التوقيت (وقت الدخول والخروج) والآخر لتسجيل نوع الحركة (دخول أو خروج). 3. **تحديد وقت الدخول والخروج**: - قم بإنشاء عمود مخصص لتحديد نوع الحركة بناءً على ترتيب السجلات (دخول أو خروج). 4. **إنشاء جدول جديد يحتوي على الساعات**: - قم بإنشاء جدول جديد يحتوي على الأعمدة التالية: رقم الموظف، التاريخ، وقت الدخول، وقت الخروج. ### التعليمات بالتفصيل: **1. استيراد البيانات:** استورد جدول البصمة إلى Power BI. **2. إضافة أعمدة جديدة:** في Power BI Desktop، انتقل إلى "Transform Data" لإضافة أعمدة جديدة. **3. تحديد وقت الدخول والخروج:** قم بإنشاء عمود مخصص لتحديد نوع الحركة = if Time.Hour([CHECKTIME]) < 12 then "In" else "Out" **4. تنظيم البيانات:** يمكنك استخدام DAX لإنشاء جدول منظم للساعات. يمكن أن يكون الكود كالتالي: WorkHours = ADDCOLUMNS( SUMMARIZE( Table, Table[EmployeeID], Table[Date], "InTime", CALCULATE(MIN(Table[CHECKTIME]), Table[MovementType] = "In"), "OutTime", CALCULATE(MAX(Table[CHECKTIME]), Table[MovementType] = "Out") ), "WorkHours", DATEDIFF([InTime], [OutTime], HO UR) ) **5. حساب عدد ساعات العمل وعدد أيام العمل:** استخدم دالات DAX لحساب الساعات والأيام لكل موظف. لحساب عدد ساعات العمل لكل يوم: DailyHours = SUMMARIZE( WorkHours, WorkHours[EmployeeID], WorkHours[Date], "TotalHours", SUM(WorkHours[WorkHour s]) ) لحساب عدد أيام العمل لكل موظف: DaysWorked = SUMMARIZE( WorkHours, WorkHours[EmployeeID], "TotalDays", COUNTROWS(DISTINCT(WorkHours[Date] )) ) ### ملاحظات: - تأكد من ضبط تنسيقات التواريخ والأوقات بشكل صحيح في Power BI. - يمكن أن تحتاج إلى إجراء بعض التعديلات على البيانات الأصلية لضمان الدقة. باتباع هذه الخطوات، يمكنك حساب عدد ساعات العمل وعدد أيام العمل لكل موظف بنجاح.
  10. بما أن المسار صحيح ويعطيك الملفات الموجودة فيه، المشكلة قد تكون في صلاحيات الوصول أو في استخدام أسماء المجلدات داخل الكود. للتحقق أكثر، تحقق من الأذونات للمجلدات الفرعية والمجلد الذي يحتوي على السكريبت chmod -R 777 /home/1.****.com/public_html/images2/ وايضان يجب ان تتأكد من أن أسماء المجلدات في الكود تتطابق بالضبط مع الأسماء الموجودة في النظام، بما في ذلك الأحرف الكبيرة والصغيرة. في بعض الأحيان، قد تكون المشكلة ناتجة عن حرف مختلف في الاسم. بعد هذه التأكيدات اذا استمرت المشكله جرب ان تضف بعض التحقق من الأخطاء في الكود الخاص بك للحصول على مزيد من التفاصيل حول الخطأ لكي نستطيع ايجاد اين المشكله بالظبط $path = 'images2/2024/imk.jpg'; if (!file_exists(dirname($path))) { die('Directory does not exist: ' . dirname($path)); } if (!is_writable(dirname($path))) { die('Directory is not writable: ' . dirname($path)); } if (file_put_contents($path, $data) === false) { die('Failed to write to file: ' . $path); } جرب هذه الخطوات وإذا استمرت المشكلة، قدم لي الرسائل الجديدة التي تحصل عليها
  11. المسار صحيح اخي ، ويعطيني الملفات الموجودة فيه،
  12. تظهر الرسالة التحذيرية أن هناك مشكلة في فتح المجلد أو الملف المحدد. يمكن أن تكون المشكلة ناتجة عن عدة أسباب مثل ان المسار غير صحيح: تأكد من أن المسار images2/2024/imk.jpg هو المسار الصحيح وأنه موجود بالفعل. يبدو أن المجلد "images2" غير موجود في المسار المحدد في الرسالة التحذيرية. قد يكون المسار الصحيح هو images/2024/imk.jpg. تأكد من أن الأذونات مضبوطة بشكل صحيح لجميع المجلدات التي تشمل المسار الكامل. الصورة تظهر أن مجلد "images" لديه أذونات كاملة، ولكن تأكد أيضا من الأذونات للمجلدات الفرعية. للتأكد من وجود المسار الصحيح: ls -l /home/1.****.com/public_html/images2/2024/ إذا لم يكن المجلد موجودا، يمكنك إنشاء المجلدات الناقصة: mkdir -p /home/1.****.com/public_html/images2/2024/ بعد تنفيذ هذه التأكيدات، حاول تشغيل السكريبت مرة أخرى للتحقق من حل المشكلة. إذا استمرت المشكلة، يرجى تقديم المزيد من التفاصيل حول السكريبت والمزيد من الرسائل التحذيرية إن وجدت.
  13. لدي مشكلة في كود php لا يستطيع وضع الملف في الفولدر رغم انني اعطيته الصلاحيات الكاملة، ويرجع لي Warning: file_put_contents(images2/2024/imk.jpg): failed to open stream: No such file or directory in /home/1.****.com/public_html/getimg.php on line 79 اين تكمن المشكلة، هذه المشكلة ظهرت لي مؤخرا بعد تركيب احد السكريبتات في السرفر Ubuntu هل تكون من Owner؟
  14. تعد ريآكت React أحد أشهر مكتبات لغة جافا سكريبت المستخدمة في تطوير الواجهات الأمامية front-end development، إلا أن تطوير التطبيقات بهذه المكتبة يمكن أن يتسبب لك ببعض المشكلات مع محركات البحث. نستعرض في هذه المقالة أهم التحديات التي تواجه المطورين في تحسين محركات البحث SEO للتطبيقات المصممة باستخدام مكتبة ريآكت React، ونوضح أهم الخطوات التي يمكنك اتباعها لتجاوز هذه المشكلات بفعالية، وتحسين سيو التطبيقات، ورفع رتبتها في صفحة نتائج محرك البحث. لمحة عن ريآكت React وآلية عملها ريآكت React هي مكتبة جافا سكريبت مخصصة لإنشاء واجهات مستخدم تفاعلية متعددة المنصات وهي تعتمد على تقسيم التطبيق لعدة مكونات أو أجزاء صغيرة قابلة لإعادة الاستخدام لتساعد في إنشاء تطبيقات واجهات أمامية فعالة وعالية الأداء. طُورت مكتبة ريآكت في الأساس من أجل إنشاء تطبيقات الصفحة الواحدة Single Page Applications أو اختصارًا SPAs -وهي تطبيقات مبنية بالاعتماد على صفحة واحدة ويمكنك أن تنتقل بين صفحاتها دون الحاجة إلى تحميل الصفحات الجديدة بالكامل- ولكنها اليوم تصلح لإنشاء مختلف أنواع مواقع الويب وتطبيقات الجوال. إلا أن المواقع والتطبيقات المصممة بهذه المكتبة قد تواجه مجموعة من التحديات والمشكلات المتعلقة بترتيبها في محركات البحث، وهذا ما ستلاحظه بنفسك إذا كنت قد طورت في البداية تطبيقات ويب بالطريقة التقليدية وكتبت بنفسك كافة التعليمات الأساسية اللازمة لواجهات هذه التطبيقات دون الاستعانة بمكتبات أوأطر عمل جاهزة، ثم انتقلت بعد ذلك لاستخدام مكتبة ريآكت إذ ستلاحظ أن جزءَا كبيرًا من شيفرات HTML و CSS الخاصة بتطبيقك قد أصبحت جزءًا من شيفرات جافا سكريبت JavaScript. السبب في ذلك هو أن مكتبة ريآكت React لا توصي بإنشاء عناصر واجهة المستخدم أو تحديثها بشكل مباشر، بل تعتمد طريقة أخرى بدلاً وهي وصف (حالة state) عناصر واجهة المستخدم أي تصف كيف يجب أن تظهر واجهة المستخدم في أي وقت، ثم تُحدِّث بعد ذلك نموذج تمثيل المستند ككائن DOM ليتوافق مع هذه الحالة بطريقة فعالة، كما توفر ريآكت مكونات قابلة لإعادة الاستخدام يمكننا استخدامها لوصف حالة واجهة المستخدم. ونتيجة لذلك، سيتوجب عليك إجراء جميع التغييرات على واجهة المستخدم أو على مستند DOM من خلال محرك ريآكت، وبالرغم من أن هذا الأمر مريح للمطورين، إلا أنه من ناحية أخرى يجعل وقت تحميل الصفحات أطول بالنسبة للمستخدمين، كما أنه يتطلب المزيد من العمل في محركات البحث للعثور على المحتوى وفهرسته، الأمر الذي ينجم عنه مشكلات محتملة في ترتيب الصفحات المبنية باستخدام React في نتائج محركات البحث. سنشرح في الفقرات التالية من المقالة المزيد حول المشكلات التي قد تواجهها في سيو التطبيقات والمواقع التي أنشأتها باستخدام رياكت، ونوفر لك عدة حلول واستراتيجيات للتعامل معها والتخلص منها. طريقة زحف محرك البحث جوجل إلى صفحات الويب وفهرستها قبل الغوص في حلول تحسين سيو تطبيقات رياكت من الضروري أن تفهم كيف يزحف محرك البحث جوجل Google إلى تطبيقاتك ومواقعك ويفهرسها، فمحرك البحث جوجل هو أشهر محرك بحث ويتلقى ما يزيد على 90% من مجمل عمليات البحث عبر الإنترنت ويمكنك من خلال فهم طريقة عمله معرفة العوامل التي تؤثر على فهرسة موقعك. للنظر للصورة التالية المقتبسة من وثائق Google وتجدر الملاحظة بأن هذا المخطط ليس سوى رسم توضيحي مبسط لعملية فهرسة موقع الويب، فالفهرسة الفعلية التي يقوم بها زاحف جوجل Googlebot أعقد بكثير. خطوات فهرسة جوجل يتبع زاحف جوجل Googlebot عملية من عدة خطوات لفهرسة مواقع الويب وهي كالتالي: ينشئ زاحف جوجل رتل انتظار للزحف crawl queue يتضمن كافة عناوين URL التي اكتشفها والتي يحتاج للزحف إليها وفهرستها لاحقًا. عندما يكون الزاحف جاهزًا، فإنه يأخذ عنوان URL التالي في رتل الانتظار، ويرسل طلبًا لجلب محتوى HTML للصفحة. بعدها يقوم الزاحف Googlebot بتحليل محتوى HTML وتحديد فيما إذا كان يحتاج كذلك إلى جلب سكربتات جافا سكريبت وتنفيذها لعرض المحتوى. إذا كانت الإجابة نعم سيضاف عنوان URL إلى رتل انتظار التصيير render queue. لاحقًا، يقوم المصيّر renderer الخاص بالزاحف بجلب شيفرات جافا سكريبت وتنفيذها من أجل تصيير أو عرض render الصفحة ويرسل كود HTML الناتج مرة أخرى إلى وحدة لمعالجة الكود processing unit. تستخرج وحدة المعالجة جميع وسوم الروابط <a> لعناوين URL المكتشفة في صفحة الويب وتضيفها من جديد إلى رتل انتظار الزحف crawl queue. أخيرًا يضاف المحتوى إلى فهرس جوجل. لاحظ أن هناك اختلافات واضحة بين مرحلة المعالجة التي تحلل كود HTML ومرحلة التصيير التي تنفذ أكواد جافا سكريبت لاحقًا، والسبب في ذلك هو أن تنفيذ أكواد جافا سكريبت مكلف ويستغرق وقتًا طويلاً جدًا، ويحتاج زاحف جوجل للاطلاع على ما يزيد على 130 تريليون صفحة على الويب، لذا عندما يزحف على صفحة ويب فإنه يحلل HTML فورًا ثم يضع أكواد جافا سكريبت في رتل انتظار لتشغيلها لاحقًا، وبحسب وثائق جوجل قد تبقى أكواد جافا سكريبت في رتل انتظار التصيير render queue لمدة بضع ثوانٍ أو أكثر. ومن الجدير بالذكر أيضًا الإشارة إلى ميزانية الزحف، فعملية زحف وفهرسة جوجل مقيدة بالموارد المتاحة مثل سعة النطاق الترددي والوقت وعدد روبوتات جوجل المتاحة. وتخصص جوجل ميزانية أو موارد محددة لفهرسة كل موقع إلكتروني على شبكة الإنترنت. فإذا كنت تنشئ موقع ويب ضخم يضم آلاف الصفحات والكثير من المحتوى كموقع تجارة إلكترونية على سبيل المثال، وتستخدم في صفحات موقعك قدرًا كبيرًا من أكواد جافا سكريبت لعرض المحتوى، فقد لا يتمكن جوجل من الزحف لكافة صفحات موقعك وقراءة كافة محتوياته لأنه مكلف في الزحف. ملاحظة: ينصح بقراءة الإرشادات التي يعتمدها جوجل من أجل إدارة وتحسين ميزانية الزحف الخاصة بك من هنا. لماذا يمثل السيو تحديًا في ريآكت React ؟ بعد أن كونت فكرة عامة عن طريقة عمل زاحف جوجل Googlebot وفهرسته للموقع ستتمكن كمهندس برمجيات من تحديد المشكلات المحتملة التي تواجهها محركات البحث التي تحاول الزحف إلى صفحات مواقع أو تطبيقات ريآكت وفهرستها بشكل أفضل. وفيما يلي نبين أبرز أسباب حدوث مشكلات في تحسين محركات البحث لمواقع وتطبيقات React ونوضح سبل حلها والتغلب عليها. السبب الأول: محتوى الصفحة فارغ عند المرور عليها لأول مرة تعتمد تطبيقات ريآكت بشكل أساسي على أكواد جافا سكريبت لعرض المحتوى الديناميكي للصفحات، لذا تواجه مشكلات مع محركات البحث في معظم الحالات، حيث تعتمد ريآكت بشكل افتراضي على بنية أو نموذج (هيكل التطبيق App Shell) وهو نموذج لتصميم لتطبيقات الويب يعتمد على إنشاء ملف HTML أساسي عند تحميل الصفحة، ولكن لا يحتوي هذا الملف على أي محتوى ذي معنى، ويجب على المستخدم أو روبوت الزحف تنفيذ أكواد جافا سكريبت لإنشاء ورؤية المحتوى الفعلي للصفحة. وهذا بدوره يعني أن زاحف جوجل Googlebot سيعثر على صفحة فارغة عند مروره الأول على الصفحة ولن يرى المحتوى الفعلي إلا في مرحلة تصيير أو عرض الصفحة، ونظرًا لكون الزاحف يتعامل مع آلاف الصفحات، سيتسبب هذا الأمر في تأخير فهرسة المحتوى. السبب الثاني: زيادة وقت التحميل التي تؤثر على تجربة المستخدم UX قد يستغرق جلب أكواد جافا سكريبت وتحليلها وتنفيذها وقتًا طويلًا، أضف إلى ذلك فقد تحتاج أكواد جافا سكريبت إلى الاتصال مع شبكة لطلب المحتوى من مصادر مختلفة (مثل قواعد البيانات أو الواجهات البرمجية APIs) وفي هذه الحالة سيضطر المستخدم إلى الانتظار لفترة من الزمن قبل أن يتمكن من الحصول على نتيجة الطلب وعرض المعلومات المطلوبة. وبما أن جوجل تعتبر أن مواقع الويب التي تستغرق وقتًا طويلاً للتحميل تؤثر سلبًا على تجربة المستخدم وتعتمد هذا الأمر كمعيار لتحديد ترتيب المواقع في محركات البحث فالمواقع الأبطأ في التحميل ستحصل على ترتيب أقل في صفحة نتائج البحث. السبب الثالث: صعوبة تخصيص البيانات الوصفية metadata لكل صفحة من صفحات الموقع تفيد الوسوم الوصفية أو ما يعرف بوسوم ميتا في وصف صفحات الموقع لمحركات البحث، وتسمح لمحرك بحث جوجل ولمواقع التواصل الاجتماعي بإظهار عناوين وأوصاف هذه الصفحات وصورها المصغرة، لكن المواقع المطورة باستخدام ريآكت تستخدم الوسم في صفحات الويب المستردة للحصول على هذه المعلومات، وهي لا تنفذ شيفرات جافا سكريبت للصفحة الهدف. كما تعتمد رياكت على منهجية تصيير كل المحتوى بما في ذلك وسوم ميتا من جانب العميل، وبالتالي سيكون هيكل التطبيق App shell هو نفسه لكامل الموقع أو التطبيق، بمعنى آخر ستكون البيانات الوصفية metadata موحدة لكافة صفحات موقع الويب أو التطبيق وسيكون من الصعب تخصيص هذه البيانات لكل صفحة على حدة، وبهذا سترى محركات البحث نفس البيانات الوصفية لجميع الصفحات، حتى لو كانت هذه الصفحات مختلفة تمامًا عن بعضها البعض وهذا قد يؤثر على فهرستها بصورة صحيحة. السبب الرابع: عدم وجود طريقة مدمجة لإنشاء خريطة الموقع Sitemap خريطة الموقع Sitemap هي ملف يوفر معلومات حول محتوى صفحات الموقع ومقاطع الفيديو التي تتضمنها والملفات الأخرى الموجودة على الموقع، ويوضح العلاقات أو الروابط فيما بينها، وتقرأ محركات البحث -ومن بينها محرك جوجل- هذا الملف لتتمكن من الزحف إلى موقعك بطريقة أفضل. ولا توفر مكتبة ريآكت طريقة مدمجة لإنشاء خريطة الموقع، لكن في حال كنت تستخدم مكتبة React Router للتعامل مع توجيه الصفحات Routing فيمكنك في هذه الحالة العثور على أدوات مساعدة لإنشاء خريطة الموقع، لكن هذا قد يحتاج منك لبعض الجهد. نصائح عامة لتحسين محركات البحث غير مرتبطة بمكتبة ريآكت إليك أهم النصائح والممارسات التي يمكنك الأخذ بها لتحسين محركات البحث للمواقع والتطبيقات بشكل عام وليست خاصة بتطبيقات ريآكت فقط. احصل على عنوان URL سهل لموقعك أو تطبيقك ويمكن فهمه من قبل البشر ومحركات البحث ويعطي فكرة واضحة عن المحتوى الذي يتضمنه. حَسّن ملف robots.txt لمساعدة روبوتات البحث على فهم كيفية الزحف إلى صفحات موقعك. استخدم شبكة توصيل محتوى CDN لتخزين جميع الأصول الثابتة مثل CSS و JS والخطوط، واستخدم صورًا متجاوبة لتقليل أوقات تحميل الصفحات. كما يمكن معالجة العديد مشكلات السيو باستخدام التصيير من جانب الخادم SSR أو التصيير المسبق pre-rendering وسنستعرض هذه الأساليب بمزيد من التفصيل في فقرات لاحقة. ما هي تطبيقات ريآكت المتماثلة Isomorphic يشير مصطلح إسومورفيك Isomorphic بشكل عام إلى التوافق أو التشابه في الشكل، أما في مكتبة ريآكت React فهو يعني هذا أن الخادم والعميل لهما له نفس نموذج أو قاعدة الشيفرة تقريبًا، بمعنى آخر يمكن إعادة استخدام نفس مكونات ريآكت React على كل من الخادم والعميل. وبالتالي يعرف تطبيق رياكت المتماثل Isomorphic بأنه تطبيق يمكن تشغيله على كل من جانب العميل وجانب الخادم باستخدام نفس الشيفرة، إذ يمكن استخدام نفس المكونات على كل منهما ونفس المنطق في التصيير على الخادم والتصيير على العميل وهذا يقلل هذا من تكرار الشيفرة ويضمن تناسق التطبيق. يسمح هذا النهج المتماثل للخادم يتصيير render تطبيق رياكت وإرسال النتيجة إلى المستخدمين ومحركات البحث ليتمكنوا من عرض المحتوى على الفور، بينما تُحمّل أكواد وتنفذ جافا سكريبت في الخلفية وقد اعتمدت عدة أطر على هذا الأسلوب وزادت من شهرته مثل إطار Next.js ومولد المواقع Gatsby . تجدر الملاحظة بأن المكونات المتماثلة قد تبدو مختلفة عن مكونات React التقليدية بشكل واضح. على سبيل المثال، يمكن أن تحتوي على كود يعمل على الخادم بدلاً من العميل، كما يمكن أن تشمل حتى مفاتيح سرية وبيانات وصول لواجهات برمجة التطبيقات API رغم أن كود الخادم يحذف قبل إرساله للعميل. تسهل هذه الأطر من الكثير من التعقيدات على المطورين وتقدم طريقة محددة لكتابة التعليمات البرمجية. وسنتعمق في تأثيرها على أداء التطبيقات ونوضح العلاقة بين مسارات التصيير render paths وأداء الموقع لاحقًا، لكن لنناقش قبل ذلك بعض المعايير الأساسية لقياس أداء موقع الويب. مقاييس أداء الموقع سنوضح الآن بعض المعايير التي تستخدمها محركات البحث لتصنيف وترتيب مواقع الويب لنساعدك على فهم المزيد حول رفع رتبة موقعك في نتائج البحث. إلى جانب الإجابة على استفسار المستخدم بسرعة ودقة، تعتقد جوجل أن موقع الويب الجيد يجب أن يحقق ما يلي: يتمكن المستخدمون من الوصول إلى محتوى الموقع بسرعة ودون الانتظار لوقت طويل. يتفاعل الموقع مع إجراءات المستخدم خلال وقت قصير. يُحمّل الموقع بسرعة. لا يجلب الموقع أي بيانات غير ضرورية، ولا ينفذ تعليمات برمجية مستهلكة للموارد تستنزف بيانات المستخدم أو موارد جهازه. تتوافق هذه الميزات تقريبًا مع المقاييس التالية: زمن وصول أول بايت (TTFB): هو اختصار لعبارة Time to First Byte ويعني مقدار الوقت الذي يستغرقه وصول أول جزء من المحتوى من الخادم إلى المتصفح، أو الوقت بين النقر على الرابط ووصول الجزء الأول من المحتوى للمستخدم. أضخم محتوى مرئي (LCP): وهو اختصار لعبارة Largest Contentful Paint ويمثل الزمن الذي يحتاجه عرض العنصر الذي يتضمن أضخم جزء مرئي من الصفحة وهو يعطي فكرة عن زمن انتظار المستخدم لتحميل ما يكفي من الصفحة لتصبح ذات معنى، وتوصي جوجل بأن لا تتجاوز هذه القيمة 2.5 ثانية. زمن التفاعل (TTI): وهو اختصار لعبارة Time to Interactive ويعني الوقت الذي تصبح فيه الصفحة تفاعلية أي يمكن للمستخدم النقر فوق عناصر أو تمريرها…إلخ. حجم الحزمة (Bundle Size): ويمثل إجمالي عدد البايتات المحملة والتعليمات البرمجية المنفذة قبل أن تصبح الصفحة مرئية وتفاعلية بالكامل. سنعود للحديث عن هذه المقاييس لاحقًا لفهم كيفية تأثير مسارات التصيير render paths المختلفة على كل منها بشكل أفضل. وسنوضح تاليًا ما هي مسارات التصيير المتاحة لمطوري رياكت. مسارات التصيير Render Paths نعني بمسارات التصيير الطرق المختلفة التي يمكن من خلالها الوصول إلى محتوى الصفحة حيث يمكننا تصيير أو عرض تطبيق React على جانب المتصفح client-side أو على جانب الخادم server-side وإنتاج مخرجات مختلفة. وهنالك وظيفتان تتفاوتان بشكل كبير بين التطبيقات المصيًّرة من جانب العميل والخادم وهما عملية التوجيه routing، وعملية تقسيم التعليمات البرمجية code splitting، لنتعرف على آلية القيام بكل منهما في كل حالة: حالة التصيير من جانب العميل (CSR) التصيير من جانب العميل هو مسار التصيير الافتراضي في تطبيقات رياكت ذات الصفحة الواحدة React SPA. حيث أن الخادم يوفر غلاف تطبيق shell app لا يتضمن أي محتوى فعلي وبمجرد قيام المتصفح بتحميل أكواد جافا سكريبت JavaScript المضمنة في الصفحة ويحللها وينفذها سيملأ محتوى HTML ويعرض بالكامل. في هذه الحالة يتم التعامل مع وظيفة التوجيه بواسطة تطبيق العميل client app من خلال إدارة سجل المتصفح browser history. وهذا يعني أنه يتم تصيير أو عرض نفس ملف HTML بغض النظر عن المسار الذي طُلِب، ويقوم العميل بتحديث حالة العرض view state الخاصة به بعد عرضه. أما تقسيم الكود في هذه الحالة فهو أمر بسيط نسبيًا حيث يمكن تقسيم التعليمات البرمجية الخاصة بالتطبيق باستخدام الاستيراد الديناميكي dynamic imports أو بالاستعانة بمكتبة React.lazy إذ يقسم الكود بحيث يتم تحميل التبعيات المطلوبة فقط بناءً على المسار أو إجراءات المستخدم. إذا كانت الصفحة بحاجة إلى جلب بيانات معينة من الخادم لتصيير المحتوى مثل عنوان المدونة أو وصف منتج ما فلن تتمكن من القيام بذلك إلا عندما يتم تثبيت المكونات ذات الصلة وعرضها، وسيرى المستخدم غالبًا عبارة مثل "جاري تحميل البيانات" أثناء قيام موقع الويب بجلب واستيراد الموقع لبيانات إضافية. إذَا في هذه الحالة لن تسترد البيانات من الخادم إلا عند الحاجة إليها لعرض المحتوى. وهذا يقلل وقت التحميل الأولي للصفحة ويوفر تجربة مستخدم أفضل. ومع ذلك، قد يرى المستخدم مؤشر تحميل أثناء استرداد البيانات الإضافية. التصيير من جانب العميل باستخدام البيانات التمهيدية (CSRB) لنفترض أن لدينا حالة تصيير من جانب العميل CSR ولكن بدلاً من جلب البيانات بعد تصيير وعرض مستند DOM بحيث تظهر المحتويات أو البيانات ذات الصلة بشكل تدريجي، سنفترض أن الخادم يرسل البيانات ذات الصلة مباشرة داخل كود HTML المُصَيَّر. يمكن أن نضيف عقدة node كما يلي داخل صفحة HTML: <script id="data" type="application/json"> {"title": "My blog title", "comments":["comment 1","comment 2"]} </script> يضمن هذا الكود البيانات بصيغة JSON داخل صفحة HTML، وتحلل هذه القاعدة التي تحتوي على البيانات المطلوبة (وهي عنوان المدونة والتعليقات عليها) وتفسر عند إضافة المكون إلى مستند DOM على النحو التالي: var data = JSON.parse(document.getElementById('data').innerHTML); بهذا نكون قد وفرنا عملية ذهاب وعودة من الخادم، وسيظهر المحتوى بشكل أسرع للمستخدم لأن المتصفح لم يضطر إلى الانتظار لطلب البيانات من الخادم مرة أخرى. تصيير المحتوى الثابت من جانب الخادم (SSRS) في هذه الحالة يتم إنشاء وتصيير الصفحة بالكامل على جانب الخادم قبل إرساله إلى المتصفح، تخيل على سبيل المثال حالة لموقع أو تطبيق ويب تحتاج فيه إلى إنشاء كود HTML بسرعة، على سبيل المثال إذا كنت تريد بناء تطبيق ريآكت لآلة حاسبة عبر الإنترنت، وأدخل المستخدم لهذا التطبيق استعلام من المستخدم من خلال عنوان URL على النحو التالي: /calculate/34+15 يحتاج التطبيق لمعالجة هذا الاستعلام وتقييم النتيجة والرد بكود HTML الذي تم إنشاؤها، وبما أن كود HTML النتاتج يملك بنية بسيط جدًا فلست بحاجة لأن تقوم رياكت بإدارة DOM ومعالجته ويمكنك الاكتفاء بعرض HTML الناتج مباشرة. لذلك يمكن توفير محتوى HTML و CSS فقط واستخدام التابع renderToStaticMarkup لتحقيق ذلك. سيتعامل التطبيق في هذه الحالة مع التوجيه بالكامل من جانب الخادم لأنه يحتاج إلى إعادة حساب HTML لكل نتيجة (كلما تم تغيير عنوان URL)، كما يمكن استخدام التخزين المؤقت لكود HTML الناتج ضمن شبكة توصيل المحتوى CDN لتسريع استجابة التطبيق. ويمكن أيضًا تخزين ملفات CSS مؤقتًا بواسطة المتصفح لتحميل الصفحات اللاحقة بسرعة أكبر. التصيير من جانب الخادم مع المكونات المعززة (SSRH) المكونات المشبعة أو المعززة Hydrated Components هي مكونات رياكت تعمل كجسر بين نسخ التطبيق التي تنشأ على الخادم والعميل، ولفهم آلية عملها تخيل الآن أنك تحتاج لتطوير تطبيق رياكت كامل الوظائف على العميل، أي تطبيق يتطلب تفاعل المستخدمين ويوفر إمكانية تنقلهم بين الصفحات ويحتاج لجلب البيانات من الخادم. ملاحظة:يشير مصطلح التشبيع أو التعزيز hydration في رياكت إلى الطريقة التي تتصل بها React مع كود HTML الموجود مسبقًا والذي تم تصييره بالفعل بواسطة رياكت في جانب الخادم. فهو عملية يتم فيها ربط أو تعزيز شيفرة جافا سكريبت التفاعلية لمحتوى HTML الثابت المصير مسبقًا على الخادم لجعل كود HTML تفاعليًا. وبالتالي تقوم رياكت بتنفيذ التصيير الأول لصفحات الموقع على الخادم، وترسل محتوى HTML الناتج إضافة إلى ملفات جافا سكريبت إلى العميل، ثم تقوم بإعادة تعزيز الكود المرسل من جانب الخادم، ليصبح التطبيق وكأنه تطبيق تصيير من جانب العميل (CSR) من هذه النقطة فصاعدًا. توفر رياكت عدة طرق مدمجة لتنفيذ هذه الإجراءات تسمى ReactDOMServer، حيث تعالج رياكت أول طلب لعرض أو تصيير صفحة ما من جانب الخادم، ثم تتعامل مع الطلبات التالية لعرض هذه الصفحة من جانب العميل. ولهذا يطلق على هذه التطبيقات اسم تطبيقات رياكت العامة لكون عملية العرض أو التصيير تتم على جانبي الخادم والعميل كليهما، وقد يتم تقسيم (أو تكرار) الكود الذي يتعامل مع التوجيه على كل من الخادم والعميل. إن تقسيم الكود أمر صعب بعض الشيء أيضًا، لأن توابع ReactDOMServer المستخدمة لإنشاء صفحات HTML ثابتة على الخادم لا تدعم React.lazy، لذلك لا يمكن استخدامها لتحميل المكونات ديناميكيًا على الخادم وللتعامل مع هذا الأمر قد تضطر لاستخدام المكونات القابلة للتحميل وهي مكونات يمكنك تحميلها ديناميكيًا عند الحاجة. وقد تضطر إلى استخدام شيء مثل Loadable Components. يجب التنويه أيضًا أن ReactDOMServer تقوم فقط بعرض بسيط. وبالرغم من استدعاء طريقة التصيير لمكوناتك، إلا أن الطريقة componentDidMount التي ستحتاج لاستدعائها بعد أن يتم تثبيت المكون في DOM لا تستدعى في هذه الحالة. لذلك تحتاج إلى إعادة تصميم كودك لتوفر البيانات لمكونات التطبيق باستخدام طريقة بديلة. هنا تبرز فائدة إطارات العمل مثل NextJS. فهي تختفي التعقيدات المرتبطة بعمليات التوجيه وتقسيم الكود في حالة تصيير الصفحات على الخادم وتعتمد أسلوب التصيير من جانب الخادم مع المكونات المعززة SSRH لتوفر تجربة أكثر سلاسة للمطورين. التصيير المسبق للمحتوى الثابت (PRS) ماذا لو تمكنا من عرض صفحات الموقع قبل أن يطلبها المستخدم؟ يسمى هذا الأمر التصيير المسبق Pre-rendering وهو أسلوب لإنشاء محتوى HTML للتطبيق بالكامل على الخادم قبل أن يطلبه المستخدم، بعدها يرسل المحتوى للمتصفح ويعرض مباشرة دون الحاجة إلى إنشاء واجهة المستخدم بالكامل من البداية، ويمكن القيام بذلك في وقت إنشاء الموقع أو ديناميكيًا عندما تتغير البيانات. ويمكن فيما بعد تخزين محتوى HTML الناتج على شبكة توصيل المحتوى CDN وتصييره بشكل أسرع عندما يطلبه المستخدم وهو أمر مفيد في كافة المواقع التي لا يعتمد محتواها على البيانات المقدمة من قبل المستخدم كالمدونات وتطبيقات التجارة الإلكترونية. التصيير المسبق مع تفعيل المكونات (PRH) قد ترغب في أن يكون HTML المصير مسبقًا تطبيق React يعمل بكامل طاقته عندما يعرضه العميل. في هذه الطريقة، ينشأ محتوى HTML للتطبيق بالكامل على الخادم كما هو الحال في التصيير المسبق العادي، وإلى جانب ذلك تضمن كذلك معلومات الحالة المقابلة لكل عنصر رياكت في محتوى HTML. وبالتالي في هذه الطريقة، بعد تقديم الطلب الأول لعرض التطبيق، سيتصرف التطبيق مثل تطبيق React القياسي. وبشكل مشابه لحالة تصيير الصفحات على الخادم SSRH من حيث التعامل مع وظائف التوجيه وتقسيم التعليمات البرمجية. مصفوفة الأداء لنناقش الآن كيفية تأثير كل مسار من مسارات التصيير التي وضحناها سابقًا على مقاييس أداء مواقع الويب ونعرف أي طريقة منها هي الأفضل من خلال الجدول التالي الذي يعطي نتيجة تتراوح من 1 إلى 5 وتدل النتائج على ما يلي: نتيجة غير مرضية نتيجة ضعيفة 3.نتيجة متوسطة نتيجة جيدة نتيجة ممتازة TTFB LCP TTI حجم الحزمة المجموع CSR 5 يمكن تخزين HTML مؤقتاً على شبكة CDN 1 يحتاج للذهاب مرات متعددة للخادم لجلب البيانات 2 تأخر في جلب البيانات وفي تنفيذ أكواد جافا سكريبت 2 تحميل جميع تبعيات الجافا سكريبت قبل التصيير 10 CSRB 4 يمكن تخزين HTML مؤقتًا بشرط عدم اعتماده على بيانات الطلب 3 تحميل البيانات مع التطبيق 3 يجب جلب جافا سكريبت وتحليلها وتنفيذها قبل التفاعل 2 تحميل جميع تبعيات الجافا سكريبت قبل التصيير 12 SSRS 3 يُولَّد كود HTML في كل طلب ولا يمكن تخزينه مؤقتًا 5 عدم تحميل جافا سكريبت أو عمليات غير متزامنة 5 الصفحة تكون تفاعلية فورًا بعد الرسم الأول 5 يحتوي على المحتوى الثابت الأساسي فقط\ 18 SSRH 3 يُولَّد HTML في كل طلب ولا يمكن تخزينه مؤقتًا 4 الرسم الأول أسرع بسبب التصيير الأول على جانب الخادم 2 أبطأ بسبب تنشيط DOM بعد تحليل ورسم HTML أول مرة 1 HTML الناتج+ تحميل تبعيات الجافا سكريبت 10 PRS 5 تخزين HTML مؤقتًا على شبكة CDN 5 عدم تحميل جافا سكريبت أو عمليات غير متزامنة 5 تكون الصفحة تكون تفاعلية فورًا بعد الرسم الأول 5 يحتوي على المحتوى الثابت الأساسي فقط 20 PRH 5 تخزين HTML مؤقتًا على شبكة CDN 4 التصيير الأول أسرع بسبب التصيير من جانب الخادم لأول مرة 2 أبطأ بسبب تفعيل DOM بعد تحليل ورسم HTML الأول 1 HTML المصير+ تحميل تبعيات الجافا سكريبت 12 يمكن أن نستنتج من الجدول السابق ما يلي: يؤدي التصيير المسبق للمحتوى الثابت (PRS) إلى أفضل أداء لمواقع الويب، بينما قد يؤدي التصيير من جانب الخادم مع المكونات المعززة (SSRH) أو التصيير من جانب العميل (CSR) إلى نتائج غير مرضية. من الممكن أيضًا استخدام أساليب متعددة لأجزاء مختلفة من موقع الويب. على سبيل المثال، قد تكون مقاييس الأداء هذه مهمة لصفحات الويب العامة حتى يمكن فهرستها بشكل أكثر فعالية، بينما قد تكون أقل أهمية بمجرد دخول المستخدم ورؤية بيانات حسابه الخاصة. يعتمد اختيار كل مسار على طبعة تطبيقك وكيفية معالجة بياناتك، اختر ما يناسبك بحيث تحسن تجربة المستخدمين بأفضل صورة ممكنة. طرق إضافية لتحسين سيو مواقع الويب حاولنا في هذه المقالة أن نناقش الأساليب والتقنيات الشائعة حاليًا بتحسين أداء تطبيقات رياكت وتعزيزها في محركات البحث، ويمكن إضافة إلى ما سبق الاطلاع على النصائح والاستراتيجيات التي يوفرها مطورو جوجل. وأخيرًا من العوامل الإضافية التي تساعدك على تحسين سيو تطبيقات ومواقع الويب المطورة بمكتبة رياكت اعتماد نظام إدارة محتوى موقعك CMS جيد لاسيما عند إنشاء مواقع ويب ذات محتوى ضخم، وتوفير ميزة إنشاء وتعديل معاينات وسائل التواصل الاجتماعي بسهولة وتحسين الصور لتتناسب مع مختلف أحجام الشاشات فهذه العوامل من شأنها تحسين سرعة تحميل الصفحة وتحسين تجربة المستخدم بشكل كبير. الخاتمة هذا تكون قد وصلت لنهاية هذا المقال الذي وضحنا فيه أبرز تحديات تحسين محركات البحث في تطبيقات ومواقع رياكت، ووضحنا أهم الاستراتيجيات التقنيات المستخدمة التي يمكنك القيام بها للتغلب عليها لتحسين سيو تطبيقات ومواقع رياكت React الخاصة بك وتحسين فرصك في ظهورها في نتائج البحث. اقرأ أيضًا مقارنة شاملة بين رياكت React و Next.js المصطلحات المستخدمة في React شمولية تطبيقات React لكافة أنواع المستخدمين تقسيم تطبيق React إلى مكونات
  15. لم ينجح عندما قمت بعم لم ينجح الامر عندما قمت بعمل هاذه الخطوة if Text.End([CHECKTIME], 2) = "AM" then "Entry" else "Exit" وبعدها قمت بعمل Pivot column اصبحت القيم لدي 0 و 1 مما جعل هذه الخطوة Duration.TotalHours([Exit] - [Entry]) لا تعمل وتعطي نتائج 1 و -1
  16. السلام عليكم أمل ، لفصل توقيـت الدخول والخروج في عمودين منفصلين لحساب ساعـات العمل لكل موظف، يمكنك استخدام برنامج Power BI واستخدام استعلامات DAX أو Power Query سـوف أوضح لكى كيفيـة القيام بذلك باستخدام Power Query، وهو جزء من Power BI Desktop. اولا قومى بتحميل البيانات إلى Power BI: افتحى Power BI Desktopوانقرى على Get Data وحددى نوع البيانات Excel إذا كانت بياناتك في ملف Excel. وقمى بتحميل الجدول الذي يحتوي على بيانات البصمة. ومن ثـم افتحى محرر Power Query: -بعد تحميل البيانات، انقرى على Transform Data لفتح محرر Power Query. -إضافة عمود مخصص لتحديد نوع الحدث دخول أو خروج. -اختر الجدول الخاص بك في Power Query. -اضغطى على Add Column ثم Custom Column أضفى عمود مخصص لتحديد نوع الحدث دخول أو خروج بناء على الوقت. يمكنك استخدام صيغة لتحديد ما إذا كان الوقت في الصباح (AM) هو دخول وما إذا كان في المساء PM هو خروج: if Text.End([CHECKTIME], 2) = "AM" then "Entry" else "Exit" فصل التاريخ والوقت: استخدمى Split Column لفصل التاريخ والوقت في عمود CHECKTIME إلى تاريخ ووقت ،.واخترى العمود CHECKTIME. انقر على Home ثم Split Columnواختر By Delimiter واختر Space كالفاصل. تحويل النص إلى تاريخ/وقت: حددى العمود الذي يحتوي على التاريخ وحوله إلى نوع البيانات Date. حددى العمود الذي يحتوي على الوقت وحوله إلى نوع البيانات Time. ومن ثم نجعل الجدول Pivot: -استخدم Pivot Column لجعل القيم في عمود نوع الحدث دخول أو خروج كعناوين أعمدة. -اخترى العمود الذي يحتوي على نوع الحدث.وانقرى على Transform ثم Pivot Column. -في نافذة Pivot Column، اختر العمود الذي يحتوي على الوقت كقيم. ومن ثم نقوم بحساب عدد الساعات: أضفى عمود مخصص جديد لحساب عدد الساعات بين الدخول والخروج. اضغطى على Add Column ثم Custom Column. استخدم صيغة لحساب الفرق بين وقت الدخول ووقت الخروج: Duration.TotalHours([Exit] - [Entry]) واخيرا انقرى على Close & Apply لتطبيق التغييرات والعودة إلى Power BI وبعد ذلك قومى بإنشاء التقارير التى تريدين.
  17. انا اعمل على برنامج Power bi لدي جدول البصمة يحتوي على عمود رقم الموظف وعمود تاريخ دخول وخروج الموظف وتوقيت خروج ودخول الموظف تكمن المشكله في عدم تمكني في حساب عدد ساعات العمل ان وقت الخروج والدخول في نفس العمود وكل منهما في صف كما في الصورة اريد ان احسب عدد ساعات العمل في اليوم وعدد ايام العمل لكل موظف لم استطع ان اقوم بفصل التوقيت AM و PM كل منهما في عمود حتى اقوم بحساب عدد الساعات هل يمكن لاحد ان يقدم لي المساعدة؟
  18. شكراً استاذ : El Sayed El Tohamy شكراً على ، الاهتمام و الطرح المتميز ، و المعلومة الهامة التي قدمتها لنا ، فعلاً تم حل المشكل بفضلكم و توجيهاتكم ،قمت بإجراء بعض التغييرات و بالاضافة الى السطر الخاص بـ "gradle.properties" شكراً استاذ مرة اخرى تمنياتي لك بالتوفيق
  19. البارحة
  20. تلك قائمة من القواميس (dictionaries)، لا تستطيع الوصول إلى عنصر بشكله مباشرة باستخدام مفتاح كما فعلت، بل تحتاج إلى تحديد العنصر في القائمة أولاً ثم الوصول إلى القيمة باستخدام المفتاح المناسب. arr = [ {'4': 'bog'}, {'2': 'took'}, {'3': 'his'}, {'-2': 'Vatsan'}, {'5': 'for'}, {'6': 'a'}, {'12': 'spin'} ] for dictionary in arr: if '2' in dictionary: print(dictionary['2']) break لاحظ البحث عن القاموس الذي يحتوي على المفتاح '2' ثم طبع القيمة المرتبطة به، وفي حال أنك متأكد أن المفتاح موجود في القاموس الثاني، فنصل إليه مباشرة هكذا: print(arr[1]['2'])
  21. السلام عليكم ازي هنا اقدر الوصل لمفتاح ؟ ان عملت كده بس بيظهر خطاء arr = [ {'4':'bog'}, {'2':'took'}, {'3':'his'}, {'-2':'Vatsan'}, {'5':'for'}, {'6':'a'}, {'12':'spin'} ] print(arr['2'])
  22. لوحظ على الكثير من الفرق التي تدّعي أنها تعمل بمنهجية أجايل عيوبٌ جسيمة، مثل الإجراءات المقيَّدة ودورات التطوير التي لا تنتهي وانسداد مسار ضمان الجودة. وتنشأ معاناة هذه الفرق من الهوّة الكبيرة بين ما يعتقدون أنها منهجية أجايل من جهة، وما هي منهجية أجايل الحقيقية من جهةٍ أخرى. لنتحدث بالتفصيل عن الأخطاء الشائعة التي تقع بها بعض الفرق التي تطبق منهجية أجايل معيبة، مع التطرق إلى الحلول الممكنة لتحسين تقديم البرمجيات ورفع معنويات المطورين. ما هو المفهوم الصحيح لمنهجية أجايل؟ أجايل هي منهجية تسعى للمساعدة على تقديم البرمجيات بالشكل الذي ترغب به الأطراف المعنية. نشأت هذه المنهجية على أنقاض العقبات والمصاعب التي كانت تواجه نماذج التطوير السابقة، والتي كانت تنص على أن البرنامج يجب أن يكون أولًا واضح المعالم ثم تجري هندسته، بعدها يقدَّم بشكله النهائي المكتمل. كانت النماذج السابقة لأجايل تحمل مخاطر كبيرة، فعند تقديم البرنامج بشكله المكتمل، قد تكون احتياجات العميل قد تغيرت بحلول نهاية المشروع، وربما يتبين أنها لم تكن مفهومةً جيدًا عندما تم افتراضها في البداية. لكن منهجية أجايل ليست كذلك، فمن خلال إبقاء قناة التواصل مفتوحة، يمكن تغيير المتطلبات قبل هدر الوقت والجهد في تنفيذ منتج خاطئ، ويمكن تقييم التعديلات الجديدة للتحقق من ملاءمتها. يجب أن تنبع جميع عمليات وهيكليات أجايل من القيم والمبادئ التي تنص عليها اتفاقية أجايل، كما يجب الاستفسار عن سبب كل قرار تقني وكل ممارسة ودور ضمن العمل، ليكون التبرير مرتبطًا بواحد أو أكثر من هذه القيم والمبادئ. مع ذلك يمكن القول أن فرق أجايل تنفذ جميع عمليات وهيكليات أجايل دون أن تحقق مكاسب بسهولة، والقاسم المشترك بين الفرق التي تعاني من صعوبات هي أنها تنتهج منهجية أجايل من خلال ممارسات مقيَّدة وصارمة، بدلًا من أن تستفيد من المرونة التي هي السمة العامة لهذه المنهجية كما يشير اسمها. تزييف أجايل: مخاطر التقليد السطحي ربما مرّت عليك بعض المتاجر التي يدّعي أصحابها أن لديهم منتجات مطابقة للعلامات التجارية الأصلية، يتركز هؤلاء البائعون في أسواق معينة، وتفتقر متاجرهم لعلامة تجارية ذات سمعة، إلا أن ميزتهم الوحيدة هي انخفاض أسعار منتجاتهم. على سبيل المثال، من الممكن أن تشتري سماعات لاسلكية لها نفس شكل سماعات آبل ونفس حجمها ولونها، لكن عندما تستلمها تلاحظ أن التشابه ينتهي عند الناحية الشكلية والجمالية، وذلك عندما تواجه صعوبةً بربطها بأجهزتك، كما تكتشف لاحقًا أن الصوت من خلالها رديء. صحيح أن السماعات مجهولة الاسم قلدت بشكلها الخارجي سماعات آبل من خلال استنساخ مواصفاتها الخارجية لكي تزداد فرص بيعها، إلا أن مواصفاتها لم تكن فعالة بما يكفي لتعطي منتجًا مفيدًا. هناك الكثير من فرق العمل التي تقع في فخ ملاحظة شيء يفعله الآخرون ويقودهم إلى النجاح ثم محاولة تقليده، لكن بطريقة خاطئة بسبب الفهم غير المكتمل؛ لذا يمكن القول أن الاستيعاب العميق لنطاق المشكلة هو المفتاح لإيجاد حلول ملائمة. وبغياب هذا الاستيعاب، يحصل الفريق على حلول غير متوافقة بدلًا من الحلول المدروسة. عندما تسبب حلول أجايل المقلَّدة مشكلات أو نتائج عكسية، من الشائع الاعتقاد بأن "الحل يجب أن يكون صحيحًا لأننا نسخناه من أشخاص ناجحين، لذا فإن المشكلة ببساطة تكمن في عدم قدرة الأشخاص على التكيف معه مما يجعله سببًا للتباطؤ أو الضرر". وللأسف فإن هذه العقلية منتشرة جدًا رغم فظاعتها. خصائص النسخة الزائفة من منهجية أجايل يحدث تزييف أجايل عندما يطبَّق إطار عمل أجايل شكلي على تطوير البرمجيات، أي يكون هذا الإطار مشابهًا شكليًا فقط لقيم ومبادئ أجايل الحقيقية. بمعنى آخر، فإن النسخة الزائفة من منهجية أجايل هي نسخة سطحية قد تبدو مشابهة لممارسات أجايل شكليًا، لكن دون أن تراعي حقيقةً تلبية هذه المبادئ. في منهجية أجايل الزائفة، يقيم مدرب إطار عمل سكرام Scrum دورات تطوير تستغرق وقتًا معينًا وتتضمن اجتماعات خلال أيام وأوقات محددة، ويكون مالك المنتج أو ما يقابله من مسميات الإدارة هو المرجع الوحيد لكل النقاشات ضمن الفريق أو بين الفريق والأطراف المعنية، وبذلك فإن كل ما تقدمه هذه الاجتماعات من مزايا تعزيز التواصل واكتشاف الحلول يكون موجَّهًا إلى مديري الفريق؛ مما يحدّ من قدرات المطورين بدلًا من تعزيز استنباطهم لنتائج أفضل. مؤشرات الخطورة التي تدل على تزييف أجايل فيما يلي مجموعة متنوعة من الحالات القصيرة عن قصص مبرمجين مستوحاة من تجارب الحياة الواقعية، والتي قد تذكِّر المطورين الخبراء بتجارب سابقة مروا بها؛ أما المستجدين من المطورين فقد يتعين عليهم دراسة هذه القصص بعناية ليتعرفوا من خلالها على مؤشرات الخطورة. المراسم تهدف مراسم أجايل إلى تخفيف العقبات وإبقاء المشاريع على المسار الصحيح، أما في منهجية أجايل الزائفة فتتحول المراسم بحدّ ذاتها إلى عقبات، حيث تسلط الحالات القصيرة التالية الضوء على مؤشرات الخطورة التي تنبه إلى تزييف منهجية أجايل في المراسم. الاجتماعات اليومية السريعة Stand-up: حالة أجايل الزائفة الأولى: يعتمد عقد الاجتماع اليومي لمناقشة الوضع على تفرُّغ مسؤول سكرام (وقد لا يُعقَد بالأساس)، ويختلف توقيت الاجتماع حسب الظروف اليومية؛ أما موعده المسجَّل فهو للاستئناس فقط، ويُتوقَّع من المطورين أن يكونوا متاحين في أي موعد يتغير إليه توقيت الاجتماع. وفي حال لم يكن أحد المطورين متفرغًا، فيجب أن يرسل تقرير تقدمه اليومي إلى مسؤول سكرام عبر رسالة خاصة. في بعض الأحيان يُطلب توثيق رقم كل مشكلة يعمل عليها المطور أو عالجها فعليًا، رغم أنه لا أحد يهتم بنظام تتبع المشكلات أثناء اجتماع التقدم اليومي. الدرس المستفاد: الاجتماع اليومي ليس مجرد تقرير يومي يقدَّم إلى الإدارة، بل إن هذه الاجتماعات أُعِدت من أجل المطورين، لضمان عدم تعطل عمل أي مطور بسبب مشكلات يمكن تلافيها، وللتحقق من أن تسليم العمل يسير على ما يرام. والنقطة الأهم أن الاجتماعات اليومية السريعة لا يُشترط أن يديرها شخص معين، وفي حال كان هناك حاجة لتغيير موعدها، فيجب أن يكون ذلك بالتوافق. حالة أجايل الزائفة الثانية: يجب عقد اجتماع يومي ثانٍ عبر اتصال هاتفي مع فريق المطورين في الهند، لأن الفريق يحتل مكانة أعلى من الفريق المحلي في التسلسل الهرمي للشركة، رغم أن الاجتماع اليومي الأول الذي لا يشارك فيه الفريق الخارجي هو الاجتماع الوحيد الذي تصدر عنه نتائج مفيدة. الدرس المستفاد: التوتر الناجم عن تنظيم الفريق من قِبل طرف خارجي يسبب خلافات. في الحالة السابقة، لم يكن هناك أي علاقة تربط الفريقين ببعضهما، وكان التواصل بينهما يجري نتيجة الضغوطات التنظيمية الخارجية فقط، وهذا ما قد يعطي انطباعًا للمهندسين بأنهم غير مؤهلين لتنظيم أنفسهم بأنفسهم، مما يقلل من سوية أدائهم. الاجتماعات الاسترجاعية Retrospectives: حالة أجايل الزائفة: يعقَد اجتماع استرجاعي بين الحين والآخر، ويكره الجميع حضوره. يتعين على كل مطور أن يقدم تعليقًا واحدًا على الأقل عن كل حالة سارت على ما يرام أو تحتاج إلى تحسينات. تُكتب هذه البنود في جدول بيانات جوجل، لكن لا يُحال أي منها إلى نظام تتبع المشكلات ليصبح قابلًا للتنفيذ، ناهيك عن وضعها قيد العمل في دورتي التطوير التاليتين. يُنسخ جدول بيانات الاجتماع الاسترجاعي من تقرير الاجتماع السابق مع وجود عنوانين ثانويين وهما "السابق" و"الجديد" في كل تقرير؛ والتي تشير إلى بنود الاجتماع السابق والحالي، إذ تنتقل المشكلات التي كانت "جديدة" في الاجتماع السابق لتصبح مشكلات "سابقة"، رغم أنها لم تخضع للمعالجة عندما كانت جديدة. والنقاش الوحيد الذي يدور حول البنود هو التفسير الشفهي الذي يتعين على كاتب البند تقديمه. الدرس المستفاد: يجب أن ينتج عن الاجتماع الاسترجاعي بنود قابلة للتنفيذ، وفي حال الاتفاق على إجراء تغيير ما، فيجب إعداد خطة لتطبيق هذا التغيير، ويجب إدراج هذه الخطة بعد ذلك ضمن المشكلات التي يجب تتبعها. لا يمتلك أحد في هذا السيناريو صلاحية تغيير طريقة الاجتماع الاسترجاعي لتصبح أكثر ملاءمة، في حين أن بيئة عمل أجايل الحقيقية تتيح إمكانية وضع أي أمر على طاولة عمل الاجتماع الاسترجاعي، ولا يستثنى من ذلك كيفية إجراء الاجتماع الاسترجاعي بحدّ ذاته. العروض التوضيحية Demos: حالة أجايل الزائفة: نادرًا ما تجرى عروض توضيحية، وهو أمر مفسَّر نظرًا لأن الكود البرمجي نادرًا ما يتجاوز مرحلة المراجعة. وعند إجراء عروض توضيحية، فإنها تُقدَّم عادةً من الجهاز المحلي للمطوِّر أو من خادم التطوير. ليس هناك تأكيد على ما إذا كان العميل بحاجة إلى الميزة التي يعمل المطور على توضيحها، وحتى العميل لا يكون متأكدًا من ذلك، ربما سيتمكن من الإجابة عن ذلك بعد ثلاثة أيام من هذه المرحلة. الدرس المستفاد: لا شك بأن الفريق غير القادر على إجراء عروض توضيحية يعاني من مشكلة أساسية تتمثل بنقص تسليم العمل، أي أن البنود لا تصل إلى مرحلة الإنتاج. يجب أن يشرح العرض التوضيحي "ميزات يمكن استخدامها في الوقت الحالي"، ولا بأس بأن يقرر العميل لاحقًا أنه لا يريد هذه الميزة، إذ يمكن إزالتها مرةً أخرى، لكن وضعها ضمن مسار الإنتاج يتضمن بالضرورة إعداد عروض توضيحية لجمع المعلومات من خلال اختبار المستخدم والملاحظات. اجتماعات تخطيط دورة التطوير Sprint Planning: حالة أجايل الزائفة: تعقَد اجتماعات تخطيط دورة التطوير في اليوم الذي يسبق بداية دورة التطوير، وتمتد إلى اليوم الذي من المفترض أن تبدأ فيه دورة التطوير. وبالنسبة لموعد الاجتماع فهو متفق عليه سابقًا، والهدف الوحيد من الاجتماع هو أن يحدد المطورون حجم العمل اللازم لحل المشكلات بمقياس نقاط القصة story points. الأمر المثير للاهتمام هو أن المشكلات المحددة لا تضاف إلى التزامات العمل، بل تُترَك لتجد طريقها لاحقًا إلى طاولة عمل دورة التطوير دون بذل أي جهد لتحقيق ذلك. من ناحية أخرى، عندما يُطلب من الجميع تحديد رقم لتقدير نقاط القصة من وجهة نظرهم (لتقدير حجم المهام)، فإن الشخص الذي وضع الرقم الأعلى لنقاط القصة هو الوحيد الذي يتعين عليه تبرير هذا الرقم، وتكمُن المشكلة هنا عندما يكون قد وضع رقمًا مرتفعًا ليس لشيء إلا لقلة خبرته بالموضوع؛ عندها سيُرغَم المطور قليل الخبرة على تقليل حجم العمل المقدر لحل المشكلات وسيُكلَّف بإنجاز هذا العمل عقوبة ً له. وكل ما سيحصل عليه هذا المطور هو عنوان المشكلة منسوخًا من ملف الإكسل الذي كتبه مدير المشروع، ولن يحصل على أي توصيف أو توضيح آخر. الدرس المستفاد: يجب أن ينعكس التخطيط لدورة التطوير مباشرةً على دورة التطوير، وربما من الأفضل تنفيذه في مرحلة متأخرة من دورة التطوير عندما تكون المشكلات قد تجاوزت مرحلة البرمجة ونجحت باختبار ضمان الجودة. بالنسبة للقصة أعلاه. يجب أن يتضمن الاجتماع الاسترجاعي التالي مناقشة المشكلات التالية: الحاجة لتغيير جدول عمل تخطيط دورة التطوير، وذلك ربما من خلال تخصيص مزيد من الوقت في اليوم الأخير من دورة التطوير أو توزيع الوقت المطلوب على مدار دورة التطوير. العيوب التي تعالَج بطريقة غير صحيحة باعتبار أنها غير مؤثرة على نطاق العمل. تقدير الوقت أو الجهد بطريقة غير دقيقة لتشجيع الالتزام بعبء أكبر من العمل. إدراج قضايا غير مكتملة على أنها جاهزة للتنفيذ. كل من النقاط السابقة هي مشكلة تحتاج إلى مناقشتها، لكن إذا لم يبذل الفريق جهده لإصلاح هذه المشكلات، فلن يقتصر التأثير عليها، بل إن آثارها ستمتد لتترتب عليها مشاكل أخرى: ستبدأ دورات التطوير بوقت متأخر أكثر فأكثر، أو تصبح غير محددة المعالم، أو كليهما. ستكون هناك حاجة دائمة لاستمرار دورات التطوير لأوقات إضافية، أو ستتراكم العيوب غير المعالجة، أو كليهما. ستتناقص السرعة التي تقاس بنقاط القصة. لن تلبى التزامات دورة التطوير. سيتطلب الأمر معالجة المشكلات مرة ثانية، ولن يلبي العمل الغايات المطلوبة من القصة، أو كليهما. الموظفون هناك حالتين زائفتين شائعتين هنا. حالة أجايل الزائفة الأولى هي أن يكون هناك مالك المنتج، ومالك المنتج التقني، ومدير المنتج، ومدير المشروع، ومسؤول سكرام، ومدرب أجايل، والمدير التقني، ومدير الهندسة، والمهندس المعماري؛ فضلًا عن المطورين العاديين. يستغرق اجتماع الوضع اليومي 40 دقيقة، ويجب أن يقف الجميع على شكل دائرة وأن يتحدثوا من خلال هاتف مكبر صوت موصول بخدمة Webex، ليتمكن المدير المسؤول عن المشروع عن بُعد من سماع الحالة اليومية، كما يتمكن بذلك أي شخص عالق في الزحام متأخر عن العمل من حضور الاجتماع. الدرس المستفاد: العدد المثالي للفريق هو 5 إلى 7 أعضاء، ويجب ألا يكون غالبيتهم من المديرين أو أصحاب السلطة، مع التأكيد مرةً أخرى على أن الاجتماعات اليومية لا تهدف إلى تقديم تقرير عن الوضع للمديرين، ولا تتطلب عادةً أن يتكلم فيها غير المطورين. وللتأكيد، إذا تجاوز الاجتماع اليومي 15 دقيقة، فإنه يفقد قيمته للجميع، لأن الغاية منه هي تركيز الأفكار لا تشتيتها. وإذا كان الاجتماع يُعقَد في وقت لا يزال فيه الأشخاص في طريقهم إلى المكتب، فلا بد من مراجعة توقيته. حالة أجايل الزائفة الثانية: يكون المطورون موزعين بخبرتهم بالتساوي بين موظفين بدوام كامل وموظفين بعقود، وفجأةً دون سابق إنذار تُنهى عقود جميع أصحاب العقود، ورغم ذلك يُتوقع أن تبقى سرعة الفريق على حالها. الدرس المستفاد: لا يقتصر الأمر على مشاريع أجايل، لكن يجب تجنب تغيير الموظفين في مشاريع البرمجيات عمومًا، فالثقة المطلوبة داخل الفريق من أجل تنفيذ مشروع أجايل فعال تتراكم مع الزمن، وفي حال تطلَّبَ الأمر إعادة بنائها مع موظفين جدد فلا بد أن يؤدي ذلك إلى نتائج عكسية. وفقًا لقانون بروكس Brooks's Law، فإن التأخير الناتج عن تغيير الموظفين يصبح مضاعفًا عندما يكون مشروع البرمجيات تحت ضغط زمني. المواعيد النهائية هناك حالتين زائفتين شائعتين فيما يخص المواعيد النهائية: حالة أجايل الزائفة الأولى هنا هي عندما يتم الضغط على زر الانطلاق الفعلي في دورة التطوير الحالية ضمن نظام تتبع المشكلات عند حلول اليوم الثالث من برنامج دورة التطوير، حين يُكمل مصدر هندسي واحد على الأقل مرحلة التطوير لكي يبدأ بمهمة جديدة بعد أن يتأكد من أنه لم يتبقَّ أي شيء من دورة التطوير السابقة ضمن قائمة الأعمال التي يجب القيام بها أو الجاهزة للتطوير، في الوقت الذي يكون فيه المطورون الآخرون لا يزالون يعملون على مهام دورة التطوير السابقة. وقد يضطر المطور الذي يبدأ بالعمل على مهام دورة التطوير الجديدة إلى التراجع في أي وقت إذا لم يجتَز الكود الذي تعهدَ بتسليمه مرحلةَ المراجعة بنجاح. الدرس المستفاد: يجب أن يُنهي جميع المطورين مهام التطوير في نهاية دورة التطوير، وكل أعمال تسلَّم متأخرة هي مؤشر على وجود مهام تطوير إضافية، والتي لا يمكن تخصيص وقت لها إلا من خلال تقليص نطاق دورة التطوير القادمة (تقليصًا مضاعفًا بالنسبة لدورة التطوير القادمة من أجل معالجة المشكلات الإضافية لدورة التطوير الحالية، وتقليصًا مفردًا بالنسبة للدورة اللاحقة حفاظًا على التوازن). إذا تكرر حدوث ذلك فهو مؤشر على وجود مشكلة بالالتزام بدورة التطوير أو توتر بين المطورين، وعندها يصبح تحديد نطاق دورة التطوير هدفًا أساسيًا يجب مناقشته في الاجتماع الاسترجاعي القادم. حالة أجايل الزائفة الثانية: دُمِجت الأعمال التي يجب تسليمها في دورة التطوير السابقة مع الأعمال التي يجب تسليمها في دورة التطوير الحالية، لأن فريق ضمان الجودة لم يبدأ بها بعد. ولم يُنشَر أي تحديث للمنتج منذ ثلاثة شهور. الدرس المستفاد: قد يكون تأخر فريق ضمان الجودة مؤشرًا على ثقل برنامج عمل دورات التطوير أو انخفاض جودة البرمجيات أو تراكم أعمال خط ضمان الجودة، أو توليفة من هذه الأسباب. يشير وجود عقبات أمام الإنتاج إلى وجود مشكلة في آلية التسليم المستمر إلى الإنتاج، والذي قد ينجم عن عدم اجتياز اختبار قبول المستخدم أو نقص الكوادر التي تعمل عليه، أو ربما يحدث ذلك رغم اجتياز اختبار قبول المستخدم بسبب اعتقاد مالك المنتج أن النشر ليس جاهزًا! يُعَد السعي نحو الكمال مشكلةً واقعيةً وشائعةً ضمن فرق أجايل، والعلاج الوحيد لها هو الرضا والقبول بتسليم عمل دون مستوى الكمالية إلى المستخدمين ومن ثم جمع ملاحظاتهم وإجراء تحسينات عليه. التواصل هناك أيضًا حالتي أجايل زائفتين بخصوص التواصل: حالة أجايل الزائفة الأولى: تعمل مجموعة صغيرة من مالكي المنتج ومديري سكرام على تحويل جميع عمليات التواصل من الأطراف المعنية إلى المطورين، وبذلك تصبح الأطراف المعنية مجهولة تقريبًا بالنسبة للفريق، مع عدم وجود طريقة للتواصل معهم، مما يؤدي إلى تعذر إجراء اختبارات المستخدمين (الذين يُعَدّون من ضمن الأطراف المعنية). الدرس المستفاد: يتعارض أسلوب التواصل هذا مع المبدأ الرابع من مبادئ أجايل الذي ينص على أن "أصحاب المشروع والمطورين يجب أن يعملوا على المشروع جنبًا إلى جنب يوميًا". عندما يكون مسار جميع عمليات التواصل موجهًا نحو نقطة ضيقة، فقد يتعذر التعاون مع العملاء (القيمة الثالثة من قيم أجايل). وبغياب التعاون يفوِّت الفريق فرص الاستجابة للتغيرات في احتياجات الأطراف المعنية أو تفاضيلاتهم. حالة أجايل الزائفة الثانية: فرق المحتوى المتعددة ضمن المؤسسة هي المسؤولة عن تعبئة المنصة التي يعمل المهندسون على إعدادها، وعندما لا يُملَأ المحتوى تنعدم فائدة التطبيق، ويقع اللوم على المهندسين؛ وعندما يترأس الفريق نائب جديد ويجمع الفريق ليخبرهم بتكليفه، يهمل تقصير النائب السابق ويطرد مدير الهندسة الذي يحظى بسمعة طيبة، ويبقى المحتوى مفقودًا. الدرس المستفاد: الحاجة إلى التعاون لا تقتصر على العملاء، وفي هذا المثال كان من الضروري أن يجري التواصل بين المطورين وفرق المحتوى من أجل الحد من ترددهم في نشر محتواهم ضمن النظام الجديد. بسبب عدم حدوث هذا التواصل، حدث تأجيل في توفير محتوى بالتنسيق الذي يتطلبه النظام الجديد على نطاق واسع. وقد أدت القيود الصارمة التي فُرضت على التواصل مع فرق المحتوى إلى تعذر تواصل المهندسين معهم، مما انعكس سلبًا على المشروع برمّته. العمليات التقنية حالة أجايل الزائفة هنا هي عندما يجري تغيير قاعدة البيانات المحلية للمطورين إلى آلية مختلفة عن بيئة التحضير والإنتاج. ويكون هناك مشروعان واحد منهما فقط لديه محرك لترحيل قواعد بيانات، أما المشروع الآخر فيتعين عليه توجيه جميع طلبات التغيير عبر المستشار التقني لإجراء تحديثات يدوية، لكن المستشار التقني لا يتمتع بأي خبرة بإدارة قواعد البيانات. الدرس المستفاد: التكامل المستمر والنشر المستمر CI/CD ونموذج DevOps هما عنصران أساسيان من مسار عمل أجايل، لكن يمكن أن تعرقلهما عمليات بشرية تسبب التباطؤ. بالنسبة لحالة قواعد البيانات، من الأفضل وضع شروط لترحيل البيانات قبل البدء بأي مشروع، ومع ذلك فيمكن تطبيق شروط ترحيل البيانات على أي مشروع يأتي فيما بعد، يجب أيضًا الاهتمام بشكل خاص باختيار سياسات السحابة، نظرًا لأن المطورين يحتاجون إلى تراخيص الاستخدام الفردي أو تكنولوجيا مكافئة من أجل التطوير المحلي. الخلاصة تتمثل أولويات منهجية أجايل الحقيقية بتقديم برمجيات فعالة قائمة على التواصل المستمر والقدرة على التكيف، مع الالتزام بقيم ومبادئ اتفاقية أجايل. مع ذلك فإن الكثير من الفرق تقع في فخ تزييف منهجية أجايل، وذلك من خلال تطبيق نسخ ظاهرية من ممارسات أجايل دون الالتفات إلى مبادئه الأساسية. للاستفادة من مزايا أجايل كما يجب، لا بد وأن يبدي الفريق استيعابًا عميقًا لنطاق المشكلة، وأن يوفر المناخ الملائم للمطورين لتنظيم عملهم؛ مع الحرص على التواصل الفعال، وإعطاء الأولوية لتسليم العمل والحصول على ملاحظات المستخدمين، وضمان أن تدعم العمليات التقنية استمرارية التكامل والنشر. لا بد من الالتزام بهذه المبادئ لكي تتمكن الفرق من تحقيق النجاح عبر منهجية أجايل. ترجمة -وبتصرّف- للمقال You're Doing Agile Wrong لصاحبه Bradley Momberger. اقرأ أيضًا دليل المبتدئين لمنهجية أجايل Agile دليلك إلى أشهر أطر عمل منهجية أجايل المراسم الأربعة لمنهجية أجايل Agile ceremonies ما هي إدارة المنتجات؟ ما هي إدارة المشاريع؟ تعرف على إطار عمل سكرام scrum أشهر أطر منهجية أجايل
  23. أولاً ستحتاج إلى شراء رخصة للمحتوى غير ذلك يعتبر أمر غير قانوني. وستحتاج إلى مناقشة التكلفة مع مبرمج لديه معرض أعمال جيد وتجنب من لديه معرض أعمال ضعيف، عامًة لو احتسبنا الأمر على سعر ساعة 10 دولار، والتطبيق يحتاج تطويره كتقدير مبدئي لمدة 3-6 أشهر، أي 600 ساعة في 10 يصبح السعر 6000 دولار. لكن عامًة تستطيع الحصول على سعر جيد في حال قمت بعرض مشروعك على موقع العمل الحر مثل مستقل، وستستقبل العروض ويمكنك الإختيار من بينها بناءًا على السعر وجودة معرض الأعمال، مثل تكلفة 1500 إلى 3000 دولار.
  1. عرض المزيد
×
×
  • أضف...