ما ملف PDF الخطي (Linearized)؟ الخلفية التقنية للعرض السريع على الويب
6 دقيقة للقراءة
من ملفَي PDF بالحجم نفسه يُفتح أحدهما فوراً في المتصفح، ويعرض الآخر صفحة فارغة إلى أن ينزل كاملاً. والفرق ليس في محتوى الملف — بل في ترتيب الكائنات داخله. نشرح في هذا المقال آلية قراءة PDF، وكيف تقلب الخطية هذه الآلية، وما فائدة جداول التلميحات.
لماذا يُقرأ PDF من النهاية
توجد في نهاية ملف PDF الأشياء الثلاثة التالية:
startxref
1247893
%%EOF
فسطر startxref يقول عند أي بايت من الملف يبدأ جدول الإحالات المتقاطعة. وأول ما يفعله العارض عند فتح ملف PDF هو قراءة آخر بضع مئات البايتات من الملف ليجد هذا الرقم.
ثم يذهب إلى ذلك البايت ويقرأ جدول xref. ويُدرِج هذا الجدول رقم كل كائن في الملف والبايت الذي يبدأ عنده. ويأتي بعد الجدول قاموس trailer؛ وفيه رقم كائن الكاتالوج.
ويستطيع العارض الآن إيجاد الكاتالوج. ومنه يصل إلى شجرة الصفحات، ومنها إلى كائن الصفحة الأولى، ومنه إلى تدفق المحتوى والموارد المستخدمة. وقد تكون هذه الموارد في أي موضع من الملف — فقد يكون خط الصفحة الأولى في وسط الملف وصورتها قرب نهايته.
ولهذا التصميم سبب: التحديث التزايدي. فحين يُجرى تغيير على ملف PDF تُضاف التغييرات إلى النهاية ويُكتب جدول xref جديد بدل إعادة كتابة الملف كاملاً. ويشير الجدول الجديد إلى القديم قائلاً «انظر هناك لما لم يتغير». فيكبر الملف لكن العملية سريعة وتبقى النسخة القديمة في الملف. وعلى هذا تقوم آلية عمل التواقيع الرقمية أيضاً.
وثمن ذلك: أن عليك رؤية نهاية الملف قبل أن تستطيع قراءة أي جزء منه.
لماذا يمثّل ذلك مشكلة عبر الشبكة
على القرص المحلي يُعدّ القفز إلى نهاية الملف مجانياً. والحال مختلف عبر الشبكة.
فحين يطلب متصفح ملف PDF من الخادم، يبدأ الخادم بإرساله من أوله. والمعلومات التي يحتاجها العارض في آخره. أي أنه يلزم عملياً نزول الملف كاملاً لرسم الصفحة الأولى.
وكتالوج بحجم 50 ميجابايت ينزل في نحو 40 ثانية على اتصال بسرعة 10 ميجابت/ث. وينظر المستخدم إلى صفحة فارغة طوال هذه الـ 40 ثانية. ومعظم المستخدمين لا ينتظرون.
الخطية تقلب الترتيب
بنية ملف PDF الخطي كالتالي:
| الموضع | المحتوى |
|---|---|
| بداية الملف | قاموس معاملات الخطية (/Linearized) |
| مباشرة بعده | جدول xref الخاص بالصفحة الأولى وtrailer الخاص بها |
| ثم | كل كائنات الصفحة الأولى (المحتوى، والخط، والصورة) |
| ثم | جداول التلميحات (hint tables) |
| ثم | كائنات بقية الصفحات، بترتيب الصفحات |
| نهاية الملف | جدول xref الرئيسي (للتوافق) |
ويقول قاموس المعاملات في مقدمة الملف: هذا الملف خطي، وطوله الكلي كذا، وكائنات الصفحة الأولى تمتد حتى البايت كذا، وجداول التلميحات تبدأ هنا.
وبذلك يمتلك العارض كل ما يلزم لرسم الصفحة الأولى لحظة تلقّيه أول بضع مئات الكيلوبايتات من الملف. فيبدأ المستخدم قراءة الصفحة الأولى بينما التنزيل مستمر.
جداول التلميحات: البنية التي تتيح القفز إلى الصفحات
الفائدة الثانية للخطية، ولعلها الأثمن، هي إمكان القفز مباشرة إلى الصفحة المطلوبة.
والبنية التي تحقق ذلك هي جداول التلميحات. وهي اثنان:
جدول تلميحات إزاحة الصفحات (Page Offset Hint Table): يُدرج لكل صفحة البايت الذي تبدأ عنده كائناتها وكم بايتاً تمتد. فحين يقفز المستخدم إلى الصفحة 147 ينظر العارض في هذا الجدول، ويحصل على معلومة «الصفحة 147 بين البايتين 8234100 و8291000»، فيطلب من الخادم ذلك النطاق وحده.
جدول تلميحات الكائنات المشتركة (Shared Object Hint Table): يُدرج الموارد التي تشترك فيها صفحات متعددة — كالخطوط المضمّنة المستخدمة عبر المستند، والشعار المتكرر في كل صفحة. فإن احتاجت الصفحة 147 إلى بعضها عرف العارض نطاقات بايتها من هنا أيضاً.
والنتيجة: يكفي تنزيل بضع مئات الكيلوبايتات لرؤية الصفحة 147 في ملف من 500 صفحة وبحجم 80 ميجابايت.
نطاقات البايت: الشرط في جانب الخادم
تقوم الآلية أعلاه على قدرة المتصفح على قول «أعطني البايتات بين 8234100 و8291000 من هذا الملف» للخادم. ويتم ذلك في HTTP عبر ترويسة Range، وينبغي أن يستجيب الخادم بـ 206 Partial Content.
وتدعم خوادم الويب الحديثة ذلك كلها تقريباً في الملفات الساكنة، وهو مفعّل افتراضياً عادةً. لكنه لا يعمل في الحالات التالية:
- إذا كان الملف يُولَّد ديناميكياً (أي إن كان خادم تطبيقات ينشئ ملف PDF لحظياً) فلا تُدعم نطاقات البايت عادةً.
- إذا كانت الاستجابة مضغوطة بـ gzip فقدت نطاقات البايت معناها. ولأن ملفات PDF مضغوطة داخلياً أصلاً، فتطبيق gzip عليها في الخادم لا لزوم له ويخلق هذه المشكلة.
- قد لا تمرّر بعض تهيئات CDN أو الوسيط (proxy) طلبات النطاقات.
فإن تحقق أحد هذه الشروط اضطر المتصفح إلى تنزيل الملف كاملاً حتى لو كان خطياً، وزالت الفائدة.
ما لا تغيّره الخطية
ينبغي توضيح هذه النقطة لأن ثمة سوء فهم شائعاً:
حجم الملف. فالخطية لا تُسقط أي محتوى ولا تعيد ترميز أي صورة. ولأن جداول التلميحات تُضاف، يكبر الملف نمطياً بنسبة 1–2%. وإن أردت التصغير فالضغط هو المطلوب.
جودة الصورة. فلا يتغير أي بكسل.
النص والخط والتخطيط. فلا يتأثر أي منها.
سرعة الفتح محلياً. فإن كان الملف على القرص أصلاً فلا أهمية للترتيب؛ ولا يُفتح الملف الخطي أسرع محلياً.
اللحظات التي تفسد فيها الخطية
قد يفقد الملف الخطي هذه الخاصية عند إجراء عمليات عليه:
كل عملية تجري تحديثاً تزايدياً تفسدها. فإضافة تعليق، وتعبئة حقل نموذج، ووضع توقيع رقمي — معظم هذه العمليات يضيف التغييرات إلى نهاية الملف. ويبقى الملف صالحاً لكن على العارض الآن أن ينظر في النهاية ليعرف الحالة الراهنة؛ فيسقط وعد الخطية.
والعمليات التي تعيد الكتابة كاملة تفسدها أيضاً: الضغط، وإضافة/حذف الصفحات، والدمج، والتقسيم. فهذه تنتج الملف من الصفر ولا يُصان الترتيب الخطي الخاص.
والنتيجة العملية: ينبغي أن تكون الخطية آخر خطوة في سير العمل. اضغط، وحرّر، ووقّع، وافعل ما تريد — ثم اجعل الملف خطياً وانشره في النهاية.
كيف يُتحقَّق من ذلك
أبسط طريقة لمعرفة ما إذا كان الملف خطياً هي النظر في بايتاته الأولى. فالكائن الأول في ملف PDF خطي يشبه هذا:
1 0 obj
<< /Linearized 1 /L 1247893 /O 6 /E 45231 /N 120 /T 1247100 >>
endobj
فالمفتاح /Linearized 1 دليل مباشر. و/N يعطي عدد الصفحات الكلي، و/L طول الملف، و/O رقم كائن الصفحة الأولى.
وللاختبار في ظروف واقعية، ارفع الملف إلى الخادم وافتحه في أدوات مطوّري المتصفح مع محاكاة اتصال بطيء. ففي الملف الخطي تظهر الصفحة الأولى قبل اكتمال التنزيل.
الخلاصة
يضع PDF جدول الإحالات المتقاطعة في نهاية الملف لإتاحة التحديث التزايدي؛ وهذا يعني انتظار الملف كاملاً عند القراءة عبر الشبكة. والخطية تقلب الترتيب: فيأتي كل ما يخص الصفحة الأولى في المقدمة، وتُضاف بعده جداول تلميحات تقول أين تقع كل صفحة. وبذلك تظهر الصفحة الأولى فوراً ويمكن القفز مباشرة إلى الصفحة المطلوبة — لكن ذلك يقتضي أن يدعم الخادم طلبات نطاقات البايت. ولا تصغّر العملية حجم الملف ولا تغيّر الجودة ولا تسرّع الفتح المحلي. وهي ذات معنى في الملفات الكبيرة المنشورة على الويب فقط، وينبغي تطبيقها كخطوة أخيرة لأنها تفسد إن أُجريت عملية أخرى على الملف.
الأسئلة الشائعة
لماذا يضطر العارض إلى النظر في نهاية الملف في ملف PDF عادي؟
لأن صيغة PDF تضع جدول الإحالات المتقاطعة (xref) — الذي يقول أين يقع كل كائن في الملف — في نهاية الملف. وهذا الاختيار التصميمي غايته إتاحة التحديث التزايدي: إذ تُضاف التغييرات الجديدة إلى النهاية ويُكتب جدول xref جديد، ولا يفسد القديم. وثمن ذلك الاضطرار إلى بدء القراءة من النهاية.
ماذا يحتوي جدول التلميحات (hint table) بالضبط؟
يوجد جدولان رئيسيان. جدول تلميحات إزاحة الصفحات يقول في أي نطاق بايت من الملف تقع كائنات كل صفحة. أما جدول تلميحات الكائنات المشتركة فيبيّن أين تقع الموارد التي تشترك فيها صفحات متعددة (الخطوط، والصور المتكررة). وينظر العارض في هذين الجدولين عند القفز إلى صفحة ما فيطلب نطاقات البايت اللازمة وحدها.
هل يُفتح الملف الخطي في العارضات العادية أيضاً؟
نعم، يُفتح تماماً. فالخطية جزء من المعيار، والملف الخطي هو في الوقت نفسه ملف PDF عادي صالح؛ إذ يوجد في نهايته جدول xref كذلك. والعارض الذي لا يفهم الخطية يقرأ الملف بالطريقة الكلاسيكية ولا يواجه أي مشكلة. فتضيع الفائدة لكن لا يختل التوافق.
لماذا يفسد التحديث التزايدي الخطية؟
لأن وعد الخطية الأساسي هو وجود كل ما يلزم لرسم الصفحة الأولى في مقدمة الملف. والتحديث التزايدي يضيف التغييرات إلى نهاية الملف ويكتب جدول xref جديداً؛ فيصير على العارض أن ينظر في النهاية ليعرف الحالة الراهنة. ويبقى الملف صالحاً لكن ضمانة العرض السريع على الويب تسقط.
جرّب ذلك الآن باستخدام Web İçin Optimize Et.
جرّب Web İçin Optimize Et