تحسين محركات البحث لـ Qwik

كيف تضع قابلية الاستئناف في Qwik المحتوى داخل HTML افتراضيًا، وتساعد على خفض INP وTBT — مع أنماط QwikCity لوسوم meta والروابط الأساسية وJSON-LD وخرائط المواقع وi18n اللازمة لتحسين ظهور موقع Qwik في البحث.

نُشر أول مرة: 26 يونيو 2026 · آخر تحديث: 11 أغسطس 2026 · Advanced
اللغات
دليل واحد في هذه الصفحة

Qwik هو إطار عمل JavaScript تعتمد فكرته الأساسية على قابلية الاستئناف: يسلسل الخادم حالة التطبيق والمستمعين وشجرة المكوّنات داخل HTML، فيستأنف المتصفح عمله من دون ترطيب (مع استمرار تشغيل سكربت Qwikloader بحجم ~1 كيلوبايت؛ أي إن الحمل ليس صفر JavaScript حرفيًا). بالنسبة إلى تحسين محركات البحث، يمنح ذلك ميزتين للمسارات التي تُصيَّر فعليًا على الخادم: يكون المحتوى موجودًا في HTML افتراضيًا، فتراه برامج الزحف فورًا من دون انتظار موجة تصيير، وتميل قيمتا INP وTBT إلى الانخفاض لأن الترطيب لا يحجب الخيط الرئيسي عند التحميل. تحقّق من النتيجتين بالبيانات الميدانية بدل افتراضهما. يتيح QwikCity مزج SSR وSSG لكل مسار، واستخدام routeLoader$() لجلب البيانات من الخادم وتصدير head للعنوان والوصف وOG والرابط الأساسي وJSON-LD؛ وكلها تُصيَّر على الخادم. يعمل أساس SEO مباشرةً، لكن المهم هو استخدام routeLoader$() للبيانات الوصفية الديناميكية بدل تأثيرات العميل. أما القيد الأبرز فهو أن منظومته أصغر من منظومة React/Vue، وأن Qwik — حتى كتابة هذه السطور — على خط الإصدار v2 التجريبي.

TL;DR — الابتكار الأساسي في Qwik هو الاستئناف (Resumability): في وقت SSR، يقوم بتسلسل مستمعي الأحداث (كسمات HTML)، وشجرة المكونات (في تعليقات HTML)، وحالة التطبيق (في سكربت qwik/json) داخل HTML، بحيث يقوم المتصفح بالاستئناف بدلاً من الترطيب — سكربت Qwikloader صغير (~1 كيلوبايت) لا يزال يعمل، لذا ليس صفر JavaScript حرفيًا. هذا مختلف جوهريًا عن React/Vue/Angular/SolidJS، التي جميعها تقوم بالترطيب. على المسارات التي تُصيَّر فعليًا على الخادم، تكون الفائدة لتحسين محركات البحث (SEO) مزدوجة: المحتوى موجود في HTML افتراضيًا (بدون تأخير موجة العرض للزاحفين) وINP/TBT تتجه نحو الصفر لأنه لا يوجد ترطيب يحجب الخيط الرئيسي عند التحميل — تحقق من كليهما باستخدام بيانات ميدانية بدلاً من افتراضهما. QwikCity هو إطار العمل الفوقي — يمكن مزج SSR وSSG لكل مسار، وليس اختيارًا واحدًا للمشروع بأكمله. البيانات الوصفية موجودة في تصدير head (العنوان، meta، OG، canonical، JSON-LD)، وتُغذى بواسطة routeLoader$() للبيانات من جانب الخادم. خرائط المواقع (Sitemaps) تلقائية في SSG (للمسارات المبنية فعليًا) ومسار ديناميكي في SSR. Qwik حاليًا على خط v2 (إصدار تجريبي) وقت كتابة هذا. والقيد الواقعي أن النظام البيئي أحدث و أصغر من منظومة React.

الاستئناف: الفكرة الأساسية (ولماذا يهم تحسين محركات البحث)

أنشأ Miško Hevery — مبتكر Angular — إطار Qwik لدى builder.io، والغرض الأساسي منه هو التخلص من الترطيب. (وقت كتابة هذا، Qwik على خط v2، حاليًا في إصدار تجريبي — تحقق من واجهة API وفق الإصدار المثبت لديك قبل نسخ الكود من أي مصدر، بما في ذلك هذا.) الترطيب هو ما يفعله كل إطار عمل رئيسي بعد SSR: ينزّل كود المكوّنات ويعيد تنفيذه في المتصفح لإرفاق معالجات الأحداث وإعادة بناء الحالة الداخلية. كما يقول Hevery، “Hydration is when an application is downloaded and executed twice, once as HTML and again as JavaScript.” (ترجمة) «الترطيب هو عندما يتم تنزيل تطبيق وتنفيذه مرتين، مرة كـ HTML ومرة أخرى كـ JavaScript.» هذا التنفيذ الثاني عبء محض — الصفحة تبدو جاهزة لكنها ليست تفاعلية، ويظل الخيط الرئيسي مشغولًا.

بدلاً من ذلك، يقوم Qwik بتسلسل ثلاثة أشياء في HTML وقت SSR:

  • مستمعو الأحداث — مشفرون كسمات HTML (مثل on:click="./chunk.js#symbol"). سكربت صغير مضمّن (Qwikloader، ~1 كيلوبايت) يرفق مستمعًا عامًا واحدًا، ويقرأ الجزء/الرمز المشفر عند حدث، ويقوم بتنزيل كود المعالج فقط عند الطلب.
  • بنية شجرة المكونات — مشفرة في تعليقات HTML، بحيث يمكن لـ Qwik إعادة بناء التسلسل الهرمي دون تنفيذ كود المكونات.
  • حالة التطبيق — مسلسلة في كتلة <script type="qwik/json">، بحيث يمكن لأي مكون الاستئناف دون وجود أصله.

عند تحميل الصفحة، لا يعيد Qwik تشغيل مكوناتك. Evidence for this claim Qwik resumability restores listeners and application state without rerunning component initialization on page startup. Scope: Qwik resumability model. Confidence: high · Verified: Qwik: Resumable كما تقول الوثائق، “Resumability is a way for a framework to recover its state without re-executing the application components on the client.” (ترجمة) «الاستئناف هو طريقة لإطار العمل لاستعادة حالته دون إعادة تنفيذ مكونات التطبيق على العميل.» النتيجة، بكلمات الوثائق: “Qwik apps work instantly without any delay because they don’t need hydration, regardless of their size or complexity.” (ترجمة) «تطبيقات Qwik تعمل فورًا دون أي تأخير لأنها لا تحتاج إلى الترطيب، بغض النظر عن حجمها أو تعقيدها.»

هذا ليس بنية الجزر (Astro). الجزر لا تزال تقوم بالترطيب لكل جزيرة بشكل فردي. Qwik لا يقوم بالترطيب لأي شيء — لا توجد تكلفة Hydration لكل جزيرة لعدم وجود أي ترطيب.

ما يستلمه الزاحفون فعليًا

نظرًا لأن Qwik يقوم بمعالجة كل شيء مسبقًا على الخادم ولا يعيد العرض أبدًا على العميل، فإن HTML الذي يجلبه Googlebot يحتوي بالفعل على المحتوى الكامل الخاص بك — النصوص والروابط والعناوين وكل شيء — للمسار الذي يتم عرضه فعليًا على الخادم. العرض هو قرار لكل مسار في QwikCity (SSR أو SSG أو مزيج)؛ المسار الذي يُترك في وضع العميل فقط، أو المحتوى الذي يتم جلبه من تأثير جانب العميل بدلاً من routeLoader$()، لا يحصل على هذه الميزة فقط لأن المشروع يستخدم Qwik. تعالج Google JavaScript على مرحلتين (HTML أولاً، ثم تمرير عرض مؤجل يمكن أن يتأخر من ساعات إلى أيام). التطبيق المعتمد بشكل كبير على عرض العميل يخاطر بظهور المحتوى فقط في تلك الموجة الثانية. مسار Qwik المعروض بشكل صحيح على الخادم يتجنب هذا الخطر: لا يوجد تأخير في قائمة انتظار العرض لأن المحتوى لم يكن ينتظر JavaScript الخاص بالعميل في المقام الأول. تعامل مع “صفحات Qwik تتصرف مثل HTML ثابت لبرامج الزحف” على أنه نية البنية، ثم تأكد من ذلك على عناوين URL المنشورة لديك باستخدام view-source — الموقف الأكثر أمانًا لـ JavaScript SEO هو التحقق من الاستجابة، وليس الثقة في تسمية الإطار.

يعمل Bing بنفس الطريقة — نموذج من مرحلتين يفضل HTML المعروض على الخادم لتحقيق الكفاءة. ناتج Qwik القائم على HTML أولاً يفيد كلا المحركين لنفس السبب.

Core Web Vitals: ميزة هيكلية

تستخدم Google البيانات الميدانية (CrUX) لإشارة تجربة الصفحة، وINP حلت محل FID كأحد Core Web Vitals في مارس 2024. هنا تؤتي بنية Qwik ثمارها مباشرة: مع Qwikloader كالبرنامج النصي الوحيد الذي يعمل عند التحميل — تشير الوثائق إلى أن المواقع “يمكن أن تعمل مع حوالي 1 كيلوبايت من JavaScript (بغض النظر عن تعقيد التطبيق)” — لا يوجد تقريبًا ما يعيق الخيط الرئيسي. إجمالي وقت الحظر يتجه نحو الصفر ويظل INP منخفضًا لأنه لا توجد مرحلة ترطيب تتنافس مع تفاعلات المستخدم الأولى. تطبيق Qwik الأكبر لا يعني تكلفة بدء تشغيل أعلى؛ يتم جلب JavaScript بشكل كسول، لكل تفاعل، وليس كحزمة تشغيل واحدة.

هذا هو الفرق عن الأطر الراسخة. Next.js وNuxt وAngular SSR تضع المحتوى في HTML أيضًا — فهي ليست سيئة لتحسين محركات البحث — لكنها تحمل تكلفة ترطيب تتوسع مع التطبيق. تزيل Qwik هذه التكلفة بالتصميم.

هذا هو التوقع المعماري، وليس نتيجة مقاسة. لا يضمن درجة INP أو TBT أو CrUX محددة لموقعك — البرامج النصية من جهات خارجية، وعلامات التحليلات، وتكلفة جلب البيانات لكل مسار يمكن أن تستهلك جميعها الميزة. تأكد من ذلك باستخدام البيانات الميدانية (CrUX، تقرير Core Web Vitals في Search Console) على عناوين URL المنشورة الخاصة بك قبل تقديم ادعاء بالأداء لعميل أو أصحاب مصلحة؛ راجع علامة التبويب كيفية القياس لمؤشرات الأداء الرئيسية والإيقاع المحددين.

وسوم Meta وhead للمستند

في QwikCity، توجد بيانات تعريف الصفحة في تصدير head من كل ملف مسار. بالنسبة لبيانات التعريف الثابتة، فهي ثابتة: Evidence for this claim Qwik City route modules can export a DocumentHead value or function for route metadata. Scope: Qwik City route metadata. Confidence: high · Verified: Qwik City: Head

export const head: DocumentHead = {
  title: 'Qwik SEO Guide',
  meta: [
    { name: 'description', content: 'How Qwik resumability helps SEO.' },
    { property: 'og:title', content: 'Qwik SEO Guide' },
    { property: 'og:description', content: 'Resumability, meta tags, sitemaps.' },
  ],
  links: [
    { rel: 'canonical', href: 'https://example.com/qwik-seo/' },
  ],
};

يتم عرض كل هذا على الخادم في <head>، لذا فهو موجود في HTML الذي يراه الزاحف. النمط الأساسي — links: [{ rel: 'canonical', href: '...' }] — من السهل تفويته ولكنه المكان الصحيح له.

بالنسبة إلى البيانات الوصفية الديناميكية (منشورات المدونات والمنتجات)، فإن النمط الحاسم لـSEO هو routeLoader$(). يعمل من جهة الخادم قبل استجابة HTML، ويمكن أن يكون تصدير head دالة تتلقى قيمة المحمّل المحلولة:

export const usePost = routeLoader$(async ({ params }) => {
  return await getPost(params.slug); // runs on the server
});

export const head: DocumentHead = ({ resolveValue }) => {
  const post = resolveValue(usePost);
  return {
    title: post.title,
    meta: [{ name: 'description', content: post.excerpt }],
    links: [{ rel: 'canonical', href: `https://example.com/blog/${post.slug}/` }],
  };
};

هذا هو المكافئ في QwikCity لـ getServerSideProps. الانضباط المهم لتحسين محركات البحث: اجلب بيانات التعريف باستخدام routeLoader$()، وليس في تأثير جانب العميل (useSignal()/useResource$() التي تعمل في المتصفح). إذا قمت بتعيين العنوان من تأثير عميل، فلن يكون في HTML الموجة الأولى.

البيانات المنظمة (JSON-LD)

يتم وضع JSON-LD في مصفوفة scripts الخاصة بتصدير head، ويتم عرضه سطريًا في <head> على الخادم ويمكن الزحف إليه بالكامل:

export const head: DocumentHead = ({ resolveValue }) => {
  const post = resolveValue(usePost);
  return {
    title: post.title,
    scripts: [
      {
        props: { type: 'application/ld+json' },
        script: JSON.stringify({
          '@context': 'https://schema.org',
          '@type': 'Article',
          headline: post.title,
          datePublished: post.date,
        }),
      },
    ],
  };
};

نظرًا لأنه يتم تسلسله في استجابة HTML، فلا يوجد تأخير في العرض قبل أن يكون الترميز متاحًا لبرامج الزحف. أحد تفاصيل الإعداد التي يسهل تفويتها: حقل scripts ينتج مخرجات فقط إذا كان مكوّن router-head في مشروعك يعرض فعليًا head.scripts (عادةً عبر dangerouslySetInnerHTML) — فالأمر ليس تلقائيًا فقط لأنك ملأت المصفوفة. إذا كان router-head.tsx في قالب البداية لا يقوم بالفعل بالتكرار على head.scripts، أضف ذلك قبل الثقة في ظهور JSON-LD في الاستجابة.

Sitemaps و robots.txt

  • بناءات SSG: خيار الإعداد sitemapOutFile يولد تلقائيًا sitemap.xml أثناء البناء الثابت — لكنه يتضمن فقط المسارات التي تم بناؤها فعليًا. المسار المستبعد من البناء الثابت (معاملات ديناميكية لم تقم بمعالجتها مسبقًا، صفحة محجوبة خلف شرط) لن يكون في sitemap حتى لو كان موجودًا.
  • مواقع SSR: لا يوجد sitemap تلقائي — أضف مسارًا في src/routes/sitemap.xml/index.ts مع RequestHandler يبني ويعيد XML ديناميكيًا.
  • robots.txt: ضعه في /public/ ليتم تقديمه في الجذر.
  • الروابط الأساسية وروابط sitemap تعتمد كلاهما على origin. QwikCity يبني روابط مطلقة من origin/base المكوّن (أو أصل رأس مُعاد توجيهه في وسيط SSR). أصل خاطئ أو مسرّب من معاينة/تدريج في هذا الإعداد ينتج روابط أساسية وإدخالات sitemap خاطئة في الإنتاج — تحقق من المخرجات الفعلية، وليس فقط ملف الإعداد، بعد أي تغيير في المحول أو النشر.
Evidence for this claim The SSG origin and base configuration affect absolute canonical and sitemap URLs; preview or deployment origins can leak into production output if adapter configuration is wrong. Scope: production build, server adapter, origin reconstruction and caching Confidence: high · Verified: Deployments

تحسين محركات البحث الدولي

آليتان، تُستخدمان معًا:

  • rewriteRoutes في إعداد QwikCity يربط مسارات URL المترجمة بمساراتك دون تكرار المكونات (مثل /it/documentazione//docs/). هذا يمنحك روابط URL نظيفة ومترجمة — الأساس لهيكل URL دولي.
  • Qwik Speak (مكتبة منفصلة) يتعامل مع ترجمة المحتوى.
  • وسوم hreflang توضع في مصفوفة links في تصدير head، مشيرة كل لغة إلى بدائلها. انظر تحسين محركات البحث الدولي و hreflang للقواعد عبر المحركات.

SSR مقابل SSG لتحسين محركات البحث

كلاهما يضع المحتوى في HTML، لذا كلاهما آمن لبرامج الزحف — وQwikCity يتيح لك خلط الأوضاع لكل مسار، وليس فقط مرة واحدة للمشروع بأكمله. اختر لكل مسار بناءً على شكل المحتوى:

  • SSG (محول ثابت) ينتج ملفات HTML نقية، لا حاجة لخادم — مثالي للمحتوى الذي لا يتغير لكل طلب. sitemap تلقائي (للمسارات التي تم بناؤها فعليًا)، أرخص استضافة، أسرع TTFB من CDN. المقايضة هي الحداثة: المحتوى لا يُحدَّث إلا في عملية البناء التالية، والمسار الذي يفشل في البناء ببساطة غير موجود.
  • SSR يعرض لكل طلب — مطلوب للبيانات المخصصة أو المتغيرة بشكل متكرر. شغّله على الحافة (Cloudflare، Vercel، Netlify) لـ TTFB منخفض، واضبط رؤوس Cache-Control على استجابات SSR حتى يتمكن CDN من تقديم التكرارات دون إعادة العرض. المقايضة هي أن الفشل في وقت الطلب (مثل routeLoader$() بطيء أو به خطأ) يؤثر على الاستجابة المباشرة، لذا أضف معالجة الأخطاء لجلب البيانات بدلاً من تركها تظهر كصفحة مكسورة.

لا يوجد وضع “أكثر أمانًا لتحسين محركات البحث” من الآخر افتراضيًا — اختر لكل مسار بناءً على مدى تكرار تغيير المحتوى وما يحدث إذا كان مصدر البيانات غير متاح مؤقتًا، ثم تحقق من الاستجابة المنشورة في كلتا الحالتين.

ما يجب الانتباه إليه

  • ليس كل شيء قابلًا للتسلسل. لا يمكن وضع نسخ من الكائنات (class instances) والوعود (promises) والتدفقات (streams) في حالة HTML. الكود الذي يتعامل معها يجب أن يعمل على العميل فقط — أبقِه خارج أي شيء يحتاج إلى أن يكون في HTML الخادم (خاصة البيانات الوصفية). إذا استبعدت قيمة عمدًا باستخدام noSerialize()، فتذكر أنها تعود كـ undefined بعد استئناف التطبيق على العميل — لا تلجأ إليها في أي شيء لا تزال الصفحة بحاجة إلى قراءته بعد الاستئناف، بما في ذلك مسارات البيانات الوصفية.
  • useVisibleTask$() هي مخرج حقيقي، استخدمها باعتدال. تعمل على العميل بعد العرض الأولي — الخطاف الوحيد الذي يعمل عمدًا ضد قابلية الاستئناف. لا تحجب العرض أو تضر بـ HTML الأولي، لكنها تعني أن JavaScript على العميل يعمل والذي كان Qwik سيؤجله بخلاف ذلك. مناسبة للعمل الذي يكون على العميل فقط (مكتبة رسوم بيانية، خريطة)؛ خيار خاطئ لأي شيء يجب أن يغذي البيانات الوصفية المقدمة من الخادم.
  • تحقق من أن علامات meta موجودة في المصدر، وليست محقونة بواسطة JavaScript. يجب أن يُظهر عرض المصدر (وليس فقط DOM المعروض في أدوات المطور) العنوان والرابط الأساسي (canonical) وJSON-LD. إذا ظهرت فقط في DOM المعروض، فأنت قمت بتعيينها من تأثير على العميل بدلاً من تصدير head / routeLoader$().
  • routeLoader$() مقابل useResource$()/useSignal(). تعمل اللوادر (loaders) على الخادم وتغذي head؛ بينما يمكن للآخرين العمل في المتصفح. لأي شيء يجب أن يكون في البيانات الوصفية أو HTML للموجة الأولى، استخدم اللودر.
  • نظام بيئي أصغر. لدى Qwik عدد أقل بكثير من موصلات CMS وإضافات SEO مقارنة بـ Next.js، ومجتمع أصغر للاعتماد عليه. الإطار قادر؛ ستحتاج فقط إلى كتابة المزيد من الكود اللاصق بنفسك. موقع builder.io نفسه يعمل على Qwik، لذا فهو مستخدم في الإنتاج — ولكن ادخل بعيون مفتوحة بشأن فجوة النضج.

أين يقع هذا

Qwik هو أحد إطارين في قصة أطر عمل JavaScript — والآخر هو SolidJS. التمييز الرئيسي الذي يجب تذكره: Qwik يستأنف؛ SolidJS (وReact وVue وAngular) يرطب. كلاهما لا يزال ينتج HTML غنيًا بالمحتوى عبر أطر العمل الوصفية الخاصة بهما، لذا فإن الزحف جيد في كلتا الحالتين؛ زاوية قابلية الاستئناف هي ما يجعل ملف INP/TBT الخاص بـ Qwik الأفضل هيكليًا في المجموعة. بالنسبة للجانب المتري، انظر Core Web Vitals؛ وبالنسبة للأساسيات، راجع مركز JavaScript SEO.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.