لقد قمت مؤخرًا بإنشاء نمط جدار من الطوب كجزء من بلدي # نماذج_صغيرة سلسلة ، تحدٍ حيث أقوم بإنشاء أنماط أو زخارف عضوية في SVG في حدود 560 بايت (أو حجم تغريدتين تقريبًا). لملاءمة هذا القيد ، مررت برحلة علمتني بعض الطرق الجذرية لتحسين أنماط SVG بحيث تحتوي على أقل قدر ممكن من التعليمات البرمجية دون التأثير على جودة الصورة الإجمالية.
أريد أن أطلعك على هذه العملية وأظهر لك كيف يمكننا أخذ نمط SVG يبدأ من 197 بايت وصولاً إلى 44 بايت فقط - تخفيض هائل بنسبة 77.7٪!
نمط SVG
هذا ما يسمى بنمط لبنة "السندات الجارية". إنه نمط القرميد الأكثر شيوعًا ، والذي رأيته بالتأكيد من قبل: كل صف من الطوب يقابله نصف طول الطوب ، مما يخلق نمطًا متكررًا متداخلاً. الترتيب بسيط جدًا ، مما يجعل SVG <pattern>
عنصر مناسب تمامًا لإعادة إنتاجه في الكود.
ملف SVG <pattern>
يستخدم العنصر كائنًا رسوميًا محددًا مسبقًا يمكن تكراره (أو "تجانبه") على فترات زمنية ثابتة على طول المحاور الأفقية والرأسية. بشكل أساسي ، نحدد نمط البلاط المستطيل ويتكرر لطلاء منطقة التعبئة.
أولاً ، دعنا نحدد أبعاد الطوب والفجوة بين كل لبنة. من أجل البساطة ، دعنا نستخدم أرقامًا مستديرة نظيفة: عرض 100
وارتفاع 30
لبنة و 10
للفجوات الأفقية والعمودية بينهما.
بعد ذلك ، علينا تحديد البلاط "الأساسي" الخاص بنا. وعن طريق "البلاط" ، أتحدث عن بلاط النمط بدلاً من البلاط المادي ، حتى لا يتم الخلط بينه وبين الطوب. دعنا نستخدم الجزء المظلل من الصورة أعلاه باعتباره بلاط النمط الخاص بنا: قالبان كاملان في الصف الأول ، وواحد كامل محصور بين نصفين من الطوب في الصف الثاني. لاحظ كيف وأين يتم تضمين الفجوات ، لأنه يجب تضمينها في تجانب النمط المتكرر.
عند استخدام <pattern>
، علينا تحديد النمط width
و height
، والتي تتوافق مع عرض وارتفاع البلاط الأساسي. للحصول على الأبعاد ، نحتاج إلى القليل من الرياضيات:
Tile Width = 2(Brick Width) + 2(Gap) = 2(100) + 2(10) = 220
Tile Height = 2(Bright Height) + 2(Gap) = 2(30) + 2(10) = 80
حسنًا ، لذلك بلاط النمط لدينا هو 220✕80
. علينا أيضًا ضبط ملف patternUnits
السمة حيث القيمة userSpaceOnUse
يعني في الأساس بكسل. أخيرًا ، إضافة ملف id
إلى النمط ضروري حتى يمكن الرجوع إليه عندما نرسم عنصرًا آخر به.
<pattern id="p" width="220" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
الآن بعد أن أنشأنا أبعاد التجانب ، يكمن التحدي في إنشاء رمز للتجانب بطريقة تجعل الرسم مع أقل عدد ممكن من البايتات. هذا ما نأمل أن ينتهي به الأمر في النهاية:
العلامات الأولية (197 بايت)
إن أبسط الطرق وأكثرها توضيحًا لإعادة إنشاء هذا النمط الذي يتبادر إلى ذهني هو رسم خمسة مستطيلات. بشكل افتراضي ، fill
لعنصر SVG باللون الأسود ويكون ملف stroke
شفاف. يعمل هذا بشكل جيد لتحسين أنماط SVG ، حيث لا يتعين علينا الإعلان صراحةً عن تلك الموجودة في الكود.
يحدد كل سطر في الكود أدناه مستطيلاً. ال width
و height
يتم تعيينها دائمًا ، و x
و y
يتم تعيين المواضع فقط إذا تم إزاحة المستطيل عن 0
.
<rect width="100" height="30"/>
<rect x="110" width="100" height="30"/>
<rect y="40" width="45" height="30"/>
<rect x="55" y="40" width="100" height="30"/>
<rect x="165" y="40" width="55" height="30"/>
احتوى الصف العلوي من البلاط على طوبتين بعرض كامل ، تم وضع الطوب الثاني عليه x="110"
السماح لل 10
بكسل من الفجوة قبل الطوب. وبالمثل هناك 10
بكسل من الفجوة بعد ، لأن الطوب ينتهي عند 210
بكسل (110 + 100 = 210
) على المحور الأفقي بالرغم من أن ملف <pattern>
العرض 220
بكسل. نحن بحاجة إلى هذا القليل من المساحة الإضافية ؛ وإلا فإن الطوب الثاني سوف يندمج مع اللبنة الأولى في البلاط المجاور.
يتم إزاحة الطوب في الصف الثاني (السفلي) بحيث يحتوي الصف على نصفين من الطوب وقطعة واحدة كاملة. في هذه الحالة ، نريد دمج الطوب نصف العرض بحيث لا توجد فجوة في البداية أو النهاية ، مما يسمح لهم بالتدفق بسلاسة مع الطوب في مربعات النقش المجاورة. عند موازنة هذه الطوب ، يتعين علينا أيضًا تضمين نصف فجوات ، وبالتالي فإن x
القيم هي 55
و 165
، على التوالي.
إعادة استخدام العنصر ، (-43 ب ، 154 ب إجمالي)
يبدو أنه من غير الفعال تحديد كل لبنة بشكل صريح. ألا توجد طريقة ما لتحسين أنماط SVG من خلال إعادة استخدام الأشكال بدلاً من ذلك؟
لا أعتقد أنه من المعروف على نطاق واسع أن SVG لديه امتداد <use>
جزء. يمكنك الرجوع إلى عنصر آخر وتقديم هذا العنصر المشار إليه في أي مكان <use>
يستخدم. يؤدي هذا إلى توفير عدد غير قليل من البايتات لأنه يمكننا حذف تحديد عروض وارتفاع كل لبنة ، باستثناء البايت الأول.
هكذا قال، <use>
يأتي بسعر قليل. وهذا يعني أنه يتعين علينا إضافة id
للعنصر الذي نريد إعادة استخدامه.
<rect id="b" width="100" height="30"/>
<use href="#b" x="110"/>
<use href="#b" x="-55" y="40"/>
<use href="#b" x="55" y="40"/>
<use href="#b" x="165" y="40"/>
الاقصر id
الممكن هو حرف واحد ، لذلك اخترت "ب" لبنة. ال <use>
يمكن وضع العنصر بشكل مشابه لـ <rect>
، مع x
و y
الصفات كتعويضات. نظرًا لأن كل لبنة كاملة العرض الآن وقد انتقلنا إليها <use>
(تذكر أننا قمنا بتقسيم الطوب إلى النصف في الصف الثاني من بلاطة النمط) ، علينا استخدام السالب x
القيمة في الصف الثاني ، ثم تأكد من تدفق آخر لبنة من البلاط لهذا الاتصال السلس بين الطوب. لا بأس بذلك ، لأن أي شيء يقع خارج بلاط النمط يتم قطعه تلقائيًا.
هل يمكنك اكتشاف بعض السلاسل المتكررة التي يمكن كتابتها بكفاءة أكبر؟ دعونا نعمل على هؤلاء بعد ذلك.
إعادة الكتابة إلى المسار (-54B ، إجمالي 100B)
<path>
هو على الأرجح أقوى عنصر في SVG. يمكنك رسم أي شكل تقريبًا بداخله "أوامر" d
ينسب. هناك 20 أمرًا متاحًا ، لكننا نحتاج فقط إلى أبسطها للمستطيلات.
هذا هو المكان الذي وصلت إليه مع ذلك:
<path d="M0 0h100v30h-100z M110 0h100v30h-100 M0 40h45v30h-45z M55 40h100v30h-100z M165 40h55v30h-55z"/>
أعلم ، أرقام وحروف غريبة للغاية! كلهم لهم معنى، بالطبع بكل تأكيد. إليك ما يحدث في هذه الحالة بالذات:
M{x} {y}
: ينتقل إلى نقطة بناءً على الإحداثيات.z
: يغلق المقطع الحالي.h{x}
: رسم خط أفقي من النقطة الحالية بطولx
في الاتجاه الذي تحدده علامةx
. أحرف صغيرةx
يشير إلى إحداثي نسبي.v{y}
: رسم خط عمودي من النقطة الحالية بطولy
في الاتجاه الذي تحدده علامةy
. أحرف صغيرةy
يشير إلى إحداثي نسبي.
هذا الترميز مقتضب أكثر من السابق (فواصل الأسطر والمسافة البيضاء للمسافة البادئة هي فقط لسهولة القراءة). مهلا ، لقد تمكنا من قطع نصف الحجم الأولي ، ووصلنا إلى 100 بايت. ومع ذلك ، هناك شيء ما يجعلني أشعر أن هذا قد يكون أصغر ...
مراجعة البلاط (-38 ب ، 62 ب إجمالي)
ألا يحتوي بلاط النمط لدينا على أجزاء متكررة؟ من الواضح أنه في الصف الأول يتكرر لبنة كاملة ، لكن ماذا عن الصف الثاني؟ من الصعب بعض الشيء أن نرى ذلك ، ولكن إذا قطعنا الطوب الأوسط إلى نصفين يصبح الأمر واضحًا.
حسنًا ، الطوب الأوسط ليس مقطوعًا إلى نصفين تمامًا. هناك تعويض طفيف لأنه يتعين علينا أيضًا حساب الفجوة. على أي حال ، وجدنا للتو نمطًا أبسط للبلاط الأساسي ، مما يعني وحدات بايت أقل! هذا يعني أيضًا أنه يتعين علينا خفض width
من نحن <pattern>
عنصر من 220 إلى 110.
<pattern id="p" width="110" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
لنرى الآن كيف يتم رسم البلاط المبسط <path>
:
<path d="M0 0h100v30h-100z M0 40h45v30h-45z M55 40h55v30h-55z"/>
تم تقليل الحجم إلى 62 بايت ، وهو بالفعل أقل من ثلث الحجم الأصلي! لكن لماذا تتوقف هنا عندما يكون هناك المزيد الذي يمكننا القيام به!
أوامر تقصير المسار (-9 ب ، 53 ب إجمالي)
يجدر التعمق أكثر في ملف <path>
عنصر لأنه يوفر المزيد من التلميحات لتحسين أنماط SVG. أحد المفاهيم الخاطئة التي مررت بها أثناء العمل <path>
يتعلق بكيفية عمل ملف fill
السمة يعمل. بعد أن لعبت كثيرًا مع MS Paint في طفولتي ، تعلمت أن أي شكل أريد ملؤه بلون خالص يجب إغلاقه ، أي ليس به نقاط مفتوحة. خلاف ذلك ، سوف يتسرب الطلاء من الشكل وينتشر فوق كل شيء.
في SVG ، هذا ليس صحيحًا. اسمحوا لي أن أقتبس المواصفات نفسه:
تملأ عملية التعبئة المسارات الفرعية المفتوحة عن طريق تنفيذ عملية التعبئة كما لو تمت إضافة أمر "closepath" إضافي إلى المسار لتوصيل النقطة الأخيرة من المسار الفرعي بالنقطة الأولى من المسار الفرعي.
هذا يعني أنه يمكننا حذف أوامر إغلاق المسار (z
) ، لأن المسارات الفرعية تعتبر مغلقة تلقائيًا عند ملؤها.
شيء آخر مفيد يجب معرفته حول أوامر المسار هو أنها تأتي بأحرف كبيرة وصغيرة. الأحرف الصغيرة تعني استخدام الإحداثيات النسبية ؛ تعني الأحرف الكبيرة استخدام الإحداثيات المطلقة بدلاً من ذلك.
إنه أصعب قليلاً من ذلك مع H
و V
الأوامر لأنها تتضمن إحداثيًا واحدًا فقط. إليك كيف يمكنني وصف هذين الأمرين:
H{x}
: يرسم خطًا أفقيًا من النقطة الحالية للتنسيقx
.V{y}
: يرسم خطًا رأسيًا من النقطة الحالية للتنسيقy
.
عندما نرسم اللبنة الأولى في بلاطة النمط ، نبدأ من (0,0)
إحداثيات. ثم نرسم خطًا أفقيًا إلى (100,0)
وخط عمودي ل (100,30)
، وأخيرًا ، ارسم خطًا أفقيًا لـ (0,30)
. استخدمنا ملف h-100
الأمر في السطر الأخير ، لكنه يعادل H0
، وهو اثنان بايت بدلاً من خمسة. يمكننا استبدال حالتين متشابهتين ونفصل كود <path>
وصولا الى هذا:
<path d="M0 0h100v30H0 M0 40h45v30H0 M55 40h55v30H55"/>
حلق 9 بايت أخرى - ما مقدار أصغر يمكن أن نذهب؟
التجسير (-5 مليار ، إجمالي 48 مليار)
أطول الأوامر التي تقف في طريقنا لنمط SVG المحسن بالكامل هي أوامر "الانتقال إلى" التي تستغرق 4 و 5 و 6 بايت على التوالي. أحد القيود التي نواجهها هو:
يجب أن يبدأ مقطع بيانات المسار (إن وجد) بأمر "moveto".
لكن لا مشكلة. الأول هو الأقصر على أي حال. إذا قمنا بتبديل الصفوف ، فيمكننا التوصل إلى تعريف مسار حيث يتعين علينا فقط التحرك إما أفقيًا أو رأسيًا بين الطوب. ماذا لو تمكنا من استخدام h
و v
أوامر هناك بدلا من M
?
يوضح الرسم البياني أعلاه كيف يمكن رسم الأشكال الثلاثة بمسار واحد. لاحظ أننا نستفيد من حقيقة أن ملف fill
تغلق العملية تلقائيًا الجزء المفتوح بينهما (110,0)
و (0,0)
. من خلال عملية إعادة الترتيب هذه ، قمنا أيضًا بتحريك الفجوة إلى يسار الطوب كامل العرض في الصف الثاني. إليك كيف يبدو الرمز ، لا يزال مقسمًا إلى لبنة واحدة في كل سطر:
<path d="M0 0v30h50V0 h10v30h50 v10H10v30h100V0"/>
بالتأكيد ، وجدنا الحل الأصغر المطلق الآن بعد أن انخفض حجمنا إلى 48 بايت ، أليس كذلك؟! نحن سوف…
تشذيب الأرقام (-4B ، إجمالي 44B)
إذا كان بإمكانك أن تكون مرنًا بعض الشيء مع الأبعاد ، فهناك طريقة أخرى صغيرة يمكننا من خلالها تحسين أنماط SVG. لقد عملنا بعرض طوبة يبلغ 100
بكسل ، ولكن هذا ثلاثة بايت. تغييرها إلى 90
يعني بايت واحدًا أقل كلما احتجنا إلى كتابته. وبالمثل ، استخدمنا فجوة 10
بكسل - ولكن إذا قمنا بتغييرها إلى 8
بدلاً من ذلك ، نقوم بحفظ بايت على كل من هذه التكرارات.
<path d="M0 0v30h45V0 h8v30h45 v8H8v30h90V0"/>
بالطبع ، هذا يعني أيضًا أنه يتعين علينا ضبط أبعاد النمط وفقًا لذلك. إليك رمز نمط SVG المحسّن النهائي:
<pattern id="p" width="98" height="76" patternUnits="userSpaceOnUse"> <path d="M0 0v30h45V0h8v30h45v8H8v30h90V0"/>
</pattern>
السطر الثاني في المقتطف أعلاه - بدون حساب المسافات البادئة - هو بايت 44. وصلنا هنا من 197 بايت في ست تكرارات. هذا مكتنزة 77.7٪ تصغير الحجم!
أتساءل بالرغم من ... هل هذا هو أصغر حجم ممكن حقًا؟ هل نظرنا في جميع الطرق الممكنة لتحسين أنماط SVG؟
أدعوك لمحاولة تصغير هذه الشفرة بشكل أكبر ، أو حتى تجربة طرق بديلة لتحسين أنماط SVG. أود أن أرى ما إذا كان بإمكاننا إيجاد الحد الأدنى العالمي الحقيقي بحكمة الجمهور!
المزيد عن إنشاء أنماط SVG وتحسينها
إذا كنت مهتمًا بمعرفة المزيد حول إنشاء أنماط SVG وتحسينها ، فاقرأ مقالتي حول إنشاء أنماط باستخدام مرشحات SVG. أو ، إذا كنت تريد الاطلاع على معرض يضم أكثر من 60 نمطًا ، فيمكنك عرض ملف مجموعة PetitePatterns CodePen. أخيرًا ، نرحب بالمشاهدة دروسي التعليمية على موقع يوتيوب لمساعدتك على التعمق في أنماط SVG.
تحسين أنماط SVG إلى أصغر حجم لها نشرت أصلا في حيل CSS. يجب احصل على النشرة الإخبارية.
- "
- 10
- 100
- 77
- 9
- 98
- من نحن
- مطلق
- حسابي
- إضافي
- الكل
- السماح
- سابقا
- آخر
- نهج
- المنطقة
- البند
- سمات
- متاح
- محاور
- قطعة
- اسود
- تحدى
- تغيير
- صندوق توظيف برأس مال محدود
- الكود
- مشترك
- صلة
- يحتوي
- محتوى
- رابطة
- استطاع
- خلق
- حالياًّ
- البيانات
- أعمق
- إلى أسفل
- ينتهي
- أنشئ
- كل شىء
- مثال
- إلا
- تجربة
- أخيرا
- الاسم الأول
- تناسب
- تدفق
- وجدت
- إضافي
- فجوة
- الحصول على
- العالمية
- وجود
- ارتفاع
- مساعدة
- هنا
- سلط الضوء
- كيفية
- HTTPS
- تحديد
- صورة
- تتضمن
- شامل
- IT
- نفسها
- معروف
- تسرب
- تعلم
- تعلم
- الاستفادة من
- خط
- القليل
- بدا
- حب
- يصنع
- القيام ب
- تمكن
- الرياضيات
- مانع
- الأكثر من ذلك
- أكثر
- خطوة
- MS
- عدد
- أرقام
- عوض
- حسنا
- جاكيت
- الأمثل
- وإلا
- نمط
- مادي
- البوينت
- وضع
- ممكن
- قوي
- جميل
- السعر
- عملية المعالجة
- ويوفر
- جودة
- دائري
- تشغيل
- قال
- سلس
- مسلسلات
- طقم
- الأشكال
- مماثل
- الاشارات
- SIX
- مقاس
- So
- حل
- شيء
- الفضاء
- بقعة
- بداية
- يبدأ
- مدعومة
- الحديث
- عبر
- تيشرت
- شفاف
- الدروس
- تستخدم
- قيمنا
- المزيد
- W3
- شاهد
- ترحيب
- ابحث عن
- في غضون
- بدون
- للعمل
- عامل
- أعمال
- قيمة
- موقع YouTube