เหตุใดวิธีแก้ปัญหาเว็บแอปที่ช้าจึงไม่ใช่ชุดเครื่องมือที่ซับซ้อนกว่านี้

ก่อนหน้านี้ฉันกำลังทำงานกับแอป Angular สิ่งที่ทำให้ฉันทึ่งคือ Angular ไม่ได้เป็นเพียงเฟรมเวิร์กเท่านั้น แต่ยังเป็นแพลตฟอร์มทั้งหมดที่สร้างขึ้นบนแพลตฟอร์มเว็บอีกด้วย เหตุผลเบื้องหลังก็คือเพื่อให้นักพัฒนามีวิธีการสร้างแอปบนแพลตฟอร์มต่างๆ ที่เป็นหนึ่งเดียว แต่การใช้สิ่งที่เป็นนามธรรมนี้มีค่าใช้จ่ายเท่าไร?

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

บางทีสิ่งที่สำคัญที่สุดคือหมายความว่ามีเลเยอร์ของ JavaScript ที่ทำงานระหว่างโค้ดแอปพลิเคชันของคุณกับเบราว์เซอร์ที่ใช้แพลตฟอร์ม Angular อย่างหลีกเลี่ยงไม่ได้ สิ่งนี้ส่งผลต่อประสิทธิภาพอย่างไร

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

เราจะทำให้สิ่งต่าง ๆ ง่ายขึ้น…และเร็วขึ้นได้ไหม?

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

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

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

แอพและส้ม

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

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

ทั้ง Angular และ Polymer มาพร้อมกับชุดเครื่องมือของตัวเองเพื่อช่วยนักพัฒนา สิ่งที่โดดเด่นที่สุดคือ ทั้งสองมีเครื่องมือบรรทัดคำสั่ง (CLI) ที่สามารถใช้เพื่อบูตโปรเจ็กต์ใหม่และสร้างแอปสำหรับการปรับใช้ โพลีเมอร์ยังมีคุณสมบัติคล้ายเฟรมเวิร์กบางอย่าง เช่น การรองรับการกำหนดเส้นทาง

การตั้งค่าการทดสอบของฉัน

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

แอปพลิเคชันเชิงมุมใช้ "Kendo Grid" และ "แผนภูมิ" นอกเหนือจากเฟรมเวิร์ก Angular หลัก ในทางกลับกัน แอป Polymer จะใช้ "Vaadin Grid" และ "Charts" แม้ว่าส่วนประกอบจะไม่เหมือนกัน แต่ก็มีความซับซ้อนและฟังก์ชันการทำงานใกล้เคียงกันเพียงพอที่จะใช้สำหรับการเปรียบเทียบนี้

ฉันสร้างแอปพลิเคชันตามคำแนะนำสำหรับรุ่นที่ใช้งานจริง สำหรับ Angular 2 นั่นหมายถึงการใช้การคอมไพล์ล่วงหน้าและโหมดการผลิตล่วงหน้า (AOT) ในบิลด์ (ng build --aot --prod) สำหรับโพลีเมอร์ ฉันใช้ polymer build เพื่อสร้างบิลด์แบบรวม (เชื่อมการพึ่งพาให้เป็นไฟล์น้อยที่สุด) แอปทั้งสองใช้การโหลดแบบ Lazy Loading ต่อการดู กระบวนการสร้างแอป Polymer ได้สร้าง Service Worker เพิ่มเติมซึ่งจะโหลดมุมมองที่ตามมาล่วงหน้าลงในแคชในขณะที่ผู้ใช้เข้าสู่ระบบ

แอปพลิเคชันทั้งสองให้บริการโดยเปิดใช้งาน Gzip และสื่อสารกับ REST API เดียวกันที่โฮสต์บน localhost เพื่อให้การวัดที่สมจริงยิ่งขึ้น ฉันใช้การเชื่อมต่อ "3G ที่ดี" จำลองกับ "อุปกรณ์ระดับไฮเอนด์" ใน Chrome Dev Tools

ฉันรันการทดสอบทั้งหมดด้วย Chrome ฉันยังทำการทดสอบเปรียบเทียบบน webpagetest.org กับเวอร์ชันที่ใช้งานบนหน้า GitHub

สิ่งนี้ไปเร็วแค่ไหน?

มีผู้ชนะที่ชัดเจนมากในแง่ของความเร็วในการโหลดเริ่มต้น แอปที่ใช้โพลีเมอร์มีรูปลักษณ์ที่สมบูรณ์และพร้อมที่จะโต้ตอบภายในเวลาเพียง 0.8 วินาที แอป Angular ใช้เวลานานกว่า 4 วินาที มากจึงจะเสร็จ (4.8 วินาที) สำหรับการโหลดครั้งแรก โพลีเมอร์เร็วกว่า Angular ถึง 6 เท่า

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

สำหรับการโหลดครั้งแรก โพลีเมอร์เร็วกว่า Angular ถึง 6 เท่า

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

สิ่งที่น่าสนใจคือแอปจะโหลดเร็วขึ้นเมื่อใช้ Safari และ Polyfill ของ Web Components:

แอพทั้งสองมีขนาดเท่ากันในแง่ของการดาวน์โหลด (Polymer: 630kB, Angular: 689kB) และบรรทัดของโค้ด (Polymer: 1999 บรรทัด, Angular: 1953 บรรทัด)

สามารถดูการทดสอบฉบับเต็มได้ที่นี่

แล้วการเรนเดอร์ล่วงหน้าล่ะ?

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

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

ควรสังเกตว่า Polymer ไม่รองรับการเรนเดอร์ล่วงหน้า แต่ทีม Polymer กลับสนับสนุนให้ใช้ "รูปแบบ PRPL" เพื่อให้ได้ความเร็วที่เทียบเท่ากับการเรนเดอร์ล่วงหน้า โดยไม่ต้องเพิ่มความซับซ้อนในการรันแอปทั้งบนเซิร์ฟเวอร์และในเบราว์เซอร์

ข้อสรุป

Web Components ทำงานรวดเร็ว สำหรับการโหลดครั้งแรก ฉันสามารถเร่งความเร็วได้ถึง 6 เท่าเมื่อเทียบกับแอปเดียวกันที่ใช้งานใน Angular และฉันสามารถเร่งความเร็วนี้ได้ด้วยชุดเครื่องมือที่ง่ายกว่ามาก — ไม่ต้องคอมไพล์ AOT ไม่ต้องเรนเดอร์ล่วงหน้า

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

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

แหล่งที่มาของทั้งสองแอปนั้นอยู่บน GitHub:

แอปโพลีเมอร์

แอปเชิงมุม

เผยแพร่ครั้งแรกที่ vaadin.com