เนื่องจากเราสร้างเว็บไซต์ที่อาศัย JavaScript มากขึ้น บางครั้งเราจึงจ่ายเงินสำหรับสิ่งที่ส่งไปในรูปแบบที่เราไม่สามารถเห็นได้เสมอไป ในบทความนี้ เราจะอธิบายว่าเหตุใดการมีวินัยจึงช่วยได้ในกรณีที่คุณต้องการให้เว็บไซต์โหลดและมีการโต้ตอบอย่างรวดเร็วบนอุปกรณ์เคลื่อนที่ การส่ง JavaScript ที่น้อยลงอาจหมายถึงเวลาในการส่งเครือข่ายน้อยลง ลดเวลาในการคลายการบีบอัดโค้ด และประหยัดเวลาในการแยกวิเคราะห์และคอมไพล์ JavaScript นี้
เครือข่าย
เมื่อนักพัฒนาซอฟต์แวร์ส่วนใหญ่คิดเกี่ยวกับต้นทุนของ JavaScript ก็ให้คำนึงถึงเรื่องนี้ในแง่ของค่าใช้จ่ายในการดาวน์โหลดและการดำเนินการ การส่งจำนวนไบต์ JavaScript ผ่านสายมากขึ้นจะทำให้การเชื่อมต่อของผู้ใช้ช้าลง
ซึ่งอาจเป็นปัญหาเนื่องจากประเภทการเชื่อมต่อเครือข่ายที่มีประสิทธิภาพที่ผู้ใช้มีอาจไม่ใช่ 3G, 4G หรือ Wi-Fi คุณสามารถเชื่อมต่อ Wi-Fi ร้านกาแฟ แต่เชื่อมต่อกับฮอตสปอตเครือข่ายมือถือด้วยความเร็ว 2G ได้
คุณลดค่าใช้จ่ายในการโอนเครือข่ายของ JavaScript ได้ผ่านช่องทางต่อไปนี้
- ส่งเฉพาะโค้ดที่ผู้ใช้ต้องใช้
- ใช้การแยกโค้ดเพื่อแยก JavaScript ว่าสิ่งใดสำคัญและสิ่งใดที่ไม่สำคัญ โปรแกรมสร้างชุดโมดูล เช่น Webpack รองรับการแยกโค้ด
- การโหลดแบบ Lazy Loading ในโค้ดที่ไม่สำคัญ
- การลดขนาด
- ใช้ UglifyJS สำหรับการลดขนาดโค้ด ES5
- ใช้ babel-minify หรือ uglify-es เพื่อลดขนาด ES2015 ขึ้นไป
- การบีบอัด
- การนำโค้ดที่ไม่ได้ใช้ออก
- ระบุโอกาสสำหรับโค้ดที่สามารถนำออกหรือโหลดแบบ Lazy Loading ด้วยการครอบคลุมโค้ดสำหรับเครื่องมือสำหรับนักพัฒนาเว็บ
- ใช้ babel-preset-env และรายการเบราว์เซอร์เพื่อหลีกเลี่ยงการแปลงฟีเจอร์ที่มีอยู่แล้วในเบราว์เซอร์สมัยใหม่ นักพัฒนาซอฟต์แวร์ขั้นสูงอาจพบว่าการวิเคราะห์แพ็กเกจ WebP อย่างระมัดระวังจะช่วยระบุโอกาสในการตัดทรัพยากร Dependency ที่ไม่จำเป็น
- สำหรับการถอดโค้ด โปรดดู Tree-shaking, การเพิ่มประสิทธิภาพขั้นสูงของ Closure Compiler และไลบรารี ที่ตัดปลั๊กอิน เช่น lodash-babel-plugin หรือ ContextReplacementPlugin ของไลบรารี เช่น Moment.js
- การแคชโค้ดเพื่อลดการเดินทางในเครือข่าย
- ใช้การแคช HTTP เพื่อให้เบราว์เซอร์แคชการตอบสนองอย่างมีประสิทธิภาพ กำหนดอายุการใช้งานที่เหมาะสมที่สุดสำหรับสคริปต์ (อายุสูงสุด) และโทเค็นการตรวจสอบความถูกต้อง (ETag) เพื่อหลีกเลี่ยงการโอนไบต์ที่ไม่มีการเปลี่ยนแปลง
- การแคช Service Worker ทำให้เครือข่ายแอปมีความยืดหยุ่นและช่วยให้คุณเข้าถึงฟีเจอร์อย่างแคชโค้ดของ V8 ได้อย่างรวดเร็ว
- ใช้การแคชในระยะยาวเพื่อหลีกเลี่ยงการดึงทรัพยากรที่ไม่มีการเปลี่ยนแปลงอีกครั้ง หากใช้ Webpack โปรดดูการแฮชชื่อไฟล์
แยกวิเคราะห์/คอมไพล์
เมื่อดาวน์โหลดแล้ว ค่าใช้จ่ายที่หนักที่สุดอย่างหนึ่งของ JavaScript คือเวลาที่เครื่องมือ JS จะแยกวิเคราะห์/คอมไพล์โค้ดนี้ ในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome การแยกวิเคราะห์และคอมไพล์เป็นส่วนหนึ่งของเวลา "สคริปต์" สีเหลืองในแผงประสิทธิภาพ
แท็บ "ล่างขึ้นบน" และ "แผนผังการเรียกใช้" จะแสดงเวลาของการแยกวิเคราะห์/คอมไพล์ที่แน่นอน ดังนี้
แต่ทำไมสิ่งนี้จึงสำคัญ
การใช้เวลาในการแยกวิเคราะห์/คอมไพล์โค้ดเป็นเวลานานอาจทำให้ผู้ใช้โต้ตอบกับเว็บไซต์ได้ช้าลงอย่างมาก ยิ่งคุณส่ง JavaScript มากเท่าไร ก็ยิ่งใช้เวลาในการแยกวิเคราะห์และคอมไพล์นานขึ้นเท่านั้นก่อนที่เว็บไซต์จะโต้ตอบ
ไบต์ต่อไบต์ JavaScript ที่เบราว์เซอร์ประมวลผลมีต้นทุนสูงกว่ารูปภาพหรือเว็บฟอนต์ที่มีขนาดเท่ากัน — Tom Dale
เมื่อเทียบกับ JavaScript แล้ว การประมวลผลรูปภาพที่มีขนาดเท่ากัน (ยังคงต้องถอดรหัส) แต่โดยเฉลี่ยแล้ว ฮาร์ดแวร์อุปกรณ์เคลื่อนที่ JS มีแนวโน้มที่จะส่งผลเสียต่อการโต้ตอบของหน้ามากกว่าเมื่อเทียบกับ JavaScript
เมื่อพูดถึงการแยกวิเคราะห์และคอมไพล์ที่ช้า บริบทก็ถือเป็นเรื่องสำคัญ เรากำลังพูดถึงโทรศัพท์มือถือทั่วไปที่นี่ ผู้ใช้ทั่วไปอาจมีโทรศัพท์ที่มี CPU และ GPU ช้า ไม่มีแคช L2/L3 และอาจมีข้อจำกัดหน่วยความจำด้วย
บางครั้งความสามารถของเครือข่ายและความสามารถของอุปกรณ์อาจไม่ตรงกัน ผู้ใช้ที่มีการเชื่อมต่อ Fiber ที่น่าทึ่งไม่จำเป็นต้องมี CPU ที่ดีที่สุดสำหรับการแยกวิเคราะห์และประเมิน JavaScript ที่ส่งไปยังอุปกรณ์ของตน ในทางกลับกันเช่นกัน... การเชื่อมต่อเครือข่ายที่แย่มาก แต่เป็น CPU ที่เร็วมากๆ — Kristofer Baxter, LinkedIn
ด้านล่างนี้เป็นค่าใช้จ่ายในการแยกวิเคราะห์ JavaScript ที่บีบอัด (แบบง่าย) ประมาณ 1 MB ในฮาร์ดแวร์ระดับไฮเอนด์และต่ำ เวลาในการแยกวิเคราะห์/คอมไพล์โค้ดระหว่างโทรศัพท์ที่เร็วที่สุดในตลาดกับโทรศัพท์ทั่วไปนั้นแตกต่างกัน 2-5 เท่า
แล้วเว็บไซต์ที่มีอยู่จริงอย่าง CNN.com ล่ะ
สำหรับ iPhone 8 ระดับไฮเอนด์ ใช้เวลาเพียงประมาณ 4 วินาทีในการแยกวิเคราะห์/คอมไพล์ JS ของ CNN เทียบกับประมาณ 13 วินาทีสำหรับโทรศัพท์ทั่วไป (Moto G4) ซึ่งอาจส่งผลต่อความเร็วที่ผู้ใช้โต้ตอบกับเว็บไซต์นี้ได้อย่างเต็มที่
ข้อมูลนี้เน้นให้เห็นถึงความสำคัญของการทดสอบกับฮาร์ดแวร์ทั่วไป (เช่น MotoG4) แทนที่จะแสดงเฉพาะโทรศัพท์ที่อาจอยู่ในกระเป๋า บริบทมีความสำคัญอย่างไร: เพิ่มประสิทธิภาพให้เหมาะกับอุปกรณ์และสภาพเครือข่ายที่ผู้ใช้มี
เราส่ง JavaScript มากเกินไปจริงๆ ใช่ไหม เอ่อ อาจจะ :)
การใช้ที่เก็บถาวรของ HTTP (เว็บไซต์ประมาณ 500, 000 อันดับแรก) เพื่อวิเคราะห์สถานะของ JavaScript บนอุปกรณ์เคลื่อนที่ ทำให้เราเห็นได้ว่า 50% ของเว็บไซต์ใช้เวลามากกว่า 14 วินาทีในการโต้ตอบ เว็บไซต์เหล่านี้ใช้เวลาไม่เกิน 4 วินาทีในการแยกวิเคราะห์และคอมไพล์ JS
คำนึงถึงระยะเวลาที่ใช้ในการดึงข้อมูลและประมวลผล JS และทรัพยากรอื่นๆ ด้วย จึงอาจไม่น่าแปลกใจที่ผู้ใช้อาจต้องรอสักระยะหนึ่งก่อนที่หน้าเว็บจะพร้อมใช้ เราปรับปรุงให้ดีขึ้นได้อย่างแน่นอน
การนำ JavaScript ที่ไม่สำคัญออกจากหน้าเว็บจะช่วยลดเวลาในการส่ง การแยกวิเคราะห์และคอมไพล์ที่ใช้ CPU มาก รวมถึงอาจทำงานที่ต้องใช้หน่วยความจำได้ วิธีนี้จะช่วยให้หน้าเว็บโต้ตอบได้เร็วขึ้น
เวลาดำเนินการ
ไม่ใช่แค่การแยกวิเคราะห์และคอมไพล์ที่มีต้นทุน การดำเนินการ JavaScript (การเรียกใช้โค้ดเมื่อแยกวิเคราะห์/คอมไพล์แล้ว) เป็นการดำเนินการอย่างหนึ่งที่จะต้องเกิดขึ้นในเทรดหลัก เวลาในการดำเนินการที่นานอาจทำให้ผู้ใช้โต้ตอบกับเว็บไซต์ของคุณได้เร็วยิ่งขึ้น
หากสคริปต์ทำงานเกิน 50 มิลลิวินาที เวลาในการโต้ตอบจะล่าช้ากว่าทั้งหมดในการดาวน์โหลด คอมไพล์ และเรียกใช้ JS —Alex Russell
เพื่อแก้ปัญหานี้ JavaScript จะได้รับประโยชน์จากส่วนเล็กๆ เพื่อหลีกเลี่ยงการล็อกเทรดหลัก ลองดูว่าคุณจะลดปริมาณงานที่ต้องทำระหว่างการดำเนินการได้หรือไม่
ค่าใช้จ่ายอื่นๆ
JavaScript สามารถส่งผลกระทบต่อประสิทธิภาพของหน้าเว็บในลักษณะอื่นๆ ได้ ดังนี้
- ความทรงจำ หน้าอาจไม่สมบูรณ์หรือหยุดชั่วคราวเนื่องจาก GC (การเก็บรวบรวมข้อมูลขยะ) เมื่อเบราว์เซอร์เรียกคืนหน่วยความจำ การดำเนินการ JS จะหยุดชั่วคราวเพื่อให้เบราว์เซอร์ที่รวบรวมไฟล์ขยะสามารถหยุดการดำเนินการชั่วคราวได้บ่อยกว่าที่เราอาจต้องการ โปรดหลีกเลี่ยงการรั่วไหลของหน่วยความจำและการหยุดชั่วคราวบ่อยๆ สำหรับ GCP เพื่อให้หน้าไม่ราบรื่น
- ในระหว่างรันไทม์ JavaScript ที่ใช้เวลานานอาจบล็อกเทรดหลักซึ่งทำให้หน้าไม่ตอบสนอง การแบ่งงานออกเป็นส่วนเล็กๆ (โดยใช้
requestAnimationFrame()
หรือrequestIdleCallback()
ในการกำหนดเวลา) จะช่วยลดปัญหาการตอบสนองได้ ซึ่งจะช่วยปรับปรุงการโต้ตอบกับ Next Paint (INP)
รูปแบบสำหรับการลดต้นทุนการนำส่ง JavaScript
เมื่อพยายามรักษาเวลาในการแยกวิเคราะห์/คอมไพล์และการส่งของเครือข่ายให้ JavaScript ช้า ก็มีรูปแบบที่ช่วยเหลือคุณได้ เช่น การแบ่งข้อมูลตามเส้นทาง หรือ PRPL
PRPL
PRPL (พุช, แสดงผล, แคชล่วงหน้า, การโหลดแบบ Lazy Loading) เป็นรูปแบบที่เพิ่มประสิทธิภาพสำหรับการโต้ตอบผ่านการแยกโค้ดและการแคชเชิงรุก
มาลองดูภาพผลลัพธ์ที่จะได้รับกันเลย
เราวิเคราะห์เวลาในการโหลดของเว็บไซต์บนอุปกรณ์เคลื่อนที่ยอดนิยมและ Progressive Web App โดยใช้สถิติการเรียกใช้รันไทม์ของ V8 ดังที่เราเห็นแล้วว่าเวลาในการแยกวิเคราะห์ (แสดงเป็นสีส้ม) เป็นส่วนสำคัญที่เว็บไซต์เหล่านี้ใช้เวลาอยู่
Wego ซึ่งเป็นเว็บไซต์ที่ใช้ PRPL จัดการเวลาในการแยกวิเคราะห์เส้นทางให้ต่ำและโต้ตอบได้อย่างรวดเร็ว เว็บไซต์อื่นๆ จำนวนมากที่กล่าวมา ได้เปลี่ยนมาใช้การแยกโค้ดและงบประมาณด้านประสิทธิภาพเพื่อพยายามลดต้นทุน JS
การเปิดเครื่องแบบโปรเกรสซีฟ
เว็บไซต์จำนวนมากเพิ่มประสิทธิภาพระดับการเข้าถึงเนื้อหา แต่ต้องมีการโต้ตอบราคาแพง บางครั้งนักพัฒนาซอฟต์แวร์ใช้การแสดงผลฝั่งเซิร์ฟเวอร์เพื่อแสดงผลครั้งแรกอย่างรวดเร็วเมื่อคุณมีแพ็กเกจ JavaScript ขนาดใหญ่ บางครั้งนักพัฒนาซอฟต์แวร์จะใช้การแสดงผลฝั่งเซิร์ฟเวอร์ จากนั้น "อัปเกรด" เพื่อแนบเครื่องจัดการเหตุการณ์เมื่อมีการดึงข้อมูล JavaScript ในที่สุด
โปรดระวัง ปัญหานี้มีต้นทุนเอง ตามปกติ คุณ 1) ตอบสนอง HTML ที่ใหญ่กว่าซึ่งสามารถกระตุ้นการโต้ตอบของเรา 2) อาจทำให้ผู้ใช้อยู่ในวุ่นวายที่ประสบการณ์ครึ่งหนึ่งไม่สามารถโต้ตอบได้จนกว่า JavaScript จะเสร็จสิ้น
Progressive Bootstrapping อาจเป็นวิธีการที่ดีกว่า ส่งหน้าที่มีการทำงานเพียงเล็กน้อย (ประกอบด้วย HTML/JS/CSS ที่จำเป็นสำหรับเส้นทางปัจจุบัน) เมื่อมีทรัพยากรเข้ามามากขึ้น แอปก็จะโหลดแบบ Lazy Loading และปลดล็อกฟีเจอร์เพิ่มเติมได้
การโหลดโค้ดให้ได้สัดส่วนกับสิ่งที่ปรากฏในมุมมองคือสิ่งศักดิ์สิทธิ์ PRPL และ Progressive Bootstrapping เป็นรูปแบบที่ช่วยให้บรรลุเป้าหมายนี้
บทสรุป
ขนาดการรับส่งข้อมูลเป็นสิ่งสำคัญสำหรับเครือข่ายระดับล่าง เวลาแยกวิเคราะห์นั้นสำคัญ สำหรับอุปกรณ์ที่เชื่อมโยงกับ CPU การรักษาให้มีค่าต่ำเช่นนี้
ทีมต่างๆ ประสบความสำเร็จในการใช้งบประมาณด้านประสิทธิภาพที่เข้มงวดเพื่อทำให้เวลาในการส่งผ่าน JavaScript และแยกวิเคราะห์/คอมไพล์ต่ำ ดู "Can You Afford It?:" ของ Alex Russell งบประมาณตามประสิทธิภาพจริงบนเว็บ" สำหรับแนวทางเกี่ยวกับงบประมาณสำหรับอุปกรณ์เคลื่อนที่
หากคุณกำลังสร้างเว็บไซต์ที่กำหนดเป้าหมายอุปกรณ์เคลื่อนที่ ให้พยายามอย่างเต็มที่ในการพัฒนาฮาร์ดแวร์ตัวแทน ลดเวลาในการแยกวิเคราะห์/คอมไพล์ JavaScript ให้น้อย และนำงบประมาณประสิทธิภาพมาใช้เพื่อให้ทีมติดตามดูค่าใช้จ่าย JavaScript ของตนได้
ดูข้อมูลเพิ่มเติม
- Chrome Dev Summit 2017 - แนวทางปฏิบัติแนะนำเกี่ยวกับการโหลดที่ทันสมัย
- ประสิทธิภาพการเริ่มต้น JavaScript
- การแก้ไขวิกฤติประสิทธิภาพ ในเว็บ — Nolan Lawson
- คุณพอจะมีค่าใช้จ่ายได้ไหม งบประมาณด้านประสิทธิภาพ การใช้งานจริง — Alex Russell
- การประเมินเฟรมเวิร์กเว็บและ ไลบรารี — Kristofer Baxter
- ผลลัพธ์ของการทดสอบกับ Brotli ของ Cloudflare สำหรับการบีบอัด (โปรดสังเกตด้วยว่า Brotli แบบไดนามิกที่มีคุณภาพสูงกว่าอาจทำให้การแสดงผลหน้าเริ่มต้นล่าช้า ดังนั้นโปรดประเมินอย่างรอบคอบ คุณอาจต้องบีบอัด แบบคงที่แทน)
- สัญญาซื้อขายล่วงหน้าด้านประสิทธิภาพ — Sam Saccone