<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: playgames</title>
    <description>The latest articles on DEV Community by playgames (@playgames).</description>
    <link>https://dev.to/playgames</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4064959%2F9bb5a13e-f179-49cb-b6b6-5a8c4b4d7609.png</url>
      <title>DEV Community: playgames</title>
      <link>https://dev.to/playgames</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/playgames"/>
    <language>en</language>
    <item>
      <title>لماذا لا أحمّل لعبة الـ iframe فور فتح الصفحة؟</title>
      <dc:creator>playgames</dc:creator>
      <pubDate>Thu, 06 Aug 2026 02:00:16 +0000</pubDate>
      <link>https://dev.to/playgames/lmdh-l-hmwl-lb-l-iframe-fwr-fth-lsfh-2m8h</link>
      <guid>https://dev.to/playgames/lmdh-l-hmwl-lb-l-iframe-fwr-fth-lsfh-2m8h</guid>
      <description>&lt;p&gt;عند تطوير موقع ألعاب متصفح، يبدو الحل الأسرع واضحًا: نضع رابط اللعبة داخل عنصر &lt;code&gt;iframe&lt;/code&gt;، ثم نعرض الصفحة للمستخدم.&lt;/p&gt;

&lt;p&gt;تقنيًا، اللعبة موجودة وتبدأ في التحميل مباشرة. لكن هذا لا يعني أن التجربة جيدة.&lt;/p&gt;

&lt;p&gt;قد يفتح الزائر صفحة لعبة تلبيس أو طبخ، فيبدأ المتصفح فورًا بتحميل ملفات اللعبة، الإعلانات، الخطوط، مكتبات JavaScript وطلبات الشبكة القادمة من نطاق خارجي. يحدث هذا حتى لو لم يكن المستخدم قد قرر بعد أن يبدأ اللعب.&lt;/p&gt;

&lt;p&gt;على الهاتف واتصال الإنترنت المتوسط، تكون النتيجة واضحة:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;الصفحة تتأخر في الظهور؛&lt;/li&gt;
&lt;li&gt;الصورة والعنوان يتحركان أثناء التحميل؛&lt;/li&gt;
&lt;li&gt;الهاتف يستهلك بيانات أكثر؛&lt;/li&gt;
&lt;li&gt;التمرير يصبح أثقل؛&lt;/li&gt;
&lt;li&gt;اللعبة تبدأ في طلب الموارد قبل أن يضغط المستخدم على أي شيء؛&lt;/li&gt;
&lt;li&gt;العودة إلى الصفحة السابقة تصبح أبطأ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;لهذا توقفت عن تحميل اللعبة فور فتح الصفحة. أصبحت أعرض غلافًا خفيفًا وزرًا واضحًا، ثم أنشئ &lt;code&gt;iframe&lt;/code&gt; فقط عندما يضغط المستخدم على “ابدئي اللعب”.&lt;/p&gt;

&lt;p&gt;هذه ليست حركة تجميلية. إنها تغير طريقة تحميل الصفحة بالكامل.&lt;/p&gt;

&lt;h2&gt;
  
  
  لماذا يمثل الـ iframe عبئًا حقيقيًا؟
&lt;/h2&gt;

&lt;p&gt;عنصر &lt;code&gt;iframe&lt;/code&gt; ليس مجرد مستطيل يحتوي على صفحة أخرى.&lt;/p&gt;

&lt;p&gt;عندما يحمّله المتصفح، فإنه يفتح مستندًا مستقلًا تقريبًا داخل الصفحة الحالية. وقد يتضمن هذا المستند:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ملفات JavaScript؛&lt;/li&gt;
&lt;li&gt;ملفات CSS؛&lt;/li&gt;
&lt;li&gt;صورًا وأصواتًا؛&lt;/li&gt;
&lt;li&gt;خطوطًا؛&lt;/li&gt;
&lt;li&gt;إعلانات؛&lt;/li&gt;
&lt;li&gt;أدوات تحليل؛&lt;/li&gt;
&lt;li&gt;اتصالات بخوادم إضافية؛&lt;/li&gt;
&lt;li&gt;تخزينًا محليًا أو ملفات تعريف ارتباط؛&lt;/li&gt;
&lt;li&gt;ملفات اللعبة نفسها.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;حتى إذا كان كود صفحتي صغيرًا، يمكن للعبة المضمّنة أن ترسل عشرات الطلبات الخارجية.&lt;/p&gt;

&lt;p&gt;المشكلة أكبر عندما لا أتحكم في مصدر اللعبة. لا أستطيع ضغط ملفاته، حذف مكتبة زائدة أو تغيير طريقة تحميل إعلاناته. لذلك أفضل قرار أملكه هو تحديد متى أسمح ببدء التحميل.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;loading="lazy"&lt;/code&gt; مفيد، لكنه ليس الحل الكامل
&lt;/h2&gt;

&lt;p&gt;يمكن إضافة الخاصية التالية:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://example-game-provider.com/game"&lt;/span&gt;
  &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt;
  &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"لعبة تلبيس"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;تطلب &lt;code&gt;loading="lazy"&lt;/code&gt; من المتصفح تأجيل تحميل الـ iframe عندما يكون بعيدًا عن الجزء الظاهر من الصفحة. هذا مفيد للعناصر الموجودة أسفل الصفحة، ويقلل تحميل موارد لا يراها المستخدم بعد.&lt;/p&gt;

&lt;p&gt;لكن في صفحة لعبة، يكون الـ iframe غالبًا قريبًا من أعلى الصفحة. عندها قد يقرر المتصفح تحميله مبكرًا، لأن المستخدم سيصل إليه بسرعة.&lt;/p&gt;

&lt;p&gt;كما أن توقيت التحميل المتكاسل ليس عقدًا صارمًا. المتصفح يأخذ في الاعتبار المسافة من الشاشة والاتصال وعوامل أخرى.&lt;/p&gt;

&lt;p&gt;لذلك، إذا كنت لا أريد تحميل اللعبة قبل تفاعل المستخدم فعلًا، فلا أضع رابط اللعبة داخل &lt;code&gt;src&lt;/code&gt; منذ البداية.&lt;/p&gt;

&lt;h2&gt;
  
  
  الحل الذي استخدمته: واجهة غلاف بدل اللعبة
&lt;/h2&gt;

&lt;p&gt;عند فتح الصفحة، أعرض:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;صورة حقيقية من اللعبة؛&lt;/li&gt;
&lt;li&gt;اسم اللعبة؛&lt;/li&gt;
&lt;li&gt;وصفًا قصيرًا؛&lt;/li&gt;
&lt;li&gt;زر “ابدئي اللعب”؛&lt;/li&gt;
&lt;li&gt;معلومات أن اللعبة تعمل في المتصفح.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;لا يوجد &lt;code&gt;iframe&lt;/code&gt; نشط في هذه المرحلة.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"game-shell"&lt;/span&gt; &lt;span class="na"&gt;data-game-url=&lt;/span&gt;&lt;span class="s"&gt;"https://provider.example/game"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/images/dress-up-game.webp"&lt;/span&gt;
    &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"لعبة تلبيس واختيار فساتين وتسريحات شعر"&lt;/span&gt;
    &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"960"&lt;/span&gt;
    &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"540"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"play-button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ابدئي اللعب
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;عندما يضغط المستخدم على الزر، ينشئ JavaScript عنصر &lt;code&gt;iframe&lt;/code&gt; ويستبدل الغلاف به:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gameShell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.game-shell&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;playButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gameShell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.play-button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;playButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gameUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gameShell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gameUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;gameUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;iframe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;iframe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gameUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;لعبة متصفح&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fullscreen; autoplay&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allowFullscreen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;referrerPolicy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strict-origin-when-cross-origin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;gameShell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceChildren&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;بهذه الطريقة لا يبدأ تحميل اللعبة إلا بعد قرار واضح من المستخدم.&lt;/p&gt;

&lt;h2&gt;
  
  
  لماذا أفضل هذا على زر يغيّر قيمة &lt;code&gt;src&lt;/code&gt; فقط؟
&lt;/h2&gt;

&lt;p&gt;يمكن وضع &lt;code&gt;iframe&lt;/code&gt; فارغ ثم إضافة &lt;code&gt;src&lt;/code&gt; عند النقر:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; &lt;span class="na"&gt;data-src=&lt;/span&gt;&lt;span class="s"&gt;"https://provider.example/game"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ثم:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;هذا يعمل، لكنه يترك إطارًا فارغًا يحتاج إلى ضبط أبعاده وحالة التحميل.&lt;/p&gt;

&lt;p&gt;أنا أفضل إنشاء العنصر عند الحاجة، لأن الصفحة قبل النقر لا تحتوي أصلًا على مستند مضمّن. يصبح من الأسهل عرض صورة الغلاف والزر ورسالة الخطأ داخل حاوية واحدة.&lt;/p&gt;

&lt;p&gt;كما يقل خطر أن يبدأ iframe في التحميل بسبب خطأ في القالب أو إضافة تلقائية للخاصية &lt;code&gt;src&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  لا تستخدم صورة غلاف عامة
&lt;/h2&gt;

&lt;p&gt;إذا كانت واجهة الغلاف تعرض صورة جميلة لا تمثل اللعبة الفعلية، فقد يضغط المستخدم ثم يكتشف لعبة مختلفة.&lt;/p&gt;

&lt;p&gt;الأفضل استخدام لقطة توضّح النشاط الأساسي:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;شخصية وملابس في لعبة التلبيس؛&lt;/li&gt;
&lt;li&gt;مطبخ ومكونات في لعبة الطبخ؛&lt;/li&gt;
&lt;li&gt;وجه وأدوات تجميل في لعبة المكياج؛&lt;/li&gt;
&lt;li&gt;أثاث وغرفة في لعبة الديكور.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;الغلاف ليس إعلانًا. هو معاينة تساعد المستخدم على تحديد ما إذا كانت اللعبة تناسبه.&lt;/p&gt;

&lt;p&gt;لهذا أكتب أيضًا نصًا بديلًا واضحًا للصورة، بدل كلمات عامة مثل “أفضل لعبة رائعة”.&lt;/p&gt;

&lt;h2&gt;
  
  
  احجز مساحة اللعبة قبل بدء التحميل
&lt;/h2&gt;

&lt;p&gt;عند استبدال الغلاف بالـ iframe، يجب ألا يتغير ارتفاع الصفحة فجأة.&lt;/p&gt;

&lt;p&gt;استخدمت نسبة أبعاد ثابتة للحاوية:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.game-shell&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;aspect-ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f1f1f1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.game-shell&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.game-shell&lt;/span&gt; &lt;span class="nt"&gt;iframe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.game-shell&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;object-fit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;وجود &lt;code&gt;aspect-ratio&lt;/code&gt; يعني أن المتصفح يعرف مساحة اللعبة قبل وصول الصورة أو إنشاء الـ iframe.&lt;/p&gt;

&lt;p&gt;هذا يمنع المحتوى الموجود أسفل اللعبة من القفز عند بدء التشغيل.&lt;/p&gt;

&lt;h2&gt;
  
  
  لا تؤجل صورة الغلاف الرئيسية
&lt;/h2&gt;

&lt;p&gt;قد يبدو من المنطقي وضع &lt;code&gt;loading="lazy"&lt;/code&gt; على كل الصور، لكن صورة الغلاف الموجودة في أعلى صفحة اللعبة غالبًا هي أكبر عنصر مرئي للمستخدم.&lt;/p&gt;

&lt;p&gt;تأجيلها قد يجعل الصفحة تعرض مساحة فارغة قبل ظهور المحتوى الأساسي. إرشادات أداء الويب تنبّه إلى أن التحميل المتكاسل للصور الموجودة في الجزء الأول من الصفحة قد يبطئ ظهور أكبر عنصر مرئي، بينما يُفضّل استخدامه للصور الموجودة خارج الشاشة.&lt;/p&gt;

&lt;p&gt;لذلك أتعامل مع الصور بهذه الطريقة:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;صورة اللعبة الرئيسية: تحميل عادي؛&lt;/li&gt;
&lt;li&gt;أول صف من الألعاب المشابهة: تحميل عادي أو حسب موقعه الفعلي؛&lt;/li&gt;
&lt;li&gt;البطاقات الموجودة أسفل الصفحة: &lt;code&gt;loading="lazy"&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/images/main-game.webp"&lt;/span&gt;
  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"لعبة طبخ وتزيين كعكة"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"960"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"540"&lt;/span&gt;
  &lt;span class="na"&gt;fetchpriority=&lt;/span&gt;&lt;span class="s"&gt;"high"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ولا أضع &lt;code&gt;fetchpriority="high"&lt;/code&gt; على عشر صور. الأولوية المرتفعة يجب أن تبقى للعنصر الأساسي فقط.&lt;/p&gt;

&lt;h2&gt;
  
  
  ماذا عن الصفحة التي تعرض عشرات الألعاب؟
&lt;/h2&gt;

&lt;p&gt;في صفحة التصنيف، المشكلة ليست iframe بل الصور.&lt;/p&gt;

&lt;p&gt;صفحة تحتوي على خمسين بطاقة قد تبدأ بتحميل خمسين صورة، حتى لو كان المستخدم سيرى أول ست أو ثماني بطاقات فقط.&lt;/p&gt;

&lt;p&gt;هناك أستخدم:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/images/game-card.webp"&lt;/span&gt;
  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"لعبة مكياج وتسريح شعر"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"320"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"180"&lt;/span&gt;
  &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt;
  &lt;span class="na"&gt;decoding=&lt;/span&gt;&lt;span class="s"&gt;"async"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;لكنني لا أضيف &lt;code&gt;loading="lazy"&lt;/code&gt; تلقائيًا إلى جميع البطاقات. الصور الظاهرة فور فتح الصفحة يجب أن تصل بسرعة.&lt;/p&gt;

&lt;p&gt;أفضل تقسيم عملي هو:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;الصور داخل أول شاشة: تحميل عادي؛&lt;/li&gt;
&lt;li&gt;الصور القريبة منها: يمكن أن يقرر المتصفح تحميلها؛&lt;/li&gt;
&lt;li&gt;بقية القائمة: تحميل متكاسل.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;المبالغة في التحميل المتكاسل قد تؤخر الصور التي ينتظرها المستخدم فعلًا.&lt;/p&gt;

&lt;h2&gt;
  
  
  استخدم صورًا متعددة المقاسات
&lt;/h2&gt;

&lt;p&gt;إرسال صورة بعرض 1200 بكسل إلى بطاقة لا يتجاوز عرضها 240 بكسل يهدر البيانات.&lt;/p&gt;

&lt;p&gt;استخدمت &lt;code&gt;srcset&lt;/code&gt; حتى يختار المتصفح الحجم المناسب:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/images/game-480.webp"&lt;/span&gt;
  &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"
    /images/game-320.webp 320w,
    /images/game-480.webp 480w,
    /images/game-640.webp 640w
  "&lt;/span&gt;
  &lt;span class="na"&gt;sizes=&lt;/span&gt;&lt;span class="s"&gt;"
    (max-width: 600px) 50vw,
    (max-width: 1100px) 33vw,
    240px
  "&lt;/span&gt;
  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"لعبة اختيار أزياء أميرة"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"320"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"180"&lt;/span&gt;
  &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;هذه الخطوة أهم من تبديل امتداد الصورة فقط. صورة WebP كبيرة جدًا قد تبقى أثقل من JPEG بالحجم الصحيح.&lt;/p&gt;

&lt;h2&gt;
  
  
  لا تجعل الصفحة الرئيسية تحمل الألعاب نفسها
&lt;/h2&gt;

&lt;p&gt;من الأخطاء التي فكرت فيها مبكرًا تضمين اللعبة داخل بطاقة الصفحة الرئيسية، حتى يستطيع المستخدم اللعب دون فتح صفحة مستقلة.&lt;/p&gt;

&lt;p&gt;الفكرة تبدو سريعة، لكنها سيئة عمليًا.&lt;/p&gt;

&lt;p&gt;إذا عرضت عشر بطاقات وكل بطاقة تحتوي على iframe، فقد تحمّل الصفحة عشر ألعاب في الوقت نفسه. وقد تبدأ كل لعبة في تحميل مكتباتها وإعلاناتها وملفاتها.&lt;/p&gt;

&lt;p&gt;حتى لو استخدمت &lt;code&gt;loading="lazy"&lt;/code&gt;، تصبح بنية الصفحة معقدة ويصعب التحكم في الموارد.&lt;/p&gt;

&lt;p&gt;الأفضل أن تحتوي صفحات القوائم على الصور والعناوين فقط، ثم تفتح كل لعبة في صفحة مستقلة. داخل صفحة اللعبة نفسها يمكن استخدام التحميل بعد النقر.&lt;/p&gt;

&lt;h2&gt;
  
  
  زر التشغيل يجب أن يكون مختلفًا عن الإعلان
&lt;/h2&gt;

&lt;p&gt;في مواقع الألعاب، يشعر المستخدم بالشك عندما يرى عدة أزرار كبيرة تحمل كلمات مثل:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;تحميل؛&lt;/li&gt;
&lt;li&gt;ابدأ الآن؛&lt;/li&gt;
&lt;li&gt;تشغيل؛&lt;/li&gt;
&lt;li&gt;تثبيت؛&lt;/li&gt;
&lt;li&gt;متابعة.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;إذا كان زر اللعبة يشبه إعلان التنزيل، فقد يتردد المستخدم أو يضغط على العنصر الخطأ.&lt;/p&gt;

&lt;p&gt;استخدمت زرًا واحدًا داخل الغلاف، في مكان ثابت، مع نص واضح:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ابدئي اللعب&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;لا أستخدم كلمة “تحميل” لأن اللعبة لا تحتاج إلى ملف.&lt;/p&gt;

&lt;p&gt;ولا أستخدم “التالي” لأنها لا توضّح ما سيحدث.&lt;/p&gt;

&lt;h2&gt;
  
  
  أضف حالة تحميل بعد النقر
&lt;/h2&gt;

&lt;p&gt;عندما يضغط المستخدم، قد تحتاج اللعبة عدة ثوانٍ حتى تظهر. إذا استبدلت الصورة بإطار فارغ، فقد يعتقد أن الزر لم يعمل.&lt;/p&gt;

&lt;p&gt;لذلك أعرض مؤشرًا داخل الحاوية حتى يطلق iframe حدث &lt;code&gt;load&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;playButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gameUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gameShell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gameUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;gameShell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div class="game-loading" role="status"&amp;gt;
      جارٍ تحميل اللعبة…
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;iframe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;iframe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gameUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;لعبة متصفح&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allowFullscreen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gameShell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.game-loading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;gameShell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;لكن لا أعد المستخدم بأن اللعبة ستفتح خلال رقم محدد من الثواني، لأن سرعة الخادم الخارجي ليست تحت سيطرتي.&lt;/p&gt;

&lt;h2&gt;
  
  
  ضع مهلة وخيار إعادة المحاولة
&lt;/h2&gt;

&lt;p&gt;بعض الألعاب لا تُحمّل بسبب انقطاع الشبكة، حظر النطاق، مشكلة في المصدر أو توقف اللعبة نفسها.&lt;/p&gt;

&lt;p&gt;يمكن إضافة مهلة بسيطة:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timeoutId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;gameShell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div class="game-error"&amp;gt;
      &amp;lt;p&amp;gt;تعذر تحميل اللعبة.&amp;lt;/p&amp;gt;
      &amp;lt;button type="button" data-retry&amp;gt;حاولي مرة أخرى&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;15000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeoutId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;iframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;حدث &lt;code&gt;load&lt;/code&gt; لا يضمن أن اللعبة تعمل بالكامل، خصوصًا مع المحتوى الخارجي، لكنه أفضل من ترك المستخدم أمام مساحة فارغة إلى ما لا نهاية.&lt;/p&gt;

&lt;h2&gt;
  
  
  لا تثق بأي رابط لعبة يدخل قاعدة البيانات
&lt;/h2&gt;

&lt;p&gt;إذا كان الموقع يستورد ألعابًا من مصادر خارجية، فلا يجب وضع أي رابط مستلم مباشرة داخل &lt;code&gt;iframe&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;أتحقق من النطاق المسموح:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;urllib.parse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urlparse&lt;/span&gt;

&lt;span class="n"&gt;ALLOWED_GAME_HOSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;games.example-provider.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cdn.example-provider.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_allowed_game_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;urlparse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ALLOWED_GAME_HOSTS&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;هذه القائمة تمنع المحرر أو البيانات المستوردة من تضمين نطاق غير معروف داخل صفحات الموقع.&lt;/p&gt;

&lt;p&gt;لا أستخدم مقارنة تنتهي باسم النطاق فقط، لأن نطاقًا مثل:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;games.example-provider.com.attacker.example&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ليس تابعًا للمصدر المسموح.&lt;/p&gt;

&lt;h2&gt;
  
  
  فكر في صلاحيات iframe
&lt;/h2&gt;

&lt;p&gt;لا أعطي اللعبة صلاحيات أكثر مما تحتاج.&lt;/p&gt;

&lt;p&gt;إذا كانت اللعبة تحتاج إلى ملء الشاشة، أضيف ذلك صراحة:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;allow="fullscreen; autoplay"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;إذا لم تكن بحاجة إلى الكاميرا أو الميكروفون أو الموقع الجغرافي، فلا أضيف هذه الصلاحيات.&lt;/p&gt;

&lt;p&gt;يمكن أيضًا دراسة استخدام &lt;code&gt;sandbox&lt;/code&gt;، لكن تطبيقه بصورة عشوائية قد يمنع اللعبة من العمل. بعض الألعاب تحتاج إلى السكربتات أو التخزين أو فتح وضع ملء الشاشة.&lt;/p&gt;

&lt;p&gt;الأفضل اختبار كل مصدر وتحديد الحد الأدنى من الصلاحيات بدل نسخ قائمة واسعة من الإنترنت.&lt;/p&gt;

&lt;h2&gt;
  
  
  ما علاقة ذلك بالبحث عن ألعاب البنات؟
&lt;/h2&gt;

&lt;p&gt;من يبحث عن &lt;a href="https://gamesforgirlsonline.com/" rel="noopener noreferrer"&gt;العاب بنات&lt;/a&gt; لا يهتم باسم تقنية التحميل التي استخدمتها.&lt;/p&gt;

&lt;p&gt;لكنه يهتم بنتيجتها مباشرة:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;أن تظهر الصفحة بسرعة؛&lt;/li&gt;
&lt;li&gt;أن يرى اللعبة التي اختارها؛&lt;/li&gt;
&lt;li&gt;ألا يبدأ تحميل أشياء كثيرة قبل أن يطلبها؛&lt;/li&gt;
&lt;li&gt;أن يعمل زر اللعب بوضوح؛&lt;/li&gt;
&lt;li&gt;ألا يضطر إلى تثبيت تطبيق؛&lt;/li&gt;
&lt;li&gt;أن يستطيع تجربة لعبة أخرى إذا لم تعجبه الأولى.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;الأداء هنا ليس رقمًا في تقرير Lighthouse فقط. الأداء هو تقليل الوقت بين اختيار اللعبة والبدء الفعلي.&lt;/p&gt;

&lt;h2&gt;
  
  
  لا تجعل نتيجة Lighthouse هي الهدف الوحيد
&lt;/h2&gt;

&lt;p&gt;يمكن أن تحصل صفحة غلاف بلا لعبة على نتيجة أداء ممتازة، ثم يضغط المستخدم ويجد أن اللعبة نفسها بطيئة جدًا.&lt;/p&gt;

&lt;p&gt;لذلك أختبر مرحلتين منفصلتين:&lt;/p&gt;

&lt;h3&gt;
  
  
  قبل الضغط على التشغيل
&lt;/h3&gt;

&lt;p&gt;أقيس:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;سرعة ظهور العنوان والصورة؛&lt;/li&gt;
&lt;li&gt;استقرار التخطيط؛&lt;/li&gt;
&lt;li&gt;حجم الصفحة الأولي؛&lt;/li&gt;
&lt;li&gt;سرعة التفاعل مع زر اللعب.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  بعد الضغط على التشغيل
&lt;/h3&gt;

&lt;p&gt;أراقب:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;الوقت حتى ظهور محتوى اللعبة؛&lt;/li&gt;
&lt;li&gt;هل يتجمد التمرير؟&lt;/li&gt;
&lt;li&gt;هل يتغير ارتفاع الحاوية؟&lt;/li&gt;
&lt;li&gt;هل تعمل اللعبة على الهاتف؟&lt;/li&gt;
&lt;li&gt;هل تظهر رسائل خطأ؟&lt;/li&gt;
&lt;li&gt;هل يفتح المصدر نوافذ جديدة؟&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;صفحة سريعة قبل التشغيل لا تعني أن تجربة اللعب جيدة، لكنها تمنع اللعبة الخارجية من إفساد الصفحة قبل أن يطلبها المستخدم.&lt;/p&gt;

&lt;h2&gt;
  
  
  متى أحمّل اللعبة تلقائيًا؟
&lt;/h2&gt;

&lt;p&gt;لا أرى أن التحميل بعد النقر قاعدة إلزامية لكل موقع.&lt;/p&gt;

&lt;p&gt;قد يكون التحميل التلقائي مناسبًا عندما:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;توجد لعبة واحدة فقط في الصفحة؛&lt;/li&gt;
&lt;li&gt;مصدر اللعبة موثوق وخفيف؛&lt;/li&gt;
&lt;li&gt;المستخدم دخل من زر واضح هدفه اللعب مباشرة؛&lt;/li&gt;
&lt;li&gt;لا توجد إعلانات أو موارد خارجية ثقيلة؛&lt;/li&gt;
&lt;li&gt;أثبت القياس أن التحميل الفوري أسرع فعلًا للمستخدمين.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;لكن في دليل يحتوي على عدد كبير من الألعاب ومصادر متعددة، أفضّل التحميل بعد التفاعل.&lt;/p&gt;

&lt;p&gt;إنه قرار يمنحني تحكمًا أكبر ويمنع استهلاك الموارد لمن يغادر الصفحة قبل اللعب.&lt;/p&gt;

&lt;h2&gt;
  
  
  الخلاصة
&lt;/h2&gt;

&lt;p&gt;أكبر خطأ في صفحات ألعاب المتصفح هو افتراض أن وجود iframe يعني أن اللعبة جاهزة.&lt;/p&gt;

&lt;p&gt;الـ iframe قد يحمّل صفحة كاملة من طرف ثالث قبل أن يقرر المستخدم اللعب. لهذا أعرض صورة غلاف واضحة، وأحجز مساحة ثابتة، ثم أنشئ iframe بعد الضغط على زر التشغيل.&lt;/p&gt;

&lt;p&gt;أستخدم التحميل المتكاسل للصور والـ iframes الموجودة خارج الشاشة، لكنني لا أطبقه على المحتوى الأساسي بلا تفكير. أحمل صورة الغلاف الرئيسية مبكرًا، وأؤجل بطاقات الألعاب البعيدة، وأرسل لكل جهاز حجم الصورة المناسب.&lt;/p&gt;

&lt;p&gt;الهدف ليس منع تحميل اللعبة، بل تحميلها في اللحظة التي تصبح فيها مفيدة.&lt;/p&gt;

&lt;p&gt;عندما يصل المستخدم إلى صفحة لعبة، يجب أن تظهر الصفحة أولًا، ثم تبدأ اللعبة عندما يطلبها. ليس العكس.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>html</category>
      <category>performance</category>
      <category>webdev</category>
    </item>
    <item>
      <title>ما تعلمته من بناء واجهة RTL لموقع ألعاب عربية تعمل على الهاتف</title>
      <dc:creator>playgames</dc:creator>
      <pubDate>Thu, 06 Aug 2026 01:59:10 +0000</pubDate>
      <link>https://dev.to/playgames/m-tlmth-mn-bn-wjh-rtl-lmwq-lb-rby-tml-l-lhtf-2g29</link>
      <guid>https://dev.to/playgames/m-tlmth-mn-bn-wjh-rtl-lmwq-lb-rby-tml-l-lhtf-2g29</guid>
      <description>&lt;p&gt;عند بناء موقع عربي للألعاب، من السهل أن نعتقد أن دعم اللغة العربية يعني ترجمة العناوين، وإضافة &lt;code&gt;dir="rtl"&lt;/code&gt; إلى عنصر &lt;code&gt;html&lt;/code&gt;، ثم اعتبار المهمة منتهية.&lt;/p&gt;

&lt;p&gt;هذا يكفي لجعل النص يبدأ من اليمين، لكنه لا يكفي لصناعة تجربة جيدة.&lt;/p&gt;

&lt;p&gt;المستخدم الذي يصل إلى موقع ألعاب لا يريد قراءة مقدمة طويلة عن المشروع. يريد أن يعرف بسرعة:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ما نوع اللعبة؟&lt;/li&gt;
&lt;li&gt;هل تعمل على الهاتف؟&lt;/li&gt;
&lt;li&gt;هل تحتاج إلى تحميل؟&lt;/li&gt;
&lt;li&gt;أين زر التشغيل؟&lt;/li&gt;
&lt;li&gt;هل يستطيع الرجوع إلى الألعاب المشابهة بسهولة؟&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;عند العمل على موقع يجمع ألعاب التلبيس والطبخ والمكياج والديكور، اكتشفت أن أكبر المشكلات لم تكن في ترجمة النصوص، بل في ترتيب الواجهة، وضوح البطاقات، اتجاه العناصر المختلطة، وسرعة الوصول إلى اللعبة.&lt;/p&gt;

&lt;p&gt;في هذه المقالة أشارك أهم القرارات العملية التي اتخذتها، والأخطاء التي من الأفضل تجنبها عند بناء دليل ألعاب عربي يعمل من اليمين إلى اليسار.&lt;/p&gt;

&lt;h2&gt;
  
  
  ابدأ من نية المستخدم، لا من تصميم القالب
&lt;/h2&gt;

&lt;p&gt;قبل كتابة أي مكوّن، يجب فهم سبب دخول الزائر إلى الصفحة.&lt;/p&gt;

&lt;p&gt;من يبحث عن ألعاب بنات لا يبحث غالبًا عن مراجعة طويلة أو أخبار صناعة الألعاب. هو يريد فتح لعبة من نوع واضح، مثل:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;تلبيس؛&lt;/li&gt;
&lt;li&gt;طبخ؛&lt;/li&gt;
&lt;li&gt;مكياج؛&lt;/li&gt;
&lt;li&gt;تزيين غرف؛&lt;/li&gt;
&lt;li&gt;عناية بالحيوانات؛&lt;/li&gt;
&lt;li&gt;ألعاب أميرات؛&lt;/li&gt;
&lt;li&gt;ألعاب خفيفة تعمل على الهاتف.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;لذلك لا يجب أن يبدأ الموقع بشاشة ترحيب ضخمة تدفع الألعاب إلى أسفل الصفحة. كما لا يحتاج المستخدم إلى فقرة طويلة قبل أن يرى أول صف من الألعاب.&lt;/p&gt;

&lt;p&gt;في موقع ألعاب، شبكة الألعاب نفسها هي المحتوى الأساسي، وليست عنصرًا ثانويًا بعد مقدمة تسويقية.&lt;/p&gt;

&lt;p&gt;القرار الصحيح بالنسبة لي كان عرض عنوان واضح، وصف قصير جدًا، ثم الألعاب مباشرة.&lt;/p&gt;

&lt;h2&gt;
  
  
  استخدام &lt;code&gt;dir="rtl"&lt;/code&gt; لا يحل كل شيء
&lt;/h2&gt;

&lt;p&gt;الخطوة الأساسية هي تحديد اللغة والاتجاه على مستوى الصفحة:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ar"&lt;/span&gt; &lt;span class="na"&gt;dir=&lt;/span&gt;&lt;span class="s"&gt;"rtl"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;هذا يجعل المتصفح يتعامل مع النصوص والتخطيط الافتراضي بصورة أفضل، لكنه لا يحل العناصر التي تجمع العربية مع الإنجليزية والأرقام والروابط.&lt;/p&gt;

&lt;p&gt;مثال شائع هو عنوان يحتوي على اسم لعبة إنجليزي داخل جملة عربية. قد تنتقل الأقواس أو الأرقام إلى مكان غير متوقع، وقد يظهر الرابط بطريقة مربكة.&lt;/p&gt;

&lt;p&gt;في الحالات المختلطة يمكن استخدام:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;bdi&amp;gt;&lt;/span&gt;Cooking Game 2&lt;span class="nt"&gt;&amp;lt;/bdi&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;عنصر &lt;code&gt;bdi&lt;/code&gt; يعزل اتجاه النص الداخلي، ويمنع اسم اللعبة من إفساد ترتيب الجملة العربية المحيطة به.&lt;/p&gt;

&lt;p&gt;استخدمته خصوصًا مع:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;أسماء الألعاب الإنجليزية؛&lt;/li&gt;
&lt;li&gt;أرقام المراحل؛&lt;/li&gt;
&lt;li&gt;أسماء الملفات؛&lt;/li&gt;
&lt;li&gt;النطاقات والروابط؛&lt;/li&gt;
&lt;li&gt;أسماء التقنيات أو الشركات.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;إضافة مسافات عشوائية أو قلب النص يدويًا ليست حلًا. قد يبدو النص صحيحًا على جهاز واحد ثم ينكسر في متصفح آخر.&lt;/p&gt;

&lt;h2&gt;
  
  
  لا تعكس كل شيء لمجرد أن الصفحة RTL
&lt;/h2&gt;

&lt;p&gt;من الأخطاء الشائعة قلب جميع الأيقونات تلقائيًا.&lt;/p&gt;

&lt;p&gt;هناك عناصر يجب أن تتبع اتجاه القراءة، مثل سهم الانتقال إلى القسم السابق أو التالي. لكن توجد رموز عالمية لا تحتاج إلى قلب، مثل:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;زر التشغيل؛&lt;/li&gt;
&lt;li&gt;أيقونة الصوت؛&lt;/li&gt;
&lt;li&gt;أيقونة ملء الشاشة؛&lt;/li&gt;
&lt;li&gt;رمز الإغلاق؛&lt;/li&gt;
&lt;li&gt;أيقونة البحث؛&lt;/li&gt;
&lt;li&gt;رمز المشاركة.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;كذلك، لقطة اللعبة نفسها لا يجب قلبها أفقيًا. صورة المطبخ أو الشخصية أو واجهة اللعبة يجب أن تبقى كما هي.&lt;/p&gt;

&lt;p&gt;عند استخدام مكتبة أيقونات، لا تطبق &lt;code&gt;transform: scaleX(-1)&lt;/code&gt; على حاوية كاملة. اقلب فقط السهم الذي يمثل اتجاه التنقل عندما تكون هناك حاجة حقيقية لذلك.&lt;/p&gt;

&lt;h2&gt;
  
  
  بطاقة اللعبة يجب أن تجيب قبل النقر
&lt;/h2&gt;

&lt;p&gt;بطاقة اللعبة ليست مجرد صورة جميلة. هي أداة لاتخاذ القرار.&lt;/p&gt;

&lt;p&gt;المستخدم يحتاج إلى معرفة نوع اللعبة قبل فتحها. لهذا يجب أن تعرض الصورة شيئًا من اللعب الفعلي، لا مجرد وجه شخصية أو رسم ترويجي عام.&lt;/p&gt;

&lt;p&gt;إذا كانت اللعبة عن الطبخ، من الأفضل أن تظهر:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;الطعام؛&lt;/li&gt;
&lt;li&gt;أدوات المطبخ؛&lt;/li&gt;
&lt;li&gt;المكونات؛&lt;/li&gt;
&lt;li&gt;أو واجهة إعداد الطلبات.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;إذا كانت عن التلبيس، يجب أن تظهر الشخصية والملابس أو شاشة اختيار الأزياء.&lt;/p&gt;

&lt;p&gt;أما الصورة التي تعرض أميرة فقط من دون أي إشارة إلى طريقة اللعب، فقد تجذب النقر لكنها لا توضح ما سيحدث بعده.&lt;/p&gt;

&lt;p&gt;أفضل بنية وجدتها للبطاقة كانت بسيطة:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"game-card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/games/example-game/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
      &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/images/example-game.webp"&lt;/span&gt;
      &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"لعبة تلبيس واختيار فساتين للحفلة"&lt;/span&gt;
      &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"320"&lt;/span&gt;
      &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"180"&lt;/span&gt;
      &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;لعبة تلبيس للحفلة&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;اختاري الفستان وتسريحة الشعر والإكسسوارات.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;العنوان يوضح النوع، والوصف يذكر الفعل الذي سيقوم به اللاعب. لا حاجة إلى عبارات مثل “أفضل لعبة مذهلة لن تنسيها”.&lt;/p&gt;

&lt;h2&gt;
  
  
  اجعل مساحة النقر تشمل البطاقة
&lt;/h2&gt;

&lt;p&gt;على الهاتف، النقر على عنوان صغير ليس مريحًا.&lt;/p&gt;

&lt;p&gt;لذلك جعلت الصورة والعنوان والوصف جزءًا من رابط واحد. يستطيع المستخدم النقر على أي مساحة داخل البطاقة بدل محاولة إصابة زر صغير.&lt;/p&gt;

&lt;p&gt;لكن يجب ألا تحتوي البطاقة على عدة أزرار تؤدي إلى النتيجة نفسها. وجود رابط على الصورة، ورابط آخر على العنوان، وزر ثالث أسفل الوصف يضيف ازدحامًا من دون فائدة.&lt;/p&gt;

&lt;p&gt;رابط واحد واضح أفضل.&lt;/p&gt;

&lt;h2&gt;
  
  
  الشبكة المرنة أهم من عدد الأعمدة
&lt;/h2&gt;

&lt;p&gt;في شاشة كبيرة يمكن عرض أربع أو خمس بطاقات في صف، لكن فرض العدد نفسه على الهاتف يجعل الصور صغيرة جدًا.&lt;/p&gt;

&lt;p&gt;استخدمت شبكة تعتمد على الحد الأدنى لعرض البطاقة:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.games-grid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;auto-fill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;220px&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;بهذه الطريقة يختار المتصفح عدد الأعمدة المناسب للمساحة المتاحة.&lt;/p&gt;

&lt;p&gt;لم أستخدم &lt;code&gt;position: absolute&lt;/code&gt; لترتيب البطاقات، لأن الشبكة العادية أسهل في الصيانة وأكثر استقرارًا عند تغير طول العناوين العربية.&lt;/p&gt;

&lt;p&gt;النص العربي قد يحتاج إلى سطرين بينما يحتاج اسم إنجليزي إلى سطر واحد. يجب أن تتحمل البطاقة هذا الاختلاف من دون تداخل.&lt;/p&gt;

&lt;h2&gt;
  
  
  لا تجعل العنوان الطويل يكسر شكل الصفحة
&lt;/h2&gt;

&lt;p&gt;أسماء بعض الألعاب طويلة، خصوصًا عند محاولة وصف كل شيء داخل العنوان:&lt;/p&gt;

&lt;p&gt;“لعبة تلبيس ومكياج وقص شعر وتجهيز الأميرة لحفل الزفاف”.&lt;/p&gt;

&lt;p&gt;هذا النوع من العناوين قد يكون مفهومًا لمحرك البحث، لكنه سيئ داخل بطاقة صغيرة.&lt;/p&gt;

&lt;p&gt;الأفضل فصل الوظائف:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;العنوان:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;لعبة تجهيز الأميرة للحفل&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;الوصف:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;اختاري الفستان والمكياج وتسريحة الشعر.&lt;/p&gt;

&lt;p&gt;العنوان يحدد اللعبة، والوصف يشرح التفاصيل. لا تحتاج إلى وضع جميع الكلمات في السطر نفسه.&lt;/p&gt;

&lt;p&gt;يمكن أيضًا تحديد عدد الأسطر داخل البطاقات:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.game-card&lt;/span&gt; &lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;-webkit-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;-webkit-line-clamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;-webkit-box-orient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;vertical&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;لكن قص النص ليس بديلًا عن كتابة عنوان واضح. استخدمه فقط لمنع الحالات الاستثنائية من كسر الشبكة.&lt;/p&gt;

&lt;h2&gt;
  
  
  التصنيفات يجب أن تطابق ما يبحث عنه اللاعب
&lt;/h2&gt;

&lt;p&gt;من السهل على المطور إنشاء تصنيفات مبنية على بنية البيانات الداخلية، مثل:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ألعاب ثنائية الأبعاد؛&lt;/li&gt;
&lt;li&gt;ألعاب HTML5؛&lt;/li&gt;
&lt;li&gt;ألعاب Canvas؛&lt;/li&gt;
&lt;li&gt;ألعاب تعمل باللمس.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;هذه التصنيفات مفيدة للمطور، لكنها ليست الطريقة التي يبحث بها اللاعب.&lt;/p&gt;

&lt;p&gt;المستخدم لا يقول عادة: أريد لعبة Canvas.&lt;/p&gt;

&lt;p&gt;هو يقول:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;أريد لعبة طبخ؛&lt;/li&gt;
&lt;li&gt;أريد لعبة تلبيس؛&lt;/li&gt;
&lt;li&gt;أريد لعبة مكياج؛&lt;/li&gt;
&lt;li&gt;أريد لعبة أميرات؛&lt;/li&gt;
&lt;li&gt;أريد لعبة حيوانات.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;لذلك يجب أن تعكس القائمة لغة المستخدم، لا لغة قاعدة البيانات.&lt;/p&gt;

&lt;p&gt;يمكن الاحتفاظ بالتقنيات والخصائص في الخلفية لأغراض الفلترة، لكن التصنيفات العامة يجب أن تكون مفهومة فورًا.&lt;/p&gt;

&lt;h2&gt;
  
  
  لا تنشئ عشرات التصنيفات الفارغة
&lt;/h2&gt;

&lt;p&gt;إضافة كل تصنيف يمكن تخيله تبدو طريقة سهلة لتوسيع الموقع، لكنها تؤدي إلى صفحات ضعيفة تحتوي على لعبة أو لعبتين فقط.&lt;/p&gt;

&lt;p&gt;من الأفضل إنشاء تصنيف عندما توجد مجموعة حقيقية من الألعاب التي تشترك في نية واضحة.&lt;/p&gt;

&lt;p&gt;على سبيل المثال، يمكن جمع ألعاب إعداد الكعك والبيتزا والمطاعم تحت “ألعاب طبخ” إذا لم يكن هناك عدد كافٍ لبناء صفحة مستقلة لكل نوع.&lt;/p&gt;

&lt;p&gt;التقسيم الزائد يجعل المستخدم ينتقل بين صفحات كثيرة ولا يجد خيارات كافية في أي صفحة.&lt;/p&gt;

&lt;h2&gt;
  
  
  صفحة اللعبة يجب أن تضع اللعب قبل الشرح
&lt;/h2&gt;

&lt;p&gt;عندما يفتح المستخدم صفحة لعبة، لا يريد النزول عبر مقال طويل حتى يصل إلى زر التشغيل.&lt;/p&gt;

&lt;p&gt;رتبت صفحة اللعبة بهذا الشكل:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;اسم اللعبة؛&lt;/li&gt;
&lt;li&gt;وصف قصير يوضح المهمة؛&lt;/li&gt;
&lt;li&gt;منطقة التشغيل؛&lt;/li&gt;
&lt;li&gt;تعليمات مختصرة عند الحاجة؛&lt;/li&gt;
&lt;li&gt;ألعاب مشابهة؛&lt;/li&gt;
&lt;li&gt;معلومات إضافية في الأسفل.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;إذا كانت اللعبة لا تبدأ تلقائيًا، يجب أن يكون زر التشغيل مختلفًا بوضوح عن أي رابط أو إعلان.&lt;/p&gt;

&lt;p&gt;استخدام عبارة “ابدئي اللعب” أفضل من زر غامض يحمل كلمة “التالي”.&lt;/p&gt;

&lt;h2&gt;
  
  
  لا تستخدم زر تنزيل في موقع ألعاب متصفح
&lt;/h2&gt;

&lt;p&gt;إذا كانت اللعبة تعمل داخل المتصفح، فلا يوجد سبب لاستخدام كلمات توحي بالتثبيت.&lt;/p&gt;

&lt;p&gt;كلمات مثل:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;تحميل؛&lt;/li&gt;
&lt;li&gt;تنزيل؛&lt;/li&gt;
&lt;li&gt;تثبيت؛&lt;/li&gt;
&lt;li&gt;Get App؛&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;قد تجعل الزائر يعتقد أنه سيغادر الصفحة أو يثبت ملفًا.&lt;/p&gt;

&lt;p&gt;استخدم:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;العب الآن؛&lt;/li&gt;
&lt;li&gt;ابدأ اللعبة؛&lt;/li&gt;
&lt;li&gt;افتح اللعبة؛&lt;/li&gt;
&lt;li&gt;جرّب اللعبة.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;النص يجب أن يصف ما سيحدث بعد النقر بدقة.&lt;/p&gt;

&lt;h2&gt;
  
  
  اختبر الصفحة بإبهام واحد
&lt;/h2&gt;

&lt;p&gt;اختبار سطح المكتب لا يكفي.&lt;/p&gt;

&lt;p&gt;فتحت الصفحات على هاتف حقيقي، واستخدمتها بيد واحدة. هذا الاختبار كشف مشكلات لم تكن واضحة في أدوات المطور:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;زر صغير قريب من حافة الشاشة؛&lt;/li&gt;
&lt;li&gt;قائمة تصنيفات تحتاج إلى تمرير أفقي غير واضح؛&lt;/li&gt;
&lt;li&gt;صورة تتسبب في قفزة أثناء التحميل؛&lt;/li&gt;
&lt;li&gt;رابطان متقاربان يؤديان إلى صفحات مختلفة؛&lt;/li&gt;
&lt;li&gt;عنوان طويل يدفع زر التشغيل إلى أسفل؛&lt;/li&gt;
&lt;li&gt;نافذة لعبة أكبر من عرض الهاتف.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;حجم منطقة اللمس يجب أن يكون مريحًا، والمسافة بين العناصر القابلة للنقر يجب ألا تسبب نقرات خاطئة.&lt;/p&gt;

&lt;h2&gt;
  
  
  ثبّت أبعاد الصور قبل تحميلها
&lt;/h2&gt;

&lt;p&gt;عندما لا تحدد أبعاد الصور، تتحرك البطاقات أثناء التحميل. قد يحاول المستخدم النقر على لعبة، ثم تنتقل البطاقة فجأة ويضغط على لعبة أخرى.&lt;/p&gt;

&lt;p&gt;لذلك أضفت &lt;code&gt;width&lt;/code&gt; و&lt;code&gt;height&lt;/code&gt; إلى الصور، واستخدمت &lt;code&gt;aspect-ratio&lt;/code&gt; في CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.game-card&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;aspect-ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;object-fit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;هذا يحجز المساحة قبل وصول الصورة ويجعل الشبكة أكثر استقرارًا.&lt;/p&gt;

&lt;h2&gt;
  
  
  لا تؤجل الصورة الأولى
&lt;/h2&gt;

&lt;p&gt;استخدام &lt;code&gt;loading="lazy"&lt;/code&gt; مفيد للبطاقات الموجودة أسفل الصفحة، لكنه ليس مناسبًا دائمًا لأول صور يراها المستخدم.&lt;/p&gt;

&lt;p&gt;يمكن تحميل الصور الأولى بصورة طبيعية، وتأجيل الصور البعيدة فقط. تأجيل كل الصور قد يجعل أعلى الصفحة يبدو فارغًا للحظات، خصوصًا على اتصال بطيء.&lt;/p&gt;

&lt;p&gt;كما أن ضغط الصور وتحويلها إلى WebP أو AVIF يقلل وقت الانتظار أكثر من إضافة مؤثر تحميل جميل.&lt;/p&gt;

&lt;h2&gt;
  
  
  ماذا فعلت في المشروع الفعلي؟
&lt;/h2&gt;

&lt;p&gt;طبقت هذه القرارات أثناء تنظيم موقع &lt;a href="https://gamesforgirlsonline.com/" rel="noopener noreferrer"&gt;العاب بنات&lt;/a&gt; ليكون الوصول إلى ألعاب الطبخ والتلبيس والمكياج وغيرها مباشرًا قدر الإمكان.&lt;/p&gt;

&lt;p&gt;لم يكن الهدف عرض أكبر عدد من المكونات أو المؤثرات. الهدف كان تقليل عدد الخطوات بين دخول الصفحة وبدء اللعبة.&lt;/p&gt;

&lt;p&gt;كل عنصر لا يساعد على اختيار لعبة أو تشغيلها يحتاج إلى سبب قوي للبقاء.&lt;/p&gt;

&lt;h2&gt;
  
  
  لا تجعل RTL نسخة معكوسة من التصميم الإنجليزي
&lt;/h2&gt;

&lt;p&gt;أفضل واجهة عربية ليست دائمًا التصميم الإنجليزي نفسه بعد قلب الاتجاه.&lt;/p&gt;

&lt;p&gt;قد تحتاج القوائم إلى ترتيب مختلف، وقد تحتاج العناوين إلى مساحة أكبر، وقد يصبح شريط أفقي مناسبًا بالإنجليزية لكنه مربكًا بالعربية.&lt;/p&gt;

&lt;p&gt;التصميم الجيد يبدأ من المحتوى العربي نفسه:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;طول الكلمات؛&lt;/li&gt;
&lt;li&gt;اتجاه القراءة؛&lt;/li&gt;
&lt;li&gt;طريقة خلط الأسماء الأجنبية؛&lt;/li&gt;
&lt;li&gt;أحجام الخطوط؛&lt;/li&gt;
&lt;li&gt;استخدام الهاتف؛&lt;/li&gt;
&lt;li&gt;ترتيب المعلومات الذي يتوقعه الزائر.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RTL ليس تأثيرًا بصريًا. هو جزء من بنية الصفحة.&lt;/p&gt;

&lt;h2&gt;
  
  
  الخلاصة
&lt;/h2&gt;

&lt;p&gt;بناء موقع ألعاب عربي جيد لا يتطلب واجهة معقدة، لكنه يتطلب قرارات دقيقة.&lt;/p&gt;

&lt;p&gt;استخدم &lt;code&gt;lang="ar"&lt;/code&gt; و&lt;code&gt;dir="rtl"&lt;/code&gt; من البداية، واعزل النصوص الأجنبية، ولا تقلب الأيقونات والصور بلا سبب. اجعل بطاقة اللعبة تشرح نوعها قبل النقر، واستخدم تصنيفات يفهمها اللاعب، وضع منطقة التشغيل في أعلى صفحة اللعبة.&lt;/p&gt;

&lt;p&gt;الأهم من ذلك: اختبر المسار الكامل على الهاتف.&lt;/p&gt;

&lt;p&gt;هل يستطيع المستخدم دخول الموقع، فهم نوع اللعبة، فتحها والبدء خلال وقت قصير؟&lt;/p&gt;

&lt;p&gt;إذا كانت الإجابة لا، فلن تعالج المشكلة فقرة تسويقية إضافية أو حركة بصرية جديدة. يجب تقليل الخطوات وإزالة العناصر التي تعطل اللعب.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ui</category>
      <category>ux</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
