ส่วนหน้าของมิดเดิลเอิร์ธ

คำแนะนำแบบทีละขั้นตอนเกี่ยวกับการพัฒนาสำหรับหลายอุปกรณ์

ในบทความแรกเกี่ยวกับการพัฒนาเวอร์ชันทดลองของ Chrome อย่าง A Journey Through Middle-earth เรามุ่งเน้นที่การพัฒนา WebGL สำหรับอุปกรณ์เคลื่อนที่ บทความนี้จะกล่าวถึงความท้าทาย ปัญหา และวิธีแก้ปัญหาที่เราพบเมื่อสร้างส่วนหน้า HTML5 ที่เหลือ

เว็บไซต์เดียวกัน 3 เวอร์ชัน

เรามาเริ่มกันด้วยการพูดคุยเกี่ยวกับการปรับการทดสอบนี้ให้ทำงานได้ทั้งในคอมพิวเตอร์เดสก์ท็อปและอุปกรณ์เคลื่อนที่จากมุมมองขนาดหน้าจอและความสามารถของอุปกรณ์

โปรเจ็กต์นี้ใช้สไตล์ที่ "เหมือนภาพยนตร์" มาก ซึ่งในด้านการออกแบบ เราต้องการคงประสบการณ์ให้อยู่ในเฟรมแนวนอนแบบคงที่เพื่อรักษาความมหัศจรรย์ของภาพยนตร์ไว้ เนื่องจากโปรเจ็กต์ส่วนใหญ่ประกอบด้วย "เกม" มินิแบบอินเทอร์แอกทีฟ จึงไม่ควรให้เกมเหล่านี้ล้นเฟรม

เราสามารถใช้หน้า Landing Page เป็นตัวอย่างการปรับการออกแบบให้เหมาะกับขนาดต่างๆ

นกอินทรีเพิ่งพาเราไปที่หน้า Landing Page
นกอินทรีเพิ่งพาเราไปที่หน้า Landing Page

เว็บไซต์มี 3 โหมด ได้แก่ เดสก์ท็อป แท็บเล็ต และอุปกรณ์เคลื่อนที่ ไม่ใช่แค่เพื่อจัดการเลย์เอาต์เท่านั้น แต่เพราะเราต้องจัดการชิ้นงานที่โหลดในรันไทม์และเพิ่มการเพิ่มประสิทธิภาพต่างๆ การกำหนดชุดกฎขั้นสุดท้ายสำหรับอุปกรณ์ที่มีความละเอียดสูงกว่าคอมพิวเตอร์เดสก์ท็อปและแล็ปท็อป แต่มีประสิทธิภาพต่ำกว่าโทรศัพท์นั้นไม่ใช่เรื่องง่าย

เราใช้ข้อมูล User Agent เพื่อตรวจหาอุปกรณ์เคลื่อนที่และการทดสอบขนาดวิวพอร์ตเพื่อกําหนดเป้าหมายแท็บเล็ตในอุปกรณ์เหล่านั้น (645 พิกเซลขึ้นไป) อันที่จริงแล้ว โหมดแต่ละโหมดสามารถแสดงผลความละเอียดทั้งหมดได้ เนื่องจากเลย์เอาต์จะอิงตาม Media Query หรือการวางตำแหน่งแบบสัมพัทธ์/เปอร์เซ็นต์ด้วย JavaScript

เนื่องจากการออกแบบในกรณีนี้ไม่ได้อิงตามตารางกริดหรือกฎ และค่อนข้างแตกต่างกันไปในแต่ละส่วน การเลือกจุดพักหรือสไตล์ที่จะใช้จึงขึ้นอยู่กับองค์ประกอบและสถานการณ์ที่เฉพาะเจาะจง เราได้สร้างเลย์เอาต์ที่สมบูรณ์แบบด้วย sass-mixins และ media-queries ที่ยอดเยี่ยมมาแล้วหลายครั้ง แต่ก็ต้องเพิ่มเอฟเฟกต์ตามตำแหน่งเมาส์หรือออบเจ็กต์แบบไดนามิก และสุดท้ายก็ต้องเขียนทุกอย่างใน JavaScript ใหม่

นอกจากนี้ เรายังเพิ่มคลาสที่มีโหมดปัจจุบันในแท็ก head เพื่อให้ใช้ข้อมูลดังกล่าวในสไตล์ได้ ดังตัวอย่างนี้ (ใน SCSS)

.loc-hobbit-logo {

  // Default values here.

  .desktop & {
     // Applies only in desktop mode.
  }

 .tablet &, .mobile & {
   
   // Different asset for mobile and tablets perhaps.

   @media screen and (max-height: 760px), (max-width: 760px) {
     // Breakpoint-specific styles.
   }

   @media screen and (max-height: 570px), (max-width: 400px) {
     // Breakpoint-specific styles.
   }
 }
}

เรารองรับทุกขนาดที่เล็กสุดประมาณ 360x320 ซึ่งค่อนข้างท้าทายเมื่อต้องสร้างประสบการณ์การใช้งานเว็บที่สมจริง บนเดสก์ท็อป เรากำหนดขนาดขั้นต่ำก่อนที่จะแสดงแถบเลื่อน เนื่องจากเราต้องการให้คุณได้รับประสบการณ์การใช้งานเว็บไซต์ในวิวพอร์ตที่ใหญ่ขึ้นหากเป็นไปได้ ในอุปกรณ์เคลื่อนที่ เราตัดสินใจที่จะอนุญาตให้ใช้ทั้งโหมดแนวนอนและแนวตั้งได้จนถึงประสบการณ์แบบอินเทอร์แอกทีฟ ซึ่งเราจะขอให้คุณหมุนอุปกรณ์เป็นแนวนอน ข้อโต้แย้งคือโหมดนี้ไม่ได้ให้ประสบการณ์ที่สมจริงเท่าโหมดแนวนอน แต่เว็บไซต์ปรับขนาดได้ดีพอสมควร เราจึงใช้โหมดนี้ต่อไป

โปรดทราบว่าเลย์เอาต์ไม่ควรสับสนกับการตรวจหาฟีเจอร์ เช่น ประเภทอินพุต การวางแนวอุปกรณ์ เซ็นเซอร์ ฯลฯ ฟีเจอร์เหล่านั้นอาจอยู่ในโหมดเหล่านี้ทั้งหมดและควรครอบคลุมทุกโหมด ตัวอย่างเช่น การรองรับเมาส์และการสัมผัสพร้อมกัน การแสดงผล Retina จะชดเชยคุณภาพ แต่ประสิทธิภาพสำคัญกว่า บางครั้งคุณภาพที่ต่ำลงก็ดีกว่า ตัวอย่างเช่น ภาพพิมพ์แคนวาสมีความละเอียดครึ่งหนึ่งของประสบการณ์ WebGL ในจอแสดงผล Retina ซึ่งจะต้องแสดงผลพิกเซลเป็นจำนวน 4 เท่า

เราใช้เครื่องมือจำลองในเครื่องมือสำหรับนักพัฒนาเว็บบ่อยครั้งในระหว่างการพัฒนา โดยเฉพาะใน Chrome Canary ซึ่งมีฟีเจอร์ใหม่ๆ ที่ปรับปรุงแล้วและค่าที่กำหนดล่วงหน้าจำนวนมาก ซึ่งเป็นวิธีที่ดีในการตรวจสอบการออกแบบอย่างรวดเร็ว เรายังคงต้องทดสอบกับอุปกรณ์จริงเป็นประจำ สาเหตุหนึ่งคือเว็บไซต์ปรับให้เหมาะกับโหมดเต็มหน้าจอ หน้าเว็บที่มีการเลื่อนแนวตั้งจะซ่อน UI ของเบราว์เซอร์เมื่อเลื่อนในเกือบทุกกรณี (ปัจจุบัน Safari ใน iOS7 มีปัญหาเกี่ยวกับเรื่องนี้) แต่เราต้องปรับทุกอย่างให้พอดีโดยไม่คำนึงถึงปัญหานี้ นอกจากนี้ เรายังใช้ค่าที่กำหนดล่วงหน้าในโปรแกรมจำลองและเปลี่ยนการตั้งค่าขนาดหน้าจอเพื่อจำลองการสูญเสียพื้นที่ว่าง การทดสอบบนอุปกรณ์จริงยังมีความสำคัญต่อการตรวจสอบการใช้หน่วยความจำและประสิทธิภาพด้วย

การจัดการสถานะ

หลังจากหน้า Landing Page เราจะไปที่แผนที่ของ Middle-earth คุณสังเกตเห็นการเปลี่ยนแปลงของ URL ไหม เว็บไซต์เป็นแอปพลิเคชันหน้าเว็บเดียวที่ใช้ History API เพื่อจัดการการกำหนดเส้นทาง

ส่วนต่างๆ ของเว็บไซต์แต่ละส่วนจะเป็นออบเจ็กต์ของตัวเองที่รับค่าเริ่มต้นของฟังก์ชันการทำงาน เช่น องค์ประกอบ DOM, ทรานซิชัน, การโหลดชิ้นงาน, การจัดการ เป็นต้น เมื่อคุณสำรวจส่วนต่างๆ ของเว็บไซต์ ระบบจะเริ่มต้นส่วนต่างๆ เพิ่มและนำองค์ประกอบออกจาก DOM และโหลดชิ้นงานสำหรับส่วนปัจจุบัน

เนื่องจากผู้ใช้สามารถกดปุ่มย้อนกลับของเบราว์เซอร์หรือไปยังส่วนต่างๆ ผ่านเมนูได้ทุกเมื่อ ระบบจึงต้องทิ้งทุกอย่างที่สร้างไว้ คุณต้องหยุดและทิ้งการหมดเวลาและภาพเคลื่อนไหว ไม่เช่นนั้นอาจทำให้เกิดลักษณะการทำงาน ข้อผิดพลาด และการรั่วไหลของหน่วยความจำที่ไม่พึงประสงค์ ซึ่งไม่ใช่เรื่องง่ายเสมอไป โดยเฉพาะเมื่อใกล้ถึงกำหนดเวลาแล้วและคุณต้องใส่ทุกอย่างลงไปให้เร็วที่สุด

แสดงสถานที่

เราได้สร้างระบบโมดูลของคอมโพเนนต์รูปภาพและข้อความที่คุณสามารถลากหรือปัดในแนวนอนเพื่อแสดงฉากที่สวยงามและตัวละครของมิดเดิ้ลเอิร์ธ เรายังไม่ได้เปิดใช้แถบเลื่อนที่นี่เนื่องจากต้องการให้แต่ละช่วงมีความเร็วต่างกัน เช่น ในลำดับภาพที่คุณหยุดภาพเคลื่อนไหวไปด้านข้างจนกว่าคลิปจะเล่นจบ

หอคอยของ Thranduil
ลำดับเวลาของหอคอยของ Thranduil

ไทม์ไลน์

เมื่อเริ่มการพัฒนา เราไม่ทราบเนื้อหาของโมดูลสำหรับแต่ละตำแหน่ง สิ่งที่เราทราบคือเราต้องการใช้เทมเพลตในการแสดงสื่อและข้อมูลประเภทต่างๆ ในไทม์ไลน์แนวนอน ซึ่งจะช่วยให้เรานำเสนอสถานที่ตั้ง 6 แห่งที่แตกต่างกันได้โดยไม่ต้องสร้างทุกอย่างใหม่ 6 ครั้ง เราได้สร้างตัวควบคุมไทม์ไลน์เพื่อจัดการการเลื่อนโมดูลตามการตั้งค่าและลักษณะการทํางานของโมดูล

โมดูลและคอมโพเนนต์ลักษณะการทำงาน

โมดูลต่างๆ ที่เราเพิ่มการรองรับ ได้แก่ ซีเควนซ์รูปภาพ รูปภาพนิ่ง ฉากพารัลแลกซ์ ฉากที่มีการเปลี่ยนโฟกัส และข้อความ

โมดูลฉากภาพพารัลแลกซ์มีพื้นหลังทึบแสงที่มีจํานวนเลเยอร์ที่กำหนดเองซึ่งคอยตรวจสอบความคืบหน้าของวิวพอร์ตเพื่อหาตําแหน่งที่แน่นอน

ฉากการเปลี่ยนโฟกัสเป็นรูปแบบหนึ่งของกลุ่มพารัลแลกซ์ โดยเราใช้รูปภาพ 2 รูปสำหรับแต่ละเลเยอร์ ซึ่งจะค่อยๆ ปรากฏขึ้นและจางหายไปเพื่อจำลองการเปลี่ยนแปลงโฟกัส เราลองใช้ฟิลเตอร์เบลอแล้ว แต่ยังคงมีราคาแพงเกินไป เราจึงจะรอใช้ CSS Shader สำหรับฟีเจอร์นี้

เนื้อหาในโมดูลข้อความจะเปิดใช้การลากด้วยปลั๊กอิน TweenMax Draggable นอกจากนี้ คุณยังใช้แป้นลูกล้อเลื่อนหรือใช้ 2 นิ้วปัดเพื่อเลื่อนในแนวตั้งได้ด้วย โปรดสังเกต throw-props-plugin ที่เพิ่มฟิสิกส์แบบฟลิงเมื่อคุณปัดและปล่อย

โมดูลยังมีลักษณะการทํางานที่แตกต่างกันซึ่งเพิ่มเป็นชุดคอมโพเนนต์ได้ด้วย แต่ละรายการมีตัวเลือกเป้าหมายและการตั้งค่าของตนเอง เลื่อนเพื่อย้ายองค์ประกอบ ปรับขนาดเพื่อซูม โฮตสปอตสำหรับการวางซ้อนข้อมูล เมตริกการแก้ไขข้อบกพร่องสำหรับการทดสอบด้วยภาพ การวางซ้อนชื่อเริ่มต้น เลเยอร์แสงแฟลช และอื่นๆ รายการเหล่านี้จะต่อท้าย DOM หรือควบคุมองค์ประกอบเป้าหมายภายในโมดูล

เมื่อใช้วิธีนี้ เราจะสร้างตำแหน่งต่างๆ ได้โดยใช้เพียงไฟล์การกําหนดค่าที่กําหนดชิ้นงานที่จะโหลดและตั้งค่าโมดูลและคอมโพเนนต์ประเภทต่างๆ

ลำดับรูปภาพ

โมดูลที่ท้าทายที่สุดในแง่ประสิทธิภาพและขนาดการดาวน์โหลดคือลําดับรูปภาพ มีบทความมากมายให้อ่านเกี่ยวกับหัวข้อนี้ เราจะแทนที่ภาพเคลื่อนไหวนี้ด้วยภาพนิ่งบนอุปกรณ์เคลื่อนที่และแท็บเล็ต เนื่องจากมีข้อมูลมากเกินไปที่จะถอดรหัสและจัดเก็บไว้ในหน่วยความจำหากต้องการให้คุณภาพดีบนอุปกรณ์เคลื่อนที่ เราได้ลองใช้วิธีแก้ปัญหาอื่นๆ หลายวิธีแล้ว เช่น ใช้ภาพพื้นหลังและ Sprite Sheet ก่อน แต่วิธีนี้ทำให้เกิดปัญหาเกี่ยวกับหน่วยความจำและเกิดความล่าช้าเมื่อ GPU จำเป็นต้องสลับระหว่าง Sprite Sheet จากนั้นเราลองสลับองค์ประกอบ img แต่ก็ยังช้าเกินไป การวาดเฟรมจาก Sprite Sheet ไปยัง Canvas มีประสิทธิภาพสูงสุด เราจึงเริ่มเพิ่มประสิทธิภาพในส่วนนั้น ระบบจะประมวลผลข้อมูลรูปภาพที่จะเขียนลงใน Canvas ล่วงหน้าผ่าน Canvas ชั่วคราวและบันทึกด้วย putImageData() ลงในอาร์เรย์ ถอดรหัส และพร้อมใช้งาน เพื่อประหยัดเวลาในการประมวลผลแต่ละเฟรม จากนั้นระบบจะรวบรวมขยะจาก Sprite Sheet เดิม และเราจะจัดเก็บข้อมูลในหน่วยความจำเพียงจำนวนขั้นต่ำที่จำเป็นเท่านั้น จริงๆ แล้วการเก็บรูปภาพที่ไม่ได้ถอดรหัสอาจใช้พื้นที่น้อยกว่า แต่เราได้รับประสิทธิภาพที่ดีขึ้นขณะกรอลำดับภาพด้วยวิธีนี้ เฟรมมีขนาดเล็กมากเพียง 640x400 แต่คุณจะเห็นเฟรมดังกล่าวระหว่างที่กรอวิดีโอ เมื่อคุณหยุด รูปภาพความละเอียดสูงจะโหลดและปรากฏขึ้นอย่างรวดเร็ว

var canvas = document.createElement('canvas');
canvas.width = imageWidth;
canvas.height = imageHeight;

var ctx = canvas.getContext('2d');
ctx.drawImage(sheet, 0, 0);

var tilesX = imageWidth / tileWidth;
var tilesY = imageHeight / tileHeight;

var canvasPaste = canvas.cloneNode(false);
canvasPaste.width = tileWidth;
canvasPaste.height = tileHeight;

var i, j, canvasPasteTemp, imgData, 
var currentIndex = 0;
var startIndex = index * 16;
for (i = 0; i < tilesY; i++) {
  for (j = 0; j < tilesX; j++) {
    // Store the image data of each tile in the array.
    canvasPasteTemp = canvasPaste.cloneNode(false);
    imgData = ctx.getImageData(j * tileWidth, i * tileHeight, tileWidth, tileHeight);
    canvasPasteTemp.getContext('2d').putImageData(imgData, 0, 0);

    list[ startIndex + currentIndex ] = imgData;

    currentIndex++;
  }
}

สไปรท์ชีตสร้างขึ้นด้วย Imagemagick ต่อไปนี้เป็นตัวอย่างใน GitHub ที่แสดงวิธีสร้าง Sprite Sheet ของรูปภาพทั้งหมดในโฟลเดอร์

การทำโมดูลเคลื่อนไหว

หากต้องการวางข้อบังคับในไทม์ไลน์ การแสดงไทม์ไลน์ที่ซ่อนอยู่ซึ่งแสดงนอกหน้าจอจะติดตาม "ตัวควบคุมเวลา" และความกว้างของไทม์ไลน์ ซึ่งทําได้โดยใช้แค่โค้ด แต่การนําเสนอภาพก็มีประโยชน์สําหรับการพัฒนาและการแก้ไขข้อบกพร่อง เมื่อใช้งานจริง ระบบจะอัปเดตขนาดใหม่เพื่อกำหนดมิติข้อมูล โมดูลบางรายการจะขยายเต็มวิวพอร์ตและบางรายการมีอัตราส่วนของตัวเอง จึงปรับขนาดและจัดตำแหน่งทุกอย่างในความละเอียดทั้งหมดให้มองเห็นได้ทั้งหมดและไม่ได้ถูกครอบตัดมากเกินไปได้ยาก แต่ละโมดูลจะมีตัวบ่งชี้ความคืบหน้า 2 ตัว ได้แก่ ตัวบ่งชี้ตำแหน่งที่มองเห็นได้บนหน้าจอและตัวบ่งชี้ระยะเวลาของโมดูล เมื่อสร้างการเคลื่อนไหวแบบพารัลแลกซ์ การคำนวณตำแหน่งเริ่มต้นและตำแหน่งสิ้นสุดของวัตถุให้สอดคล้องกับตำแหน่งที่คาดไว้เมื่อวัตถุอยู่ในมุมมองมักจะทำได้ยาก คุณควรทราบเวลาที่แน่นอนที่ข้อบังคับปรากฏในมุมมอง เล่นไทม์ไลน์ภายใน และแสดงภาพเคลื่อนไหวออกจากมุมมองอีกครั้ง

แต่ละข้อบังคับจะมีเลเยอร์สีดําที่มองไม่เห็นที่ด้านบนซึ่งจะปรับความทึบแสงเพื่อให้โปร่งใสอย่างสมบูรณ์เมื่ออยู่ในตําแหน่งตรงกลาง วิธีนี้ช่วยให้คุณมุ่งเน้นที่แต่ละข้อได้ทีละข้อ ซึ่งจะช่วยปรับปรุงประสบการณ์การใช้งาน

ประสิทธิภาพของหน้าเว็บ

การเปลี่ยนจากต้นแบบที่ใช้งานได้ไปเป็นเวอร์ชันที่เผยแพร่โดยไม่มีกระตุกหมายความว่าคุณจะต้องเปลี่ยนจากการคาดเดาเป็นการทำความเข้าใจสิ่งที่เกิดขึ้นในเบราว์เซอร์ เครื่องมือสําหรับนักพัฒนาเว็บใน Chrome จะเป็นเพื่อนที่ดีที่สุดของคุณ

เราใช้เวลาค่อนข้างมากในการเพิ่มประสิทธิภาพเว็บไซต์ การบังคับใช้การเร่งฮาร์ดแวร์เป็นหนึ่งในเครื่องมือที่สำคัญที่สุดที่จะทำให้ภาพเคลื่อนไหวราบรื่น แต่ให้มองหาคอลัมน์สีสันสดใสและสี่เหลี่ยมผืนผ้าสีแดงในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome ด้วย มีบทความดีๆ เกี่ยวกับหัวข้อนี้มากมาย และคุณควรอ่านทั้งหมด รางวัลสำหรับการนำเฟรมที่ข้ามออกนั้นได้ผลทันที แต่ความหงุดหงิดก็เกิดขึ้นทันทีเช่นกันเมื่อเฟรมเหล่านั้นกลับมาอีกครั้ง และเราจะดำเนินการดังกล่าว นี่เป็นกระบวนการต่อเนื่องที่ต้องอาศัยการปรับปรุง

เราชอบใช้ TweenMax จาก Greensock สําหรับการทวิงก์พร็อพเพอร์ตี้ การเปลี่ยนรูปแบบ และ CSS คิดในแง่คอนเทนเนอร์ นึกภาพโครงสร้างขณะเพิ่มเลเยอร์ใหม่ โปรดทราบว่าการเปลี่ยนรูปแบบใหม่จะเขียนทับการเปลี่ยนรูปแบบที่มีอยู่ได้ ระบบจะแทนที่ translateZ(0) ที่บังคับให้ใช้การเร่งด้วยฮาร์ดแวร์ในคลาส CSS ด้วยเมทริกซ์ 2 มิติหากคุณใช้การตีวิดค่า 2 มิติเท่านั้น หากต้องการให้เลเยอร์อยู่ในโหมดการเร่งความเร็วในกรณีดังกล่าว ให้ใช้พร็อพเพอร์ตี้ "force3D:true" ในช่วงการเปลี่ยนภาพเพื่อสร้างเมทริกซ์ 3 มิติแทนเมทริกซ์ 2 มิติ คุณอาจลืมได้เมื่อใช้การตีกลับของ CSS และ JavaScript เพื่อตั้งค่าสไตล์

อย่าบังคับใช้การเร่งฮาร์ดแวร์เมื่อไม่จำเป็น หน่วยความจำ GPU อาจเต็มอย่างรวดเร็วและทำให้เกิดผลลัพธ์ที่ไม่ต้องการเมื่อคุณต้องการเร่งความเร็วคอนเทนเนอร์จำนวนมากด้วยฮาร์ดแวร์ โดยเฉพาะใน iOS ที่มีข้อจำกัดด้านหน่วยความจำมากกว่า การโหลดชิ้นงานขนาดเล็กลงและปรับขนาดด้วย CSS รวมถึงปิดใช้เอฟเฟกต์บางอย่างในโหมดอุปกรณ์เคลื่อนที่ช่วยปรับปรุงประสิทธิภาพได้อย่างมาก

การรั่วไหลของหน่วยความจำเป็นอีกด้านที่เราจำเป็นต้องพัฒนาทักษะ เมื่อไปยังส่วนต่างๆ ของประสบการณ์ WebGL ที่แตกต่างกัน ระบบจะสร้างวัตถุ วัสดุ พื้นผิว และเรขาคณิตจำนวนมาก หากข้อมูลเหล่านั้นยังไม่พร้อมสำหรับการเก็บขยะเมื่อคุณไปยังส่วนอื่นและนำส่วนนั้นออก ข้อมูลดังกล่าวอาจทำให้อุปกรณ์ขัดข้องหลังจากผ่านไประยะหนึ่งเมื่อหน่วยความจำหมด

ออกจากส่วนที่มีฟังก์ชันทิ้งไม่สำเร็จ
การออกจากส่วนที่มีฟังก์ชันทิ้งที่ไม่สําเร็จ
ดีขึ้นมาก
ดีมากเลย

การค้นหาการรั่วไหลนั้นทําได้ง่ายๆ ในเวิร์กโฟลว์ของเครื่องมือสําหรับนักพัฒนาซอฟต์แวร์ โดยบันทึกไทม์ไลน์และจับภาพฮีปสแนปชอต การดำเนินการจะง่ายขึ้นหากมีวัตถุที่เฉพาะเจาะจง เช่น เรขาคณิต 3 มิติหรือคลังเฉพาะที่คุณกรองออกได้ ในตัวอย่างข้างต้น ปรากฏว่าฉาก 3 มิติยังคงอยู่และยังไม่มีการล้างอาร์เรย์ที่จัดเก็บเรขาคณิต หากค้นหาตำแหน่งของออบเจ็กต์ได้ยาก เรามีฟีเจอร์ที่ยอดเยี่ยมซึ่งให้คุณดูข้อมูลนี้ได้ ฟีเจอร์นี้เรียกว่าเส้นทางการเก็บรักษา เพียงคลิกออบเจ็กต์ที่ต้องการตรวจสอบในสแนปชอตกอง heap แล้วคุณจะได้รับข้อมูลในแผงด้านล่าง การใช้โครงสร้างที่ดีกับวัตถุขนาดเล็กจะช่วยในการค้นหาข้อมูลอ้างอิง

มีการอ้างอิงฉากใน EffectComposer
มีการอ้างอิงฉากใน EffectComposer

โดยทั่วไปแล้ว คุณควรคิดให้รอบคอบก่อนจัดการ DOM เมื่อทำเช่นนั้น ให้คำนึงถึงประสิทธิภาพ อย่าดัดแปลง DOM ภายใน Game Loop หากเป็นไปได้ จัดเก็บข้อมูลอ้างอิงในตัวแปรเพื่อใช้ซ้ำ หากต้องการค้นหาองค์ประกอบ ให้ใช้เส้นทางที่สั้นที่สุดโดยจัดเก็บการอ้างอิงไปยังคอนเทนเนอร์เชิงกลยุทธ์และค้นหาภายในองค์ประกอบบรรพบุรุษที่ใกล้ที่สุด

เลื่อนเวลาในการอ่านมิติข้อมูลขององค์ประกอบที่เพิ่มใหม่หรือเมื่อนำคลาสออก/เพิ่มคลาส หากคุณพบข้อบกพร่องของเลย์เอาต์ หรือตรวจสอบว่ามีการเรียกใช้เลย์เอาต์ บางครั้งเบราว์เซอร์จะเปลี่ยนรูปแบบเป็นกลุ่มและจะไม่อัปเดตหลังจากทริกเกอร์เลย์เอาต์ครั้งถัดไป บางครั้งปัญหานี้อาจเป็นเรื่องใหญ่ แต่ก็มีเหตุผลอยู่ ดังนั้นลองศึกษาวิธีการทำงานของระบบเบื้องหลังและคุณจะได้ประโยชน์มากมาย

เต็มหน้าจอ

เมื่อพร้อมใช้งาน คุณจะมีตัวเลือกในการทำให้เว็บไซต์อยู่ในโหมดเต็มหน้าจอในเมนูผ่าน Fullscreen API แต่อุปกรณ์ยังมีการตัดสินใจของเบราว์เซอร์ที่จะแสดงแบบเต็มหน้าจอด้วย ก่อนหน้านี้ Safari ใน iOS มีวิธีแฮ็กให้คุณควบคุมสิ่งนั้นได้ แต่ตอนนี้วิธีดังกล่าวใช้ไม่ได้แล้ว คุณจึงต้องเตรียมการออกแบบให้ทำงานได้โดยไม่ต้องใช้วิธีดังกล่าวเมื่อสร้างหน้าเว็บแบบไม่เลื่อน เราอาจได้รับการอัปเดตเกี่ยวกับเรื่องนี้ในการอัปเดตในอนาคต เนื่องจากปัญหานี้ทำให้เว็บแอปจำนวนมากใช้งานไม่ได้

ชิ้นงาน

วิธีการแบบเคลื่อนไหวสำหรับการทดสอบ
วิธีการแบบเคลื่อนไหวสำหรับการทดสอบ

เว็บไซต์ของเรามีชิ้นงานหลายประเภท เช่น รูปภาพ (PNG และ JPEG), SVG (ในหน้าและพื้นหลัง), สไปรต์ชีต (PNG), แบบอักษรไอคอนที่กำหนดเอง และภาพเคลื่อนไหว Adobe Edge เราใช้ PNG สำหรับชิ้นงานและภาพเคลื่อนไหว (Spritesheet) เมื่อองค์ประกอบไม่สามารถเป็นเวกเตอร์ได้ แต่เราจะพยายามใช้ SVG มากที่สุด

รูปแบบเวกเตอร์จะทำให้รูปภาพไม่สูญเสียคุณภาพแม้ว่าเราจะปรับขนาดก็ตาม 1 ไฟล์สำหรับอุปกรณ์ทุกเครื่อง

  • ไฟล์มีขนาดเล็ก
  • เราสามารถสร้างภาพเคลื่อนไหวแต่ละส่วนแยกกันได้ (เหมาะสำหรับภาพเคลื่อนไหวขั้นสูง) ตัวอย่างเช่น เราจะซ่อน "คำบรรยาย" ของโลโก้ฮอบบิท (The Desolation of Smaug) เมื่อปรับขนาดให้เล็กลง
  • โดยสามารถฝังเป็นแท็ก SVG HTML หรือใช้เป็นพื้นหลังโดยไม่มีการโหลดเพิ่มเติม (จะโหลดพร้อมกันกับหน้า HTML)

แบบอักษรไอคอนมีข้อดีเช่นเดียวกับ SVG ในเรื่องการปรับขนาดได้ และจะใช้แทน SVG สำหรับองค์ประกอบขนาดเล็ก เช่น ไอคอนที่เราต้องการเปลี่ยนสีเท่านั้น (โฮเวอร์ ใช้งานอยู่ ฯลฯ) นอกจากนี้ ไอคอนยังนํามาใช้ซ้ำได้ง่ายมาก เพียงตั้งค่าพร็อพเพอร์ตี้ "content" ของ CSS ขององค์ประกอบ

ภาพเคลื่อนไหว

ในบางกรณี การสร้างภาพเคลื่อนไหวขององค์ประกอบ SVG ด้วยโค้ดอาจใช้เวลานานมาก โดยเฉพาะเมื่อต้องเปลี่ยนแปลงภาพเคลื่อนไหวหลายครั้งในระหว่างกระบวนการออกแบบ เราใช้ Adobe Edge สำหรับภาพเคลื่อนไหวบางอย่าง (วิธีการก่อนเกม) เพื่อปรับปรุงเวิร์กโฟลว์ระหว่างนักออกแบบและนักพัฒนาซอฟต์แวร์ เวิร์กโฟลว์ภาพเคลื่อนไหวนั้นคล้ายกับ Flash มาก ซึ่งช่วยทีมได้ แต่ก็มีข้อเสียอยู่บ้าง โดยเฉพาะการผสานรวมภาพเคลื่อนไหวของ Edge ในกระบวนการโหลดชิ้นงาน เนื่องจากมาพร้อมกับโปรแกรมโหลดและตรรกะการใช้งานของตัวเอง

เรายังรู้สึกว่ายังมีหนทางอีกยาวไกลก่อนที่จะมีเวิร์กโฟลว์ที่สมบูรณ์แบบสำหรับการจัดการชิ้นงานและภาพเคลื่อนไหวที่ทำด้วยมือบนเว็บ เราหวังว่าจะได้เห็นการพัฒนาของเครื่องมืออย่าง Edge คุณสามารถเพิ่มคำแนะนำเกี่ยวกับเครื่องมือและเวิร์กโฟลว์อื่นๆ สำหรับการสร้างภาพเคลื่อนไหวได้ในความคิดเห็น

บทสรุป

ตอนนี้เมื่อเราเผยแพร่ทุกส่วนของโปรเจ็กต์และดูผลลัพธ์สุดท้ายแล้ว ต้องบอกว่าเราค่อนข้างประทับใจกับสถานะของเบราว์เซอร์บนอุปกรณ์เคลื่อนที่สมัยใหม่ เมื่อเริ่มต้นโปรเจ็กต์นี้ เราคาดหวังไว้น้อยกว่ามากว่าโปรเจ็กต์นี้จะทำงานได้อย่างราบรื่น มีการผสานรวม และมีประสิทธิภาพมากเพียงใด เราได้เรียนรู้สิ่งใหม่ๆ มากมาย และเวลาทั้งหมดที่ใช้ไปกับการปรับปรุงและทดสอบ (มากพอสมควร) ช่วยให้เราได้เข้าใจวิธีการทำงานของเบราว์เซอร์สมัยใหม่มากขึ้น และนี่คือสิ่งที่ต้องใช้เวลาหากเราต้องการลดเวลาการผลิตในโปรเจ็กต์ประเภทนี้ จากการเดาเป็นความรู้