หากไม่มีการแสดงผลฝั่งเซิร์ฟเวอร์ แต่ยังต้องการเพิ่มประสิทธิภาพของเว็บไซต์ React อยู่ ลองแสดงผลล่วงหน้า
react-snap
เป็นบุคคลที่สาม
ที่แสดงผลล่วงหน้าของหน้าเว็บไซต์ของคุณเป็นไฟล์ HTML แบบคงที่ วิธีนี้
ปรับปรุง
การแสดงผลครั้งแรก
ครั้งในแอปพลิเคชันของคุณ
นี่คือการเปรียบเทียบแอปพลิเคชันเดียวกันที่มีและไม่มีการแสดงผลล่วงหน้า โหลดด้วยการเชื่อมต่อ 3G และอุปกรณ์เคลื่อนที่จำลอง:
เหตุใดจึงมีประโยชน์
ปัญหาประสิทธิภาพที่สำคัญในแอปพลิเคชันหน้าเว็บเดียวขนาดใหญ่คือ ผู้ใช้ต้องรอให้ชุด JavaScript ที่ประกอบกันเป็นเว็บไซต์เสร็จ ก่อนที่พวกเขาจะได้ดูเนื้อหาจริง ยิ่งแพ็กเกจมีขนาดใหญ่ขึ้น ผู้ใช้ต้องรอนานขึ้น
เพื่อแก้ไขปัญหานี้ นักพัฒนาซอฟต์แวร์จำนวนมากจึงใช้แนวทางการแสดงผลแอปพลิเคชันใน แทนที่จะเปิดเครื่องเฉพาะบนเบราว์เซอร์ ใน การเปลี่ยนหน้า/เส้นทาง ระบบจะสร้าง HTML ที่สมบูรณ์บนเซิร์ฟเวอร์และส่งไปยัง ซึ่งเป็นเบราว์เซอร์ที่ลดเวลา First Paint ได้ แต่มาพร้อมกับค่าใช้จ่ายที่ช้ากว่า เวลาที่ได้รับข้อมูลไบต์แรก
การแสดงผลล่วงหน้าเป็นเทคนิคแยกต่างหากซึ่งมีความซับซ้อนน้อยกว่าเซิร์ฟเวอร์ และยังเป็นวิธีในการปรับปรุงการแสดงผล First Paint ใน แอปพลิเคชัน มีการใช้เบราว์เซอร์แบบไม่มีส่วนหัวหรือเบราว์เซอร์ที่ไม่มีอินเทอร์เฟซผู้ใช้ เพื่อสร้างไฟล์ HTML แบบคงที่ของทุกเส้นทางในระหว่างเวลาสร้าง ไฟล์เหล่านี้ สามารถส่งไปพร้อมกับกลุ่ม JavaScript ที่จำเป็นต้องใช้สำหรับ แอปพลิเคชัน
รีแอ็ก-สแนป
react-snap
ใช้ Puppeteer เพื่อ
สร้างไฟล์ HTML ที่แสดงผลล่วงหน้าของเส้นทางต่างๆ ในแอปพลิเคชันของคุณ ถึง
เริ่มต้น ให้ติดตั้งเป็นทรัพยากร Dependency ในการพัฒนา
npm install --save-dev react-snap
จากนั้นเพิ่มสคริปต์ postbuild
ใน package.json
ดังนี้
"scripts": {
//...
"postbuild": "react-snap"
}
การดำเนินการนี้จะเรียกใช้คำสั่ง react-snap
โดยอัตโนมัติทุกครั้งที่บิลด์ใหม่ของ
แอปพลิเคชันที่สร้าง (npm build
)
สิ่งสุดท้ายที่คุณต้องทำก็คือเปลี่ยนวิธีเปิดเครื่องของแอปพลิเคชัน
เปลี่ยนไฟล์ src/index.js
เป็นดังนี้
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
ReactDOM.hydrate(<App />, rootElement);
} else {
ReactDOM.render(<App />, rootElement);
}
แทนที่จะใช้เพียง ReactDOM.render
เพื่อแสดงผลเอลิเมนต์ React รูทเท่านั้น
ไปยัง DOM โดยตรง ซึ่งจะตรวจสอบเพื่อดูว่ามีโหนดย่อยอยู่แล้วหรือไม่
เพื่อระบุว่าเนื้อหา HTML มีการแสดงผลล่วงหน้าหรือไม่ (หรือแสดงผลใน
เซิร์ฟเวอร์) หากเป็นเช่นนั้น จะมีการใช้ ReactDOM.hydrate
เพื่อแนบเหตุการณ์แทน
Listener ของ HTML ที่สร้างไว้แล้ว แทนที่จะสร้างใหม่
การสร้างแอปพลิเคชันจะสร้างไฟล์ HTML แบบคงที่เป็นเพย์โหลดสำหรับ แต่ละเส้นทางที่มีการ Crawl คุณสามารถดูว่าเพย์โหลด HTML มีลักษณะอย่างไร เช่น โดยคลิก URL ของคำขอ HTML แล้วคลิกตัวอย่าง ภายในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome
Flash ของเนื้อหาที่ไม่ได้จัดรูปแบบ
แม้ว่าในขณะนี้ HTML แบบคงที่จะแสดงผลแทบจะในทันที แต่ HTML ก็ยังคงอยู่ ไม่มีการจัดรูปแบบโดยค่าเริ่มต้น ซึ่งอาจทำให้เกิดปัญหาในการแสดง "ไม่จัดรูปแบบ" เนื้อหา" (FOUC) โดยจะสังเกตเห็นได้ชัดหากคุณใช้ CSS-in-JS ไลบรารีในการสร้างตัวเลือกเนื่องจากแพ็กเกจ JavaScript จะต้องเสร็จสิ้น เกิดขึ้นก่อนจะนำไปใช้สไตล์ใดๆ ได้
เพื่อช่วยป้องกันปัญหานี้ คุณควร CSS ที่สำคัญ หรือจำนวน CSS ขั้นต่ำที่
ที่จำเป็นต่อการแสดงผลของหน้าเริ่มต้น คุณสามารถแทรกในบรรทัดไปยัง <head>
โดยตรง
ของเอกสาร HTML react-snap
ใช้ไลบรารีอื่นของบุคคลที่สามภายใต้
ฮู้ด minimalcss
เพื่อดึงข้อมูล
CSS วิกฤติสำหรับเส้นทางต่างๆ คุณเปิดใช้งานได้โดยระบุ
รายการต่อไปนี้ในไฟล์ package.json
ของคุณ
"reactSnap": {
"inlineCss": true
}
การดูตัวอย่างการตอบกลับใน Chrome DevTools จะแสดงหน้าที่มีการจัดรูปแบบซึ่งมี CSS ที่สำคัญแทรกในบรรทัด
บทสรุป
ถ้าคุณไม่ใช่เส้นทางการแสดงผลฝั่งเซิร์ฟเวอร์ในแอปพลิเคชันของคุณ ให้ใช้
react-snap
เพื่อแสดง HTML แบบคงที่ต่อผู้ใช้ล่วงหน้า
- ติดตั้งเป็นทรัพยากร Dependency ของการพัฒนาและเริ่มต้นด้วยค่าเริ่มต้นเท่านั้น การตั้งค่า
- ใช้ตัวเลือก
inlineCss
แบบทดลองเพื่อแทรก CSS ที่สำคัญในหน้า หากใช้งานได้ สำหรับเว็บไซต์ของคุณ - หากคุณใช้การแยกโค้ดในระดับคอมโพเนนต์ภายในเส้นทางใดก็ตาม
โปรดระวังอย่าแสดงผลสถานะการโหลดล่วงหน้าให้ผู้ใช้ทราบ
react-snap
README ครอบคลุมถึงเรื่องนี้อย่างละเอียดยิ่งขึ้น