หน้านี้อธิบายปัญหาประสิทธิภาพทั่วไปและการปฏิบัติที่ดีที่สุดสำหรับการบรรเทาพวกเขา
การคำนวณสคริปต์
การดำเนินการที่แพงในรหัส Luau ใช้เวลาในการประมวลผลนานขึ้นและจึงสามารถส่งผลต่ออัตราเฟรมได้เว้นแต่จะถูกดำเนินการแบบพาราเลล โค้ด Luau จะทำงานอย่างสะสมและบล็อกกระทู้หลักจนกว่าจะพบฟังก์ชันที่ให้กระทู้ จนกว่าจะพบฟังก์ชันที่ให้กระทู้
ปัญหาทั่วไป
การดำเนินการอย่างหนักในโครงสร้างตาราง - การดำเนินการที่ซับซ้อนเช่นการเซริฟิเคชันการถอดรหัสและการโคลนลึกมีค่าใช้จ่ายด้านประสิทธิภาพสูง โดยเฉพาะอย่างยิ่งในโครงสร้างตารางขนาดใหญ่เป็นจริงโดยเฉพาะอย่างยิ่งถ้าการดำเนินการเหล่านี้เป็นการเรียกซ้ำหรือรวมถึงการเรียกผ่านโครงสร้างข้อมูลขนาดใหญ่มาก
อีเวนต์ความถี่สูง - ผูกการดำเนินการแพงไปยังอีเวนต์ขอบเฟรมของ RunService โดยไม่ จํากัด ความถี่หมายความว่าการดำเนินการเหล่านี้จะถูกทําซ้ําในแต่ละเฟรมซึ่งมักจะทําให้เกิดการเพิ่มขึ้นที่ไม่จําเป็นในเวลาการคํานวณอีเวนต์เหล่านี้รวมถึง:
การบรรเทา
- เรียกร้องโค้ดในกิจกรรม RunService อย่างประหยัด จํากัดการใช้งานเฉพาะกรณีที่การเรียกใช้บ่อยครั้งเป็นสิ่งจําเป็น (ตัวอย่างเช่น การอัปเดตกล้อง)คุณสามารถดําเนินโค้ดอื่น ๆ ส่วนใหญ่ในอีเวนต์อื่นหรือบ่อยน้อยในลูป
- แยกภารกิจขนาดใหญ่หรือราคาแพงโดยใช้ task.wait() เพื่อกระจายงานไปทั่วหลายกรอบ
- ระบุและเพิ่มประสิทธิภาพการดำเนินการที่มีราคาแพงโดยไม่จำเป็นและใช้ multithreading สำหรับภารกิจที่มีราคาแพงในการคำนวณที่ไม่จำเป็นต้องเข้าถึงโมเดลข้อมูล
- สคริปต์บางตัวบนเซิร์ฟเวอร์สามารถได้รับประโยชน์จาก การสร้างโค้ดเดิม ซึ่งเป็นธงง่ายๆ ที่รวบรวมสคริปต์เป็นโค้ดแมชชีนแทนโค้ดไบต์
ขอบเขตของ MicroProfiler
ขอบเขต | การคำนวณที่เกี่ยวข้อง |
RunService.PreRender (การดำเนินการก่อนที่จะเรนเดอร์) | รหัสดำเนินการในอีเวนต์ PreRender |
RunService.PreSimulation สิ่งที่เกิดขึ้นก่อนการจำลอง | รหัสดำเนินการบนอีเวนต์ Stepped |
ทำงานบริการ RunService.PostSimulation | รหัสดำเนินการบนอีเวนต์ Heartbeat |
การดำเนินการบริการ.Heartbeat | รหัสดำเนินการบนอีเวนต์ Heartbeat |
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการแก้ไขข้อผิดพลาดของสคริปต์โดยใช้ MicroProfiler ดูที่ห้องสมุด debug ซึ่งรวมฟังก์ชันสำหรับการทำเครื่องหมายโค้ดเฉพาะและเพิ่มความเฉพาะเจาะจงมากขึ้นเช่น debug.profilebegin และ debug.profileendหลายวิธี API ของ Roblox ที่เรียกโดยสคริปต์ยังมีแท็ก MicroProfiler ที่เกี่ยวข้องของตนเองที่สามารถให้สัญญาณที่มีประโยชน์ได้
การใช้หน่วยความจำของสคริปต์
การรั่วไหลของหน่วยความจําสามารถเกิดขึ้นเมื่อคุณเขียนสคริปต์ที่ใช้หน่วยความจําที่คัดลอกขยะไม่สามารถปล่อยได้อย่างถูกต้องเมื่อไม่ได้ใช้งานอีกต่อไปการรั่วไหลมีอยู่อย่างแพร่หลายบนเซิร์ฟเวอร์โดยเฉพาะเพราะพวกเขาสามารถออนไลน์ได้อย่างต่อเนื่องเป็นเวลาหลายวันในขณะที่เซสชันของไคลเอนต์สั้นมาก
ค่าหน่วยความจําต่อไปนี้ใน คอนโซลนักพัฒนา สามารถบ่งบอกถึงปัญหาที่ต้องการการตรวจสอบเพิ่มเติม:
- LuaHeap - การบริโภคสูงหรือเพิ่มขึ้นแนะนำการรั่วไหลของหน่วยความจำ
- จํานวนตัวอย่าง - เพิ่มจํานวนตัวอย่างอย่างต่อเนื่องแสดงให้เห็นว่าการอ้างอิงถึงบางตัวอย่างในโค้ดของคุณไม่ถูกเก็บขยะอย่างต่อเนื่อง
- หน่วยความจําสคริปต์สถานที่ - ให้สคริปต์โดยการแยกวิเคราะห์การใช้หน่วยความจําของสคริปต์
ปัญหาทั่วไป
ออกการเชื่อมต่อที่เชื่อมต่ออยู่ - เครื่องยนต์ไม่เคยรวบรวมขยะอีเวนต์ที่เชื่อมโยงกับตัวอย่างและค่าใดๆ ที่อ้างอิงภายในคอลเลกชันการโทรกลับที่เชื่อมต่อดังนั้นการเชื่อมต่อที่ใช้งานของเหตุการณ์และโค้ดภายในตัวอย่างที่เชื่อมต่อฟังก์ชันที่เชื่อมต่อ และค่าที่อ้างอิง ออกจากขอบเขตของตัวรวบรวมขยะหน่วยความจำแม้หลังจากที่เหตุการณ์ถูกยิง
แม้ว่าเหตุการณ์จะถูกตัดการเชื่อมต่อเมื่อตัวอย่างที่พวกเขาเป็นส่วนหนึ่งถูกทําลาย แต่ข้อผิดพลาดทั่วไปคือการเชื่อว่าสิ่งนี้ใช้กับวัตถุ Playerหลังจากที่ผู้ใช้ออกจากประสบการณ์แล้ว เครื่องยนต์จะไม่ทําลายวัตถุและโมเดลตัวละครที่เป็นตัวแทนของพวกเขาโดยอัตโนมัติ Player และโมเดลตัวละครและตัวละคร เช่น Player ซึ่งอยู่ภายใต้โมเดลตัวละคร เช่น Player.CharacterAdded จะยังคงใช้หน่วยความจําหากคุณไม่แยกพวกเขาในสคริปต์ของคุณอาจทำให้เกิดการรั่วไหลหน่วยความจําอย่างมากในระยะเวลาที่เซิร์ฟเวอร์มีผู้ใช้หลายร้อยคนเข้าร่วมและออกจากประสบการณ์
ตาราง - การสอดอันตรายเข้าไปในตาราง แต่ไม่ลบพวกมันเมื่อไม่จำเป็นอีกต่อไปทำให้เกิดการใช้หน่วยความจำที่ไม่จำเป็น โดยเฉพาะอย่างยิ่งสำหรับตารางที่ติดตามข้อมูลผู้ใช้เมื่อพวกมันเข้าร่วมตัวอย่างโค้ดต่อไปนี้สร้างตารางเพิ่มข้อมูลผู้ใช้ทุกครั้งที่ผู้ใช้เข้าร่วม:
ตัวอย่างlocal playerInfo = {}Players.PlayerAdded:Connect(function(player)playerInfo[player] = {} -- ข้อมูลบางอย่างend)หากคุณไม่ลบรายการเหล่านี้เมื่อไม่จำเป็นอีกต่อไป ตารางจะยังคงเติบโตในขนาดและใช้ทรัพยากรหน่วยความจำมากขึ้นเมื่อผู้ใช้รายอื่นเข้าร่วมเซสชันรหัสใดๆ ที่ซ้ำซากบนตารางนี้ยังกลายเป็นราคาแพงมากขึ้นเมื่อตารางเติบโตขนาดใหญ่ขึ้น
การบรรเทา
เพื่อล้างค่าที่ใช้ทั้งหมดเพื่อป้องกันการรั่วไหลของหน่วยความจํา:
ตัดการเชื่อมต่อทั้งหมด - ผ่านฐานคอดของคุณตรวจสอบให้แน่ใจว่าแต่ละการเชื่อมต่อถูกล้างออกผ่านหนึ่งในเส้นทางต่อไปนี้:
- การตัดการเชื่อมต่อด้วยตนเองโดยใช้ฟังก์ชัน Disconnect()
- การทําลายตัวอย่างที่เหตุการณ์นั้นเป็นส่วนหนึ่งด้วยฟังก์ชัน Destroy()
- ทำลายวัตถุสคริปที่เชื่อมโยงกลับไป
ลบวัตถุและตัวละครผู้เล่นหลังจากออก - ใช้รหัสเพื่อให้แน่ใจว่าการเชื่อมต่อไม่ยังคงอยู่หลังจากที่ผู้ใช้ออกไป, เช่นในตัวอย่างต่อไปนี้:
ตัวอย่างPlayers.PlayerAdded:Connect(function(player)player.CharacterRemoving:Connect(function(character)task.defer(character.Destroy, character)end)end)Players.PlayerRemoving:Connect(function(player)task.defer(player.Destroy, player)end)
การคำนวณฟิสิกส์
การจำลองฟิสิกส์ที่มากเกินไปอาจเป็นสาเหตุสําคัญของเวลาการคํานวณที่เพิ่มขึ้นต่อเฟรมทั้งบนเซิร์ฟเวอร์และไคลเอนต์
ปัญหาทั่วไป
ความถี่ขั้นตอนทางกายภาพที่มากเกินไป - โดยปกติแล้ว การก้าวจะอยู่ในโหมด "adaptive" ซึ่งก้าวฟิสิกส์ที่ 60 Hz, 120 Hz หรือ 240 Hz ขึ้นอยู่กับความซับซ้อนของเมคานิกส์ทางกายภาพ
โหมดคงที่ที่มีความแม่นยำของฟิสิกส์ที่ดีขึ้นยังมีอยู่เช่นกันซึ่งบังคับให้ทุกชิ้นส่วนฟิสิกส์เดินที่ความถี่ 240 Hz (สี่ครั้งต่อเฟรม)ผลลัพธ์นี้ทำให้การคำนวณเพิ่มขึ้นอย่างมากในแต่ละเฟรม
จํานวนความซับซ้อนของวัตถุจําลองเกินไป - ยิ่งมีการประกอบ 3D มากขึ้นที่จะถูกจําลอง การคํานวณทางฟิสิกส์ก็จะใช้เวลานานขึ้นในแต่ละเฟรมบ่อยครั้งที่ประสบการณ์จะมีวัตถุที่ถูกจำลองที่ไม่จำเป็นต้องเป็นหรือจะมีเครื่องมือที่มีข้อจำกัดและข้อต่อมากกว่าที่พวกเขาต้องการ
การตรวจจับการชนที่แม่นยําเกินไป - ชิ้นส่วนเมชมีคุณสมบัติ CollisionFidelity สําหรับการตรวจจับการชนซึ่งมีหลายโหมดที่มีผลกระทบต่อประสิทธิภาพที่แตกต่างกันโหมดการตรวจจับการชนที่แม่นยําสําหรับชิ้นส่วนเมชมีค่าใช้จ่ายในการทํางานแพงที่สุดและใช้เวลานานกว่าที่จะคํานวณเครื่องยนต์
การบรรเทา
ชิ้นส่วนที่ไม่ต้องการการจำลอง - ยึดชิ้นส่วนทั้งหมดที่ไม่จำเป็นต้องขับเคลื่อนโดยฟิสิกส์ เช่น สำหรับ NPC คงที่
ใช้การก้าวทางกายภาพแบบปรับได้ - การก้าวทางกายภาพที่ปรับได้จะปรับอัตราการคำนวณฟิสิกส์สำหรับฟิสิกส์ในรูปแบบต่างๆ โดยอัตโนมัติ ทำให้สามารถทำการอัปเดตฟิสิกส์ได้บ่อยน้อยลงในบางกรณี
ลดความซับซ้อนของเครื่องมือ * หากเป็นไปได้ ลดจํานวนข้อจํากัดทางฟิสิกส์หรือข้อต่อในการประกอบให้น้อยที่สุด
- ลดปริมาณการชนกันของตัวเองภายในเครื่องจักร เช่น โดยการใช้ข้อจํากัดหรือข้อจํากัดการไม่ชนกันกับส่วนของรากดอลล์เพื่อป้องกันไม่ให้พวกเขาชนกัน
ลดการใช้ความถูกต้องของการชนกันอย่างแม่นยําสําหรับเมช * สำหรับวัตถุขนาดเล็กหรือไม่สามารถโต้ตอบได้ซึ่งผู้ใช้จะแทบไม่สังเกตเห็นความแตกต่าง ให้ใช้ความซื่อสัตย์ของกล่อง
สำหรับวัตถุขนาดเล็กถึงขนาดกลางใช้ความซื่อสัตย์ของกล่องหรือเรือโดยขึ้นอยู่กับรูปร่าง
สำหรับวัตถุขนาดใหญ่และซับซ้อนมาก ให้สร้างการชนกันแบบกำหนดเองโดยใช้ชิ้นส่วนที่มองไม่เห็นเมื่อเป็นไปได้
สำหรับวัตถุที่ไม่ต้องการการชนกัน ให้ปิดการชนกันและใช้ความจงรักภาพของกล่องหรือเรือ เนื่องจากภาคการชนกันยังคงถูกเก็บไว้ในหน่วยความจำ
คุณสามารถเรนเดอร์คอลลิเดนซ์เพื่อวัตถุประสงค์ในการดีบักใน Studio โดยสลับเปิดใช้งาน ความถูกต้องของการชน จากวิดเจ็ต ตัวเลือกการแสดงผล ในมุมขวาบนของหน้าต่าง 3D มุมมอง
หรือคุณสามารถใช้ตัวกรอง CollisionFidelity=PreciseConvexDecomposition กับ Explorer ซึ่งแสดงจํานวนชิ้นส่วนเมชทั้งหมดที่มีความถูกต้องแม่นยําและช่วยให้คุณสามารถเลือกได้อย่างง่ายดาย
สำหรับการสำรวจอย่างละเอียดเกี่ยวกับวิธีการเลือกตัวเลือกความน่าเชื่อถือของการชนกันที่สมดุลความต้องการด้านความแม่นยําและประสิทธิภาพของคุณ ดู ตั้งพารามิเตอร์ฟิสิกส์และการเรนเดอร์ริ่ง
ขอบเขตของ MicroProfiler
ขอบเขต | การคำนวณที่เกี่ยวข้อง |
การกระโดดทางกายภาพ | การคำนวณฟิสิกส์โดยรวม |
ขั้นตอนโลก | ขั้นตอนฟิสิกส์เฉพาะที่ใช้ในแต่ละเฟรม |
การใช้หน่วยความจําทางกายภาพ
การเคลื่อนที่และการตรวจจับการชนกันของฟิสิกส์ใช้หน่วยความจำชิ้นส่วนเมชมีคุณสมบัติ CollisionFidelity ที่กำหนดวิธีการที่ใช้ในการประเมินขอบเขตการชนของเมช
ปัญหาทั่วไป
โหมดการตรวจจับการชนที่เริ่มต้นและแม่นยําใช้ความทรงจํามากกว่าสองโหมดอื่นที่มีรูปแบบการชนที่มีความถูกต้องน้อยกว่า
หากคุณเห็นระดับการใช้หน่วยความจําสูงภายใต้ PhysicsParts คุณอาจต้องสํารวจการลดความน่าเชื่อถือในการชนกันของวัตถุในประสบการณ์ของคุณ
วิธีการลดผลกระทบ
เพื่อลดความทรงจำที่ใช้สำหรับความน่าเชื่อถือในการชนกัน:
- สำหรับชิ้นส่วนที่ไม่ต้องการการชนกัน ให้ปิดการชนกันโดยการตั้ง BasePart.CanCollide , BasePart.CanTouch และ BasePart.CanQuery เป็น false
- ลดความจงรักภักดีของการชนกันโดยใช้การตั้งค่า Class.MeshPart.CollisionFidelity|CollisionFidelity``Enum.CollisionFidelity.Box|Box มีภาระหน่วยความจำต่ำสุด และ Default และ Precise มักจะแพงกว่า
- โดยทั่วไปเป็นความปลอดภัยที่จะตั้งความน่าเชื่อถือในการชนกันของชิ้นส่วนที่ติดตั้งขนาดเล็กใดๆ เป็น Box
- สำหรับเมชที่ซับซ้อนมากๆ ขนาดใหญ่ คุณอาจต้องการสร้างเมชการชนกันของคุณเองจากวัตถุขนาดเล็กที่มีความน่าเชื่อถือในการชนกล่อง
มนุษย์โนอิด
Humanoid เป็นคลาสที่ให้ฟังก์ชันหลากหลายแก่ตัวละครผู้เล่นและตัวละครที่ไม่ใช่ผู้เล่น (NPCs)แม้ว่าจะมีประสิทธิภาพ แต่ Humanoid มาพร้อมกับค่าใช้จ่ายในการคำนวณที่สำคัญ
ปัญหาทั่วไป
- ปิดใช้งานทั้งหมด HumanoidStateTypes บน NPCs - มีค่าใช้จ่ายด้านประสิทธิภาพในการปิดใช้งานบางส่วน HumanoidStateTypes ที่เปิดใช้งานปิดใช้งานใดๆ ที่ไม่จำเป็นสำหรับ NPC ของคุณตัวอย่างเช่น หาก NPC ของคุณไม่ได้จะปีนบันได ก็ปลอดภัยที่จะปิดใช้งานสถานะ Climbing
- สร้างโมเดลใหม่ ปรับแต่ง และเกิดใหม่อีกครั้งกับมนุษย์บ่อยๆ * นี่อาจเป็นการใช้งานหนักสำหรับเครื่องยนต์ในการประมวลผลโดยเฉพาะอย่างยิ่งถ้ารูปแบบเหล่านี้ใช้ เสื้อผ้าชั้นใน นี่ยังอาจเป็นปัญหาพิเศษในประสบการณ์ที่อวาตาร์เกิดใหม่บ่อย
- ใน MicroProfiler แท็กยาว อัปเดตคลัสเตอร์ที่ไม่ถูกต้องอย่างรวดเร็ว (มากกว่า 4 มิลลิวินาที) มักเป็นสัญญาณว่าการสร้าง/การแก้ไขอวาตาร์กำลังกระตุ้นการละเมิดที่มากเกินไป
- การใช้ Humanoids ในกรณีที่ไม่จำเป็น - NPC คงที่ที่ไม่เคลื่อนไหวโดยทั่วไปไม่จำเป็นต้องใช้คลาส Humanoid
- การเล่นแอนิเมชันบนจํานวน NPC จํานวนมากจากเซิร์ฟเวอร์ - แอนิเมชัน NPC ที่ทํางานบนเซิร์ฟเวอร์จะต้องจําลองบนเซิร์ฟเวอร์และสําเนาไปยังไคลเอนต์นี่อาจเป็นค่าใช้จ่ายที่ไม่จำเป็น
การบรรเทา
- เล่นแอนิเมชั่น NPC บนไคลเอนต์ - ในประสบการณ์ที่มีจํานวน NPC จํานวนมากให้พิจารณาสร้าง Animator บนไคลเอนต์และดําเนินการแอนิเมชั่นในท้องถิ่นสิ่งนี้ลดภาระบนเซิร์ฟเวอร์และความจำเป็นในการสําเนาที่ไม่จําเป็นนอกจากนี้ยังทำให้การปรับแต่งเพิ่มเติมเป็นไปได้ (เช่นเพียงเล่นแอนิเมชั่นสำหรับ NPC ที่อยู่ใกล้ตัวละครเท่านั้น)
- ใช้ทางเลือกที่เป็นมิตรกับประสิทธิภาพแทน Humanoids - โมเดล NPC ไม่จำเป็นต้องมีวัตถุ humanoid อยู่
- สำหรับ NPC คงที่ใช้ AnimationController ง่ายๆเพราะพวกเขาไม่จำเป็นต้องเคลื่อนที่ แต่ต้องการเล่นแอนิเมชั่นเท่านั้น
- สำหรับการเคลื่อนย้าย NPC พิจารณาการใช้ตัวควบคุมการเคลื่อนที่ของคุณเองและใช้ AnimationController สำหรับการแสดงภาพ ขึ้นอยู่กับความซับซ้อนของ NPC ของคุณ
- ปิดใช้งานสถานะ humanoid ที่ไม่ได้ใช้งาน - ใช้ Humanoid:SetStateEnabled() เพื่อเปิดใช้งานสถานะที่จำเป็นเท่านั้นสำหรับแต่ละ humanoid
- รูปแบบ NPC สระน้ำที่มีการเกิดใหม่บ่อย - แทนที่จะทำลาย NPC โดยสิ้นเชิง ส่ง NPC ไปยังสระน้ำของ NPC ที่ไม่ได้ใช้งานทางนี้เมื่อ NPC ใหม่จำเป็นต้องเกิดใหม่คุณสามารถเปิดใช้งาน NPC หนึ่งจากสระน้ำได้อีกครั้งกระบวนการนี้เรียกว่าการรวม ซึ่งลดจํานวนครั้งที่ตัวละครต้องถูกสร้างขึ้น
- สร้าง NPC เฉพาะเมื่อผู้ใช้อยู่ใกล้เท่านั้น - อย่าสร้าง NPC เมื่อผู้ใช้ไม่ได้อยู่ในระยะ และกำจัดพวกเขาเมื่อผู้ใช้ออกจากระยะ
- หลีกเลี่ยงการทำการเปลี่ยนแปลงในลำดับของอวตารหลังจากที่มันถูกสร้างขึ้น - การแก้ไขบางอย่างในลำดับของอวตารมีผลกระทบที่สำคัญต่อประสิทธิภาพมีการปรับแต่งบางอย่างที่มีอยู่:
- สำหรับแอนิเมชั่นกระบวนการที่กําหนดเอง, อย่าอัปเดตคุณสมบัติ JointInstance.C0 และ JointInstance.C1 แทน, อัปเดตคุณสมบัติ Motor6D.Transform
- หากต้องการแนบวัตถุใด ๆ BasePart ไปยังอวตาร ทำเช่นนั้นนอกจากระดับของอวตาร Model
ขอบเขตของ MicroProfiler
ขอบเขต | การคำนวณที่เกี่ยวข้อง |
ขั้นตอน Humanoid | การควบคุมและฟิสิกส์ของมนุษย์หุ่น |
ขั้นตอนการเคลื่อนไหว | อนิเมชั่นของมนุษย์และนักแสดงแอนิเมชั่น |
อัปเดตกลุ่มเร็วที่ไม่ถูกต้อง | เกี่ยวข้องกับการสร้างหรือแก้ไขอวตาร |
การเรนเดอร์
ส่วนสำคัญของเวลาที่ลูกค้าใช้ในแต่ละเฟรมคือการเรนเดอร์สถานที่ในเฟรมปัจจุบันเซิร์ฟเวอร์ไม่ทำการเรนเดอร์ใดๆ ดังนั้นส่วนนี้จึงเป็นส่วนสำหรับลูกค้าเท่านั้น
ดึงคำร้องขอ
การเรียกวาดเป็นชุดคำแนะนำจากเครื่องยนต์ไปยัง GPU เพื่อเรนเดอร์บางอย่างการเรียกวาดมีค่าใช้จ่ายที่สำคัญโดยทั่วไป ยิ่งมีการเรียกวาดน้อยต่อเฟรมมากเท่าไร เวลาในการคำนวณก็จะยิ่งน้อยลงเท่านั้นในการเรนเดอร์เฟรม
คุณสามารถดูได้ว่าการเรียกวาดเกิดขึ้นกี่ครั้งในปัจจุบันด้วยไอเทม สถิติการเรนเดอร์ > เวลา ใน Studioคุณสามารถดู สถิติการเรนเดอร์ ในไคลเอนต์โดยกด ShiftF2
ยิ่งมีวัตถุมากขึ้นที่ต้องวาดในฉากในเฟรมที่กำหนดไว้ การเรียกใช้ GPU ก็จะมากขึ้นเท่านั้นอย่างไรก็ตาม เครื่อง Roblox ใช้กระบวนการที่เรียกว่า instancing เพื่อย่อเมชที่เหมือนกันด้วยลักษณะเทกเจอร์เดียวกันให้เป็นการเรียกวาดเดียวโดยเฉพาะอย่างยิ่งเมชที่หลากหลายด้วยเดียวกัน MeshId จะได้รับการจัดการในการเรียกวาดเดียวเมื่อ:
- SurfaceAppearances เป็นตัวเอกเดียวกัน TextureIDs เป็นตัวเอกเดียวกันเมื่อ SurfaceAppearance ไม่มีอยู่
- วัสดุจะเหมือนกันเมื่อทั้ง SurfaceAppearance และ MeshPart.TextureID ไม่มีอยู่
ปัญหาทั่วไปอื่นๆ
ความหนาแน่นวัตถุที่มากเกินไป - หากจํานวนวัตถุจํานวนมากถูกรวมไว้ด้วยความหนาแน่นสูง การเรนเดอร์ส่วนนี้ของฉากจะต้องใช้การเรียกวาดเพิ่มเติมหากคุณพบว่าอัตราเฟรมของคุณลดลงเมื่อมองไปที่ส่วนหนึ่งของแผนที่บางส่วน นี่อาจเป็นสัญญาณที่ดีว่าความหนาแน่นของวัตถุในพื้นที่นี้สูงเกินไป
วัตถุเช่นภาพวาด เทกเจอร์ และอนุภาคไม่สามารถจัดเตรียมได้ดีและนำเสนอการดึงเพิ่มเติมได้ให้ความสนใจเป็นพิเศษกับประเภทวัตถุเหล่านี้ในฉากโดยเฉพาะอย่างยิ่งการเปลี่ยนแปลงคุณสมบัติไปที่ ParticleEmitters อาจมีผลกระทบอย่างมากต่อประสิทธิภาพ
พลาดโอกาสในการจำลอง - บ่อยครั้งที่ฉากจะรวมเมชเดิมซ้ำหลายครั้ง แต่แต่ละคันของเมชมี ID ทรัพยากรเมชหรือเทกเจอร์ที่แตกต่างกันสิ่งนี้ป้องกันการสร้างและอาจนำไปสู่การเรียกวาดที่ไม่จำเป็น
สาเหตุทั่วไปของปัญหานี้คือเมื่อนำฉากทั้งหมดมาในครั้งเดียวแทนที่จะนำทรัพยากรแต่ละอย่างมายัง Roblox แล้วดัดแปลงหลังจากนำมาประกอบฉาก
แม้แต่สคริปต์ง่ายๆ เช่นนี้ก็สามารถช่วยคุณระบุชิ้นส่วนที่มีชื่อเดียวกันที่ใช้ ID เมชที่แตกต่างกันได้:
local Workspace = game:GetService("Workspace")for _, descendant in Workspace:GetDescendants() doif descendant:IsA("MeshPart") thenprint(descendant.Name .. ", " .. descendant.MeshId)endendผลผลิต (ที่มี เส้นสแต็ก เปิดใช้งาน) อาจมีลักษณะเช่นนี้บรรทัดซ้ำบ่อยบ่งบอกถึงการใช้ซ้ำเมชเดียวกันซึ่งเป็นสิ่งที่ดีเส้นที่ไม่ซ้ำกันไม่จำเป็นต้องเลวเสมอไป แต่ขึ้นอยู่กับสิ่งที่คุณใช้ระบบการตั้งชื่อ อาจบ่งบอกถึงเมชที่ซ้ำกันในประสบการณ์ของคุณ:
LargeRock, rbxassetid://106420009602747 (x144) -- goodLargeRock, rbxassetid://120109824668127LargeRock, rbxassetid://134460273008628LargeRock, rbxassetid://139288987285823LargeRock, rbxassetid://71302144984955LargeRock, rbxassetid://90621205713698LargeRock, rbxassetid://113160939160788LargeRock, rbxassetid://135944592365226 -- all possible duplicatesความซับซ้อนของวัตถุมากเกินไป - แม้ว่าจะไม่สำคัญเท่ากับจํานวนการเรียกวาด แต่จํานวนสามเหลี่ยมในฉากก็มีอิทธิพลต่อระยะเวลาที่ใช้ในการแสดงผลของเฟรมฉากที่มีจํานวนเมชที่ซับซ้อนมากจํานวนมากเป็นปัญหาทั่วไปเช่นเดียวกับฉากที่มีค่า MeshPart.RenderFidelity ของคุณตั้งค่าเป็น Enum.RenderFidelity.Precise บนเมชที่มากเกินไป
การโค้งเงามากเกินไป - การจัดการเงาเป็นกระบวนการที่มีราคาแพงและแผนที่ที่มีจํานวนและความหนาแน่นของแสงสูงที่โค้งเงา (หรือจํานวนและความหนาแน่นของชิ้นส่วนขนาดเล็กที่ได้รับอิทธิพลจากเงา) มีแนวโน้มที่จะมีปัญหาประสิทธิภาพ
การดึงความโปร่งใสสูง - วางวัตถุที่มีความโปร่งใสบางส่วนอยู่ใกล้กันทำให้เครื่องยนต์ต้องแสดงพิกเซลซ้อนกันหลายครั้งซึ่งอาจทำให้ประสิทธิภาพลดลงสำหรับข้อมูลเพิ่มเติมเกี่ยวกับการระบุและแก้ไขปัญหานี้ ดู ลบความโปร่งใสแบบซ้อนกัน
การบรรเทา
- สร้างเมชที่เหมือนกันและลดจำนวนเมชที่ไม่ซ้ำกัน - หากคุณตรวจสอบให้แน่ใจว่าเมชทั้งหมดเหมือนกันทั้งหมดมี ID สินทรัพย์พื้นฐานเดียวกันเดียวกัน เครื่องยนต์สามารถรู้จักและแสดงพวกเขาในการเรียกวาดเดียวได้ตรวจสอบให้แน่ใจว่าอัปโหลดแต่ละเมชในแผนที่เพียงครั้งเดียวแล้วทำซ้ำในสตูดิโอเพื่อใช้ซ้ำแทนการนำเข้าแผนที่ขนาดใหญ่ทั้งหมดซึ่งอาจทำให้เมชที่เหมือนกันมี ID เนื้อหาแยกต่างหากและได้รับการยอมรับเป็นสินทรัพย์ที่ไม่ซ้ำกันโดยเครื่องยนต์แพคเกจ เป็นเครื่องมือที่มีประโยชน์สำหรับการใช้ซ้ำวัตถุ
- การคัดเลือก - การคัดเลือกอธิบายกระบวนการการลบคำสั่งวาดสำหรับวัตถุที่ไม่ได้เป็นปัจจัยในกรอบภาพที่สร้างขึ้นในที่สุดโดยค่าเริ่มต้น เครื่องยนต์จะข้ามการเรียกสำหรับวัตถุที่อยู่นอกสนามมุมมองของกล้อง (การคัดเลือก frustum) แต่ไม่ข้ามการเรียกสำหรับวัตถุที่ถูกปิดกั้นจากการมองเห็นโดยวัตถุอื่น (การคัดเลือกการปิดกั้น)หากฉากของคุณมีจำนวนการเรียกวาดจำนวนมาก พิจารณาที่จะใช้การคัดเลือกเพิ่มเติมของคุณเองในเวลาเรียลไทม์สำหรับทุกเฟรม เช่น การใช้กลยุทธ์ทั่วไปต่อไปนี้:
- สำหรับสภาพแวดล้อมภายใน, ให้ดำเนินการติดตั้งระบบห้องหรือพอร์ทัลที่ซ่อนวัตถุที่ไม่ได้ใช้งานอยู่ในปัจจุบันโดยผู้ใช้ใดๆ
- ลดความถูกต้องของการเรนเดอร์ - ตั้งความถูกต้องของการเรนเดอร์เป็น อัตโนมัติ หรือ ประสิทธิภาพ สิ่งนี้ช่วยให้เมชกลับไปใช้ทางเลือกที่ซับซ้อนน้อยลงซึ่งสามารถลดจํานวนโพลิโกนที่ต้องวาดได้
- การปิดใช้งานการโค้งเงาบนส่วนและวัตถุแสงที่เหมาะสม - ความซับซ้อนของเงาในฉากสามารถลดลงได้โดยการปิดใช้งานคุณสมบัติการโค้งเงาบนวัตถุแสงและส่วนอย่างเลือกได้สามารถทำได้ในเวลาแก้ไขหรืออย่างไดนามิกในระหว่างการรันไทม์ตัวอย่างบางส่วนคือ:
ใช้คุณสมบัติ BasePart.CastShadow เพื่อปิดการโค้งเงาบนชิ้นส่วนขนาดเล็กที่มีโอกาสน้อยที่จะมองเห็นเงาสิ่งนี้สามารถมีประสิทธิภาพมากขึ้นเมื่อใช้เฉพาะกับชิ้นส่วนที่อยู่ไกลจากกล้องของผู้ใช้
ปิดใช้งานเงาบนวัตถุที่เคลื่อนไหวเมื่อเป็นไปได้
ปิดใช้งาน Light.Shadows บนตัวอย่างแสงที่วัตถุไม่จำเป็นต้องโค้งเงา
จำกัดระยะและมุมของตัวอย่างแสง
ใช้ตัวอย่างแสงน้อยลง
พิจารณาการปิดไฟที่อยู่นอกขอบเขตเฉพาะหรือตามรูปแบบห้องต่อห้องสำหรับสภาพแวดล้อมภายใน
ขอบเขตของ MicroProfiler
ขอบเขต | การคำนวณที่เกี่ยวข้อง |
เตรียมและดำเนินการ | การแสดงผลโดยรวม |
ดำเนินการ/ฉาก/คํานวณแสงดําเนินการ | การอัปเดตกริดแสงและเงา |
หน่วยประมวลผลกริดแสง | การอัปเดตกริดแสงวอกเซล |
ระบบ ShadowMapSystem | แผนที่เงา |
ดำเนินการ/ฉาก/อัปเดตมุมมอง | การเตรียมการสําหรับการเรนเดอร์และการอัปเดตอนุภาค |
ดำเนินการ/ฉาก/RenderView | การเรนเดอร์และการประมวลผลภายหลัง |
เครือข่ายและการเลียนแบบ
การเชื่อมต่อและการจำลองอธิบายถึงกระบวนการที่ข้อมูลถูกส่งระหว่างเซิร์ฟเวอร์และไคลเอนต์ที่เชื่อมต่อข้อมูลจะถูกส่งระหว่างไคลเอนต์และเซิร์ฟเวอร์ในแต่ละเฟรม แต่จำนวนข้อมูลที่มากขึ้นต้องใช้เวลาในการคำนวณมากขึ้น
ปัญหาทั่วไป
การจราจรระยะไกลที่มากเกินไป - การส่งข้อมูลจํานวนมากผ่าน RemoteEvent หรือ RemoteFunction วัตถุหรือเรียกใช้พวกเขาบ่อยมากเกินไปอาจทําให้เกิดเวลาในการประมวลผลของ CPU จํานวนมากในแต่ละเฟรมข้อผิดพลาดทั่วไปรวมถึง:
- การสําเนาข้อมูลทุกเฟรมที่ไม่จำเป็นต้องสําเนา
- การสําเนาข้อมูลตามการใส่ของผู้ใช้โดยไม่มีเครื่องมือใดๆ เพื่อลดความเร็ว
- ส่งข้อมูลมากกว่าที่จำเป็นตัวอย่างเช่น การส่งสินค้าคงคลังทั้งหมดของผู้เล่นเมื่อพวกเขาซื้อรายการแทนที่จะเป็นรายละเอียดของรายการที่ซื้อ
การสร้างหรือลบต้นไม้ตัวอย่างที่ซับซ้อน - เมื่อมีการทำการเปลี่ยนแปลงในโมเดลข้อมูลบนเซิร์ฟเวอร์ จะถูกส่งต่อไปยังไคลเอนต์ที่เชื่อมต่อซึ่งหมายความว่าการสร้างและทำลายชั้นวางตำแหน่งขนาดใหญ่เช่นแผนที่ในระหว่างการทำงานอาจใช้เครือข่ายมาก ก็ได้
คนร้ายทั่วไปที่นี่คือข้อมูลแอนิเมชันที่ซับซ้อนที่บันทึกโดยปลั๊กอินตัวแก้ไขแอนิเมชันในริกหากไม่มีการลบเหล่านี้ก่อนที่เกมจะเผยแพร่และโมเดลแอนิเมชั่นถูกคลอนอย่างสม่ำเสมอจำนวนข้อมูลจำนวนมากจะถูกเลียนแบบโดยไร้ความจำเป็น
บริการ TweenService ด้านเซิร์ฟเวอร์ - หาก TweenService ถูกใช้เพื่อทวีนเซิร์ฟเวอร์ด้านวัตถุ คุณสมบัติที่ทวีนจะถูกเลียนแบบไปยังแต่ละไคลเอนต์ในแต่ละเฟรมไม่เพียงแค่นี้ทำให้วัยรุ่นตื่นตระหนกเมื่อความล่าช้าของไคลเอนต์เปลี่ยนแปลง แต่ยังทำให้เกิดการจราจรเครือข่ายที่ไม่จำเป็นจํานวนมาก
การบรรเทา
คุณสามารถใช้กลยุทธ์ต่อไปนี้เพื่อลดการซ้ำที่ไม่จำเป็น:
- หลีกเลี่ยงการส่งข้อมูลจํานวนมากในครั้งเดียวผ่านเหตุการณ์ระยะไกล แทนที่จะส่งข้อมูลที่จำเป็นเฉพาะในความถี่ที่ต่ำกว่าตัวอย่างเช่น สำหรับสถานะของตัวละคร ทำซ้ำเมื่อมันเปลี่ยนแปลงแทนที่จะทำทุกเฟรม
- แยกต้นไม้ตัวอย่างที่ซับซ้อนออกเป็นชิ้นส่วน เช่นแผนที่และโหลดพวกมันในชิ้นส่วนเพื่อจัดจำหน่ายงานสําเร็จรูปเหล่านี้ในหลายกรอบ
- ล้างข้อมูลอนิเมชั่น โดยเฉพาะอย่างยิ่งไดเรกทอรีอนิเมชั่นของแรมหลังจากนำเข้า
- จํากัดการสําเนาตัวอย่างที่ไม่จําเป็น โดยเฉพาะอย่างยิ่งในกรณีที่เซิร์ฟเวอร์ไม่จําเป็นต้องมีความรู้เกี่ยวกับตัวอย่างที่ถูกสร้างขึ้นซึ่งรวมถึง:
- เอฟเฟกต์ภาพเช่นระเบิดหรือระเบิดคาถาเวทย์มนตร์เซิร์ฟเวอร์ต้องรู้ตำแหน่งเท่านั้นเพื่อกำหนดผลลัพธ์ ในขณะที่ลูกค้าสามารถสร้างภาพได้ท้องถิ่น
- รูปแบบการดูรายการบุคคลแรก
- วัตถุระหว่างที่อยู่บนไคลเอนต์แทนที่จะเป็นเซิร์ฟเวอร์
ขอบเขตของ MicroProfiler
ขอบเขต | การคำนวณที่เกี่ยวข้อง |
แพคเกจกระบวนการ | การประมวลผลสำหรับแพคเกจเครือข่ายที่เข้ามา เช่น การเรียกใช้เหตุการณ์และการเปลี่ยนแปลงคุณสมบัติ |
กำหนดความถี่และส่งผู้ส่ง | อีเวนต์ที่ออกบนเซิร์ฟเวอร์ที่เกี่ยวข้อง |
การใช้หน่วยความจําสินทรัพย์
เครื่องมือการมีผลกระทบสูงสุดที่มีอยู่สำหรับผู้สร้างเพื่อปรับปรุงการใช้หน่วยความจําของไคลเอนต์คือการเปิดใช้งาน การสตรีมตัวอย่าง
การสตรีมตัวอย่างอินสแตนซ์
การสตรีมตัวอย่างเลือกโหลดส่วนหนึ่งของโมเดลข้อมูลที่ไม่จำเป็นซึ่งอาจทำให้เวลาการโหลดลดลงอย่างมากและเพิ่มความสามารถของไคลเอนต์ในการป้องกันการล้มเหลวเมื่ออยู่ภายใต้แรงกดดันของหน่วยความจำ
หากคุณพบปัญหาเกี่ยวกับหน่วยความจําและมีการสตรีมตัวอย่างถูกปิดใช้งาน พิจารณาอัปเดตประสบการณ์ของคุณเพื่อสนับสนุนมันโดยเฉพาะอย่างยิ่งถ้าโลก 3D ของคุณใหญ่การสตรีมตัวอย่างขึ้นอยู่กับระยะทางในพื้นที่ 3D ดังนั้นโลกขนาดใหญ่จะได้รับประโยชน์มากขึ้นตามธรรมชาติ
หากการสตรีมตัวอย่างเปิดใช้งานแล้ว คุณสามารถเพิ่มความก้าวร้าวของมันได้ ตัวอย่างเช่น พิจารณา:
- ลดการใช้งานคงที่ ความสมบูรณ์ของการสตรีม * ลดรัศมีการสตรีม **** สำหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกการสตรีมและประโยชน์ของพวกเขา ดู คุณสมบัติการสตรีม
ปัญหาทั่วไปอื่นๆ
- การซ้ำของสินทรัพย์ - ข้อผิดพลาดทั่วไปคือการอัปโหลดสินทรัพย์เดียวหลายครั้งซึ่งทำให้เกิด ID สินทรัพย์ที่แตกต่างกันสิ่งนี้อาจทำให้เนื้อหาเดียวกันถูกโหลดลงในหน่วยความจําหลายครั้ง
- ปริมาณสินทรัพย์ที่มากเกินไป - แม้ว่าสินทรัพย์จะไม่เหมือนกัน แต่ก็มีกรณีที่โอกาสในการใช้สินทรัพย์เดียวกันและประหยัดหน่วยความจำถูกพลาด
- ไฟล์เสียง - ไฟล์เสียงสามารถเป็นผู้บริจาคที่น่าประหลาดใจในการใช้หน่วยความจำได้ โดยเฉพาะอย่างยิ่งหากคุณโหลดพวกเขาทั้งหมดในไคลเอนต์พร้อมกันแทนที่จะโหลดเฉพาะสิ่งที่คุณต้องการสำหรับส่วนหนึ่งของประสบการณ์สำหรับกลยุทธ์ดูที่ เวลาโหลด
- เทกเจอร์ความละเอียดสูง - การใช้หน่วยความจำกราฟิกสำหรับเทกเจอร์ไม่เกี่ยวข้องกับขนาดของเทกเจอร์บนดิสก์ แต่เป็นจํานวนพิกเซลในเทกเจอร์
- ตัวอย่างเช่น เทกเจอร์ขนาด 1024x1024 ใช้หน่วยความจํากราฟิกสี่เท่าของเทกเจอร์ 512x512
- ภาพที่อัปโหลดไปยัง Roblox จะถูกเข้ารหัสเป็นรูปแบบคงที่ดังนั้นจึงไม่มีประโยชน์ในการอัปโหลดภาพในโมเดลสีที่มีขนาดไฟล์น้อยกว่า 1 ไบต์ต่อพิกเซลเช่นเดียวกับการบีบอัดภาพก่อนอัปโหลดหรือลบช่องแอลฟาออกจากภาพที่ไม่ต้องการสามารถลดขนาดภาพบนดิสก์ได้ แต่ก็ไม่ดีขึ้นหรือดีขึ้นเพียงเล็กน้อยเท่านั้นในการใช้หน่วยความจำแม้ว่าเครื่องยนต์จะลดความละเอียดของเทกเจอร์ในบางอุปกรณ์โดยอัตโนมัติ แต่ขนาดของการลดความละเอียดขึ้นอยู่กับคุณลักษณะของอุปกรณ์ และความละเอียดของเทกเจอร์ที่มากเกินไปยังคงสามารถทำให้เกิดปัญหาได้
- คุณสามารถระบุการใช้หน่วยความจํากราฟิกสําหรับเทกเจอร์ที่กำหนดโดยขยายหมวดหมู่ กราฟิกเทกเจอร์ ใน คอนโซลนักพัฒนา
การบรรเทา
อัปโหลดสินทรัพย์เพียงครั้งเดียว - ใช้สินทรัพย์เดียวกันในวัตถุทั้งหมดและตรวจสอบให้แน่ใจว่าสินทรัพย์เดียวกันโดยเฉพาะอย่างยิ่งเมชและภาพไม่ถูกอัปโหลดแยกต่างหากหลายครั้ง
ค้นหาและแก้ไขสินทรัพย์ซ้ำ - มองหาชิ้นส่วนเมชและเทกเจอร์ที่เหมือนกันที่อัปโหลดหลายครั้งด้วยรหัสที่แตกต่างกัน
- แม้ว่าจะไม่มี API ที่จะตรวจจับความคล้ายคลึงกันของสินทรัพย์โดยอัตโนมัติ คุณสามารถรวบรวม ID ทั้งหมดของสินทรัพย์ภาพในสถานที่ของคุณ (ไม่ว่าจะเป็นด้วยตนเองหรือด้วยสคริปต์) ดาวน์โหลดพวกเขา และเปรียบเทียบพวกเขาโดยใช้เครื่องมือเปรียบเทียบภายนอก
- สำหรับชิ้นส่วนเมช กลยุทธ์ที่ดีที่สุดคือการใช้ ID เมชที่ไม่ซ้ำกันและจัดระเบียบตามขนาดเพื่อระบุชิ้นส่วนซ้ำด้วยตนเอง
- แทนที่จะใช้เทกเจอร์แยกต่างหากสำหรับสีที่แตกต่างกัน ให้อัปโหลดเทกเจอร์เดียวและใช้คุณสมบัติ SurfaceAppearance.Color เพื่อใช้สีต่างๆ กับมัน
นำทรัพยากรมาในแผนที่แยกต่างหาก - แทนที่จะนำแผนที่ทั้งหมดมาในครั้งเดียว ให้นำทรัพยากรและสร้างใหม่ในแผนที่เป็นรายบุคคลและสร้างใหม่นักนำเข้า 3D ไม่ทําการซ้ําของเมช ดังนั้นหากคุณนําเข้าแผนที่ขนาดใหญ่พร้อมกับกระเบื้องหลายชิ้น แต่ละกระเบื้องจะถูกนํามาเป็นสินทรัพย์แยกต่างหาก (แม้ว่าพวกเขาจะเป็นซ้ําก็ตาม)สิ่งนี้สามารถนำไปสู่ปัญหาประสิทธิภาพและหน่วยความจําลงตามเส้น เนื่องจากแต่ละเมชจะได้รับการปฏิบัติเป็นอิสระและใช้หน่วยความจําและดึงการโทรไป
จำกัดพิกเซลของภาพ ไม่เกินจำนวนที่จำเป็นยกเว้นถ้าภาพกำลังใช้พื้นที่จำนวนมากบนหน้าจอ มักจะต้องการพิกเซลสูงสุด 512x512 เท่านั้นภาพขนาดเล็กส่วนใหญ่ควรมีขนาดเล็กกว่า 256x256 พิกเซล
ใช้แผ่นตัด เพื่อให้แน่ใจว่ามีการนำใช้เทกเจอร์สูงสุดในแผนที่ 3Dสำหรับขั้นตอนและตัวอย่างวิธีการสร้างแผ่นตัดดูที่ สร้างแผ่นตัด
คุณอาจพิจารณาใช้แผ่นสปรายต์เพื่อโหลดภาพ UI ขนาดเล็กจำนวนมากเป็นภาพเดียวด้วยจากนั้นคุณสามารถใช้ ImageLabel.ImageRectOffset และ ImageLabel.ImageRectSize เพื่อแสดงส่วนของแผ่นงาน
เวลาโหลด
ประสบการณ์จํานวนมากใช้หน้าจอโหลดที่กําหนดเองและใช้วิธี ContentProvider:PreloadAsync() เพื่อขอทรัพยากรเพื่อให้ภาพเสียงและเมชจะถูกดาวน์โหลดในพื้นหลัง
ข้อดีของวิธีนี้คือคุณสามารถตรวจสอบให้แน่ใจว่าส่วนสำคัญของประสบการณ์ของคุณโหลดเต็มแล้วโดยไม่ต้องป๊อปอินอย่างไรก็ตาม, ข้อผิดพลาดทั่วไปคือการใช้วิธีนี้มากเกินไปในการโหลดล่วงหน้าสินทรัพย์เพิ่มเติมที่จริงจำเป็น
ตัวอย่างของการปฏิบัติที่ไม่ดีคือการโหลดทั้งหมด Workspace ในขณะที่อาจป้องกันการปรากฏตัวของเทกเจอร์ แต่มันเพิ่มเวลาในการโหลดอย่างมาก
แทนที่จะใช้เฉพาะ ContentProvider:PreloadAsync() ในสถานการณ์ที่จำเป็นซึ่งรวมถึง:
- ภาพในหน้าจอโหลด
- ภาพสำคัญในเมนูประสบการณ์ของคุณ เช่น พื้นหลังปุ่มและไอคอน
- สินทรัพย์สำคัญในพื้นที่เริ่มต้นหรือจุดเกิด
หากคุณต้องโหลดจํานวนมากของสินทรัพย์ เราขอแนะนําให้คุณให้ปุ่ม ข้ามการโหลด