← บทความทั้งหมด

Skeleton loading ให้กริดสินค้า WooCommerce

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

อย่างแรก ทำให้แน่ใจว่าไม่มีอะไรกระโดด

skeleton ใช้พื้นที่เดียวกับที่รูปจะใช้ พื้นที่นั้นจึงต้องรู้ก่อนที่รูปจะมา WooCommerce ใส่ width และ height ให้รูปสินค้า และเบราว์เซอร์ใช้ค่าเหล่านี้จองกล่องขนาดที่ถูกต้องไว้ ตราบใดที่ CSS ของธีมยังใช้ height: auto และไม่มีอะไรตัดแอตทริบิวต์ทิ้ง วิธีตรวจคือหน่วงความเร็วเน็ตในเครื่องมือนักพัฒนาของเบราว์เซอร์ แล้วโหลดหน้าร้านใหม่ ถ้ากริดขยายตัวตอนรูปมาถึง ให้แก้ตรงนี้ก่อน ถ้ารูปย่อสินค้าของคุณครอปเป็นสี่เหลี่ยมจัตุรัส (หน้าตา → ปรับแต่ง → WooCommerce → Product Images) แค่นี้ก็พอ

.woocommerce ul.products li.product img {
	aspect-ratio: 1 / 1;
	object-fit: cover;
}

skeleton: CSS ที่เห็นตั้งแต่หน้าเว็บแสดงครั้งแรก

รูปภาพก็เป็นกล่องที่มีพื้นหลังเหมือนองค์ประกอบอื่น และพื้นหลังจะแสดงอยู่จนกว่าภาพจะวาดทับ แสงวิบวับจึงอยู่บนตัวรูปเองได้ ไม่ต้องเพิ่มมาร์กอัป และไม่ต้องรอ JavaScript เพราะ CSS อยู่ใน head ของหน้า skeleton จึงอยู่ตรงนั้นตั้งแต่หน้าเว็บแสดงครั้งแรก

.woocommerce ul.products li.product img:not(.is-loaded) {
	background: linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%) 0 0 / 200% 100%;
	animation: shop-skeleton 1.4s linear 8;
}

@keyframes shop-skeleton {
	to {
		background-position: -200% 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.woocommerce ul.products li.product img:not(.is-loaded) {
		animation: none;
	}
}

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

JavaScript: เอาออกเมื่อรูปมาถึง

ถ้ามีแค่ CSS สีเทาจะค้างอยู่หลังรูปที่มีส่วนโปร่งใส และแอนิเมชันจะยังวิ่งอยู่หลังทุกรูป โค้ดไม่กี่บรรทัดนี้ทำเครื่องหมายให้แต่ละรูปเมื่อมันมาถึง

const shopImages = '.woocommerce ul.products li.product img';

const markLoaded = (img) => {
	// placeholder ของการโหลดแบบ lazy เป็นรูป data: ให้รอไฟล์จริง
	if (!img.currentSrc.startsWith('data:')) {
		img.classList.add('is-loaded');
	}
};

// รูปที่โหลดเสร็จนับจากนี้ รวมถึงรูปที่ตัวกรองหรือปุ่มโหลดเพิ่มใส่เข้ามา
// load และ error ไม่ bubble จึงต้องฟังในช่วง capture
for (const type of ['load', 'error']) {
	document.addEventListener(type, (event) => {
		if (event.target instanceof HTMLImageElement && event.target.matches(shopImages)) {
			markLoaded(event.target);
		}
	}, true);
}

// รูปที่โหลดเสร็จก่อนโค้ดนี้ทำงาน
document.querySelectorAll(shopImages).forEach((img) => {
	if (img.complete) {
		markLoaded(img);
	}
});

listener ตัวเดียวบน document จับได้ทุกรูป ทั้งรูปที่อยู่ในหน้าและรูปที่ถูกเพิ่มทีหลัง จึงไม่ต้องตั้งอะไรใหม่หลังตัวกรองสินค้าโหลดกริดใหม่ ส่วนการเช็ก data: มีไว้สำหรับธีมและปลั๊กอินที่โหลดแบบ lazy โดยใส่ placeholder เล็ก ๆ ไว้ใน src แล้วค่อยสลับเป็นไฟล์จริงทีหลัง placeholder โหลดเสร็จทันที ถ้าไม่เช็ก skeleton จะหายไปก่อนที่รูปสินค้าจะมาถึง

ใน StyleScript ปลั๊กอินฟรีสำหรับ CSS และ JavaScript ของคุณเอง CSS ใส่ในกล่อง CSS ซึ่งพิมพ์ไว้ใน head ของหน้า skeleton จึงแสดงตั้งแต่หน้าเว็บแสดงครั้งแรก ส่วนสคริปต์ใส่ในกล่อง JavaScript โดยโหลดในส่วนท้าย

ถ้ากริดสินค้าของร้านสร้างด้วยบล็อกของ WooCommerce หรือวิดเจ็ตสินค้าของ page builder มาร์กอัปจะต่างออกไป ให้ตรวจรูปสินค้าสักรูปในเบราว์เซอร์ แล้วใช้ class ของมันแทน selector ข้างบน

สิ่งที่ควรเลี่ยง

เวอร์ชันที่ไม่ต้องเขียนโค้ด

StyleScript Pro ซึ่งเป็น add-on ของปลั๊กอินฟรี มี Skeleton Loading เป็นเอฟเฟกต์สำเร็จรูป ที่ หน้าตา → StyleScript → เอฟเฟกต์ เลือกได้ว่าจะใช้กับองค์ประกอบไหน โดยมีชุดตั้งค่าสำเร็จสำหรับกริดสินค้า WooCommerce กล่องสินค้าและแบนเนอร์ของ Flatsome รูปภาพและแกลเลอรีของ Elementor block Image และ Gallery หรือทุกรูปที่โหลดแบบ lazy และตั้งสี ความเร็วของแสงวิบวับ สีเข้มสำหรับผู้เข้าชมที่ใช้โหมดมืด ระยะเวลาแสดงอย่างน้อย และเวลาที่หยุดช้าที่สุด CSS ของมันพิมพ์ไว้ใน head จึงเห็นตั้งแต่หน้าเว็บแสดงครั้งแรก ส่วนสคริปต์ที่เล็กไม่ถึงหนึ่งกิโลไบต์ รองรับตัวโหลดแบบ lazy ที่สลับ placeholder เป็นรูปจริง รวมถึงของ Flatsome และยังมีอีกโหมดสำหรับกล่องที่ว่างอยู่จนกว่าจะมีอะไรมาเติม เช่น รายการที่ตัวกรองสินค้าโหลดใหม่

เก็บโค้ดที่ใส่เองไว้ในที่เดียว

StyleScript เก็บ CSS, JavaScript และโค้ดส่วนหัว/ส่วนท้ายของคุณแยกจากธีม ใส่แต่ละอย่างในที่ของมัน และเก็บทุกเวอร์ชันที่บันทึก

ดูว่า StyleScript ทำอะไรได้  ดูราคา