الارتقاء بتطبيقات PixiJS إلى المستوى التالي باستخدام الاستراتيجيات والتقنيات المتقدمة
يتناول هذا المنشور الطرق المختلفة التي يمكن من خلالها تحسين عرض عناصر متعددة داخل pixiJS بشكل أفضل من حيث وحدة المعالجة المركزية / الذاكرة. على سبيل المثال، مع الأخذ في الاعتبار الفرق بين إعادة عرض كل إطار دون أي تخزين مؤقت - وهو ما يؤدي أداءً جيدًا من حيث استخدام وحدة المعالجة المركزية - أو التخزين المؤقت للرسومات المعروضة في الذاكرة. سيؤدي هذا إلى زيادة استخدام الذاكرة بما يتناسب مع عدد الرسومات في المشهد.
هناك عدد من الاستراتيجيات للتعامل مع مثل هذه التحسينات. تجدر الإشارة بشكل خاص إلى التصميم الموجه نحو البيانات، والذي يقدم مجموعة بديلة جذريًا من الأساليب من طريقة البرمجة الشيئية الأكثر شيوعًا تقليديًا.
تتضمن الطرق الرئيسية الأخرى ما يلي: اختيار واستخدام تنسيقات أكثر تنظيماً - NativeArrays في C# وTypedArrays في TypeScript، على سبيل المثال. سيسمح ذلك بإدارة أكبر بكثير للمخازن المؤقتة للذاكرة، مما قد يحد من أخطاء ذاكرة التخزين المؤقت، ولكنها تحتاج أيضًا إلى خبرة هندسية كبيرة و/أو تخصيص.
في هذا المنشور، سأركز على طريقة عمل واحدة لتحسين بيئة WebGL باستخدام PixiJS: النهج الموجه للكائنات، بما في ذلك أفضل الممارسات. سيوفر لك هذا وسيلة جيدة التنظيم لزيادة السرعة والكفاءة في تطبيقات PixiJS الخاصة بك.
في مقالتي القادمة، سأتحدث عن نهج تحسين قوي آخر: نهج نظام المكونات. يعتمد نهج ECS على البيانات بشكل لافت للنظر ويقدم نظرة جديدة عندما يتعلق الأمر بتحسين PixiJS في البيئات عالية الأداء. تابع على موقع Medium للحصول على هذه المقالة، حيث أتناول بالتفصيل التفاصيل الجوهرية لنهج ECS.
تذكر دائمًا أن هناك دائمًا شيء يمكن القيام به بشكل أفضل في محاولة لتحسين أداء تطبيق Pixi الخاص بك وتعزيزه. بالأفضل، لا يعني ذلك أنه الأكثر تحسينًا أو الأسرع. الحل الأفضل هو مسألة المفاضلة بين مقدار الوقت الذي تستثمره في التحسين والعائد على هذا الاستثمار للتأكد من قدرتك على الوفاء بالمواعيد النهائية للمشروع ولكن مع تحسين كافٍ لإرضاء أي مستخدمين محتملين دون الإفراط في توسيع مواردك.
في هذا القسم، سأقوم بإرشادك عبر أفضل الطرق لتحسين تطبيقات PixiJS.
يعتمد هذا القسم على نصائح رسمية، تستحق المراجعة!
ستدور بقية مناقشتنا حول Pixi Graphics وSprites وMeches ومتى يتم استخدام حاوية الجسيمات بدلاً من حاوية Pixi الافتراضية. يجب أن يمنحك هذا الفصل رؤية واضحة لكيفية استخدام كل شيء على النحو الأمثل في سياق كائني التوجه حتى تكون مشاريع PixiJS الخاصة بك فعالة ويتم تقديمها بأكبر قدر من الكفاءة.
من أجل استخدام رسومات Pixi بشكل فعال، نحتاج إلى فهم كيفية عملها داخليًا. فلنبدأ بعرض مثال أساسي جدًا لإنشاء كائن رسومي في Pixi:
const graphics = new PIXI.Graphics(); graphics.beginFill(0xff0000); graphics.drawRect(0, 0, 200, 100); graphics.endFill();
لكن المهم في هذا التنفيذ البسيط هو ما يحدث "تحت الغطاء". عند إنشاء هذا النوع من الرسوم، تقوم Pixi بإنشاء شيء يسمى كائن GraphicsGeometry. يأخذ هذا الكائن الشكل والحجم بناءً على الأبعاد والخصائص التي تحددها للشكل الذي ترسمه. يتم بعد ذلك تخزين كائن الهندسة النهائي داخل قائمة GeometryList داخل كائن الرسومات.
لاحظ أنه في كل مرة تقوم فيها برسم شيء ما بمساعدة PIXI.Graphics، يتم تحديث GeometryList. في بعض الأحيان، تريد فقط مسح هذه القائمة، ولكن في الوقت نفسه تبقي كائن الرسومات الخاص بك على قيد الحياة - وهنا يأتي دور طريقة .clear(). إن معرفة كيفية عمل هذه العملية سيساعدك بشكل كبير عند استخدام Pixi، لأنه يؤثر بشكل مباشر على كيفية تعامل Pixi مع الرسومات وعرضها في تطبيقك.
دعونا نستكشف إستراتيجيات التحسين من خلال حالة استخدام لإنشاء 100 كائن رسومي في PixiJS.
function createGraphics(x, y) { const graphic = new PIXI.Graphics(); graphic.beginFill(0xDE3249); graphic.drawCircle(x, y, 10); graphic.endFill(); return graphic; } for (let i = 0; iفي هذا السيناريو، إذا كانت جميع الكائنات الرسومية المائة تشترك في نفس العرض والارتفاع، فيمكننا التحسين من خلال إعادة استخدام الشكل الهندسي.
تمرير هندسة الرسومات كمرجع
إنشاء شكل هندسي واحد لدائرة وإعادة استخدامه:
// Create a single geometry for a circle const circleGeometry = new PIXI.Graphics(); circleGeometry.beginFill(0xDE3249); circleGeometry.drawCircle(0, 0, 10); // Draw a circle at the origin circleGeometry.endFill(); // Function to create a graphic using the circle geometry function createCircle(x, y) { const circle = new PIXI.Graphics(circleGeometry.geometry); circle.x = x; circle.y = y; return circle; } // Create 100 circles using the same geometry for (let i = 0; iتعمل هذه الطريقة على تقليل استخدام الذاكرة بشكل كبير من خلال الرجوع إلى نفس الشكل الهندسي بدلاً من تكراره لكل كائن.
ارسم كائنًا رسوميًا الكل في واحد
بالنسبة للرسومات الثابتة أو الهياكل المعقدة، يعد رسم جميع العناصر في كائن رسومي واحد أسلوبًا آخر للتحسين:
const graphics = new PIXI.Graphics(); // Draw 100 circles using the same PIXI.Graphics instance for (let i = 0; iفي هذا الأسلوب، بدلاً من إنشاء كائنات رسومية جديدة، نضيف أشكالًا هندسية جديدة إلى GeometryList لمثيل رسومات واحد. هذه الطريقة فعالة بشكل خاص للهياكل الرسومية الأكثر تعقيدًا.
الاستفادة من قوة CacheAsBitmap في PixiJS
إحدى أقوى الميزات في PixiJS هي CacheAsBitmap. بشكل أساسي، فهو يتيح للمحرك التعامل مع الرسومات مثل النقوش المتحركة. يمكن أن يؤدي ذلك إلى رفع الأداء بشكل كبير في بعض الحالات.
استخدم CacheAsBitmap فقط إذا لم يتم تحديث الكائن كثيرًا.
يمكن تخزين مجموعة كبيرة من الرسومات مؤقتًا كصورة نقطية في الحاوية. بدلاً من إعادة عرض 100 رسم، سيأخذ pixi لقطة ويعرضها مسبقًا كصورة نقطية.
ضع في اعتبارك دائمًا استخدام الذاكرة، فالصور النقطية المخزنة مؤقتًا تستخدم قدرًا كبيرًا من الذاكرة.
ينبغي للمرء استخدام ذاكرة التخزين المؤقت AsBitmap بحكمة. سيكون أكثر فعالية عند تطبيقه على الكائنات التي نادرًا ما تحتاج إلى التحديث. على سبيل المثال، إذا كان لدى أحد الأشخاص آلاف من وحدات تخزين الرسومات الثابتة أو التي تحتوي على تغيير نادر فقط، فإن تخزينها مؤقتًا كصورة نقطية يقلل بشكل جذري من عبء العرض.
بدلاً من إعادة عرض 100 رسم فردي، يمكن لـ PixiJS التقاط "لقطة" منها وتقديمها كصورة نقطية واحدة. هذه هي الطريقة التي يمكنك تنفيذها:
const graphicsContainer = new PIXI.Container(); // Add your graphics to the container // ... // Cache the entire container as a bitmap graphicsContainer.cacheAsBitmap = true;
ومع ذلك، من المهم الانتباه إلى استخدام الذاكرة. يمكن أن تستهلك الصور النقطية المخزنة مؤقتًا قدرًا كبيرًا من الذاكرة. لذلك، على الرغم من أن ذاكرة التخزين المؤقت asBitmap يمكنها تقليل حمل العرض بشكل كبير، إلا أنها يتم استبدالها باستخدام المزيد من الذاكرة. يجب دراسة هذه المقايضة بعناية بناءً على الاحتياجات والقيود المحددة لتطبيقك.
باختصار، تعد ذاكرة التخزين المؤقت كصورة Bitmap أداة فعالة لتحسين الأداء في PixiJS، خاصة بالنسبة للرسومات الثابتة أو التي نادرًا ما يتم تحديثها. إنه يبسط العرض من خلال التعامل مع الرسومات المعقدة كصور نقطية واحدة، ولكن من الضروري موازنة ذلك مع آثار بصمة الذاكرة.
عندما يتعلق الأمر بكفاءة الذاكرة في PixiJS، فإن النقوش المتحركة عمومًا لها اليد العليا على الرسومات. يكون هذا واضحًا بشكل خاص عند التعامل مع كائنات متعددة تشترك في نفس الشكل أو الملمس. دعونا نعيد النظر في مثال إنشاء رسم 100 دائرة، ولكن هذه المرة باستخدام النقوش المتحركة.
أولاً، نقوم بإنشاء نسيج من هندسة رسم دائرة واحدة:
const circleGraphic = new PIXI.Graphics(); circleGraphic.beginFill(0xDE3249); circleGraphic.drawCircle(0, 0, 10); circleGraphic.endFill(); // Generate a texture from the graphic const circleTexture = app.renderer.generateTexture(circleGraphic); Next, we use this texture to create sprites: // Function to create a sprite using the circle texture function createCircleSprite(x, y) { const sprite = new PIXI.Sprite(circleTexture); sprite.x = x; sprite.y = y; return sprite; } // Create and add 100 circle sprites to the stage for (let i = 0; iفي هذا الأسلوب، بدلاً من إعادة عرض الرسومات وإدارة قائمة الأشكال الهندسية المتزايدة لكل كائن، نقوم بإنشاء نسيج واحد وإعادة استخدامه عبر العديد من النقوش المتحركة. وهذا يقلل بشكل كبير من تحميل العرض واستخدام الذاكرة.
القيود والحلول الإبداعية
أحد قيود هذه الطريقة هو أنك مقيد بالأنسجة التي قمت بإنشائها. ومع ذلك، هنا يصبح الإبداع هو المفتاح. يمكنك إنشاء أنسجة ذات أشكال مختلفة باستخدام PIXI.Graphics وتطبيقها على Sprites. الأسلوب الفعال بشكل خاص هو إنشاء مادة أساسية، مثل صورة نقطية بحجم 1 × 1 بكسل، وإعادة استخدامها لجميع النقوش المتحركة المستطيلة. من خلال تغيير حجم الكائن إلى أبعاد مختلفة، يمكنك الاستفادة من نفس البنية الأساسية عبر العديد من الكائنات دون تكرار.
على سبيل المثال:// This creates a 16x16 white texture const baseTexture = PIXI.Texture.WHITE; // Use this baseTexture for all rectangular shapes const sprite= new PIXI.Sprite(baseTexture); sprite.tint = 0xDE3249; // Set the sprite color sprite.position.set(x, y); sprite.width = width; sprite.height = height;باستخدام هذه الطريقة، يتيح لك .tint() تلوين الكائن دون تشغيل إعادة عرض كاملة، حيث يتم تطبيق الصبغة كتأثير تظليل إضافي مباشرة على وحدة معالجة الرسومات.
استخدام 100 ألف سبرايت في حاوية الجسيمات
لتوضيح قوة هذه التقنية، تخيل تشغيل 100000 كائن فردي مع صبغات عشوائية، كل منها يتحول في كل إطار، كل ذلك مع الحفاظ على 60 إطارًا في الثانية بسلاسة.
لمزيد من القراءة حول تحسين PixiJS، أوصي بشدة بمقالة ثاقبة كتبها أحد المبدعين الأصليين لـ PixiJS، والتي تتعمق في تقنية renderTexture.
تجده هنا
رائع! إذا كنت قد وصلت إلى هذا الحد، أود أن أشكرك بشدة على بقاءك معي خلال هذا البحث العميق في تحسين PixiJS. أتمنى أن تجد الأفكار والتقنيات التي تمت مشاركتها هنا ذات قيمة لمشاريعك. ترقب مقالتي التالية، حيث سأستكشف نهج نظام المكونات (ECS) وقوة NativeArrays بمزيد من التفصيل. ستأخذ هذه الطرق تطبيقات PixiJS الخاصة بك إلى آفاق جديدة في الأداء والكفاءة. شكرا على القراءة، ونراكم في الحلقة القادمة!
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3