- ช่วงหลังมานี้มีแนวโน้มที่จะนำเครื่องมือ Node.js ไปเขียนใหม่ด้วยภาษาที่เร็วกว่าอย่าง Rust, Zig, Go ฯลฯ ซึ่งน่ากังวล จึงได้สรุปข้อกังวลเชิงวัตถุวิสัยไว้
[ประสิทธิภาพ]
- มองว่ายังมีโอกาสในการทำให้เครื่องมือ JavaScript เร็วขึ้นอีกมากที่ยังไม่ได้ถูกสำรวจจนหมด
- ใน ESLint, Tailwind และโครงการอื่น ๆ ยังมีจุดที่ปรับปรุงได้ง่ายอีกมาก
- บนเบราว์เซอร์ JavaScript นั้น "เร็วพอ" สำหรับเวิร์กโหลดส่วนใหญ่
- แล้วทำไมในเครื่องมือ CLI เราจึงพยายามจะทิ้ง JavaScript กัน?
การเขียนใหม่ครั้งใหญ่
- ตลอดเวลานานที่ผ่านมา ระบบนิเวศของเครื่องมือ JavaScript มุ่งเน้นที่การ "ทำให้ใช้งานได้"
- ตอนนี้ API ส่วนใหญ่เริ่มนิ่งแล้ว และทุกคนต่างต้องการ "ของเดิม แต่ให้เร็วกว่า"
- เครื่องมือใหม่อาจเร็วกว่าได้ เพราะถูกเขียนขึ้นใหม่โดยคำนึงถึงประสิทธิภาพ และมี API ที่กำหนดไว้แล้ว จึงประหยัดเวลาในการพัฒนา
- เมื่อเขียนใหม่จาก A ไปเป็น B แล้วความเร็วดีขึ้น ก็ทำให้ง่ายที่จะอ้างว่า B เร็วกว่า A
- แต่สาเหตุที่เร็วขึ้นอาจเป็นเพราะการเขียนใหม่เองก็ได้ (เพราะรอบที่สองเรารู้มากขึ้นและใส่ใจเรื่องประสิทธิภาพมากกว่าเดิม)
ไบต์โค้ดและ JIT
- ในเบราว์เซอร์ เรามักมองข้ามไปว่า JavaScript ได้ประโยชน์จากแคชไบต์โค้ดและ JIT (Just-In-Time compiler)
- หาก JavaScript ถูกแคชไว้อย่างถูกต้อง เบราว์เซอร์ก็ไม่จำเป็นต้องพาร์สและคอมไพล์ซอร์สโค้ดเป็นไบต์โค้ดอีก
- ฟังก์ชันที่ถูกรันบ่อยจะถูกปรับแต่งให้เหมาะสมยิ่งขึ้นเป็นโค้ดเครื่อง (JIT)
- แต่ในสคริปต์ Node.js แทบไม่ได้รับประโยชน์จากแคชไบต์โค้ดเลย
- อย่างไรก็ตาม ตอนนี้ใน Node ก็สามารถใช้ compile cache ได้แล้ว (ตั้งค่าตัวแปรสภาพแวดล้อม
NODE_COMPILE_CACHE)
- JIT ต้องให้ฟังก์ชันถูกรันหลายครั้งจน "ร้อน" ก่อน จึงยากที่จะเห็นประโยชน์ในสคริปต์ที่รันครั้งเดียวจบ
- ใน Pinafore เคยพยายามเปลี่ยนไลบรารี blurhash แบบ JavaScript ไปเป็นเวอร์ชัน Rust (Wasm) แต่พอถึงการวนรอบครั้งที่ 5 ความต่างด้านประสิทธิภาพก็หายไป
- อาจลองพิจารณา AOT คอมไพล์สคริปต์ Node ด้วยเครื่องมืออย่าง Porffor
- การใช้ Wasm มีประสิทธิภาพตกลงเมื่อเทียบกับเครื่องมือ native ล้วน
[การมีส่วนร่วมและความง่ายในการดีบัก]
- นี่คือความกังขาหลักต่อกระแส "เขียนทุกอย่างใหม่เป็น native"
- JavaScript เป็นภาษาที่ได้รับความนิยมเพราะมีระบบ type ที่ยืดหยุ่น เรียนรู้ง่าย และมีเบราว์เซอร์รองรับ
- ตลอดมาในระบบนิเวศ JavaScript ทั้งผู้เขียนไลบรารีและผู้ใช้ต่างก็ใช้ JavaScript ด้วยกันทั้งคู่
- สิ่งนี้ช่วยลดกำแพงในการมีส่วนร่วม
- แต่ถ้าผู้เขียนไลบรารี JavaScript หันไปใช้ภาษาอื่น ข้อดีนี้ก็จะหายไป
- นอกจากนี้ การแก้ dependency ของ JavaScript แบบโลคัลก็ทำได้ง่าย (แก้ตรงใน
node_modules ได้เลย)
- ตรงกันข้าม หากเขียนด้วยภาษา native ก็ต้อง checkout ซอร์สโค้ดออกมาและคอมไพล์เอง
- เวลา debug ไลบรารี JavaScript ก็ใช้เครื่องมือสำหรับนักพัฒนาในเบราว์เซอร์หรือดีบักเกอร์ของ Node.js ที่คุ้นเคยได้
- ใน Wasm ก็ไม่ใช่ว่าดีบักไม่ได้ แต่ต้องใช้ชุดทักษะอีกแบบหนึ่ง
[บทสรุป]
- การที่มีเครื่องมือยุคใหม่สำหรับระบบนิเวศ JavaScript เกิดขึ้นมาเป็นเรื่องที่ดี
- เครื่องมือเดิมหลายตัวช้ามาก และน่าจะได้ประโยชน์จากการแข่งขัน
- แต่ไม่ได้คิดว่า JavaScript นั้นช้าโดยเนื้อแท้ หรือไม่มีช่องทางให้ปรับปรุงอีกแล้ว
- เมื่อดูการปรับปรุงล่าสุดของเครื่องมือสำหรับนักพัฒนาใน Chromium ก็รู้สึกว่ายังไปได้อีกไกล
- น่ากังวลว่ามันอาจกลายเป็นโลกที่เป็นของนักพัฒนา Rust และ Zig เท่านั้น
- นักพัฒนา JavaScript ทั่วไปอาจรู้สึกหมดหนทางเมื่อเจอบั๊กใน build tool
- มันอาจเท่ากับกำลังสอนความหมดหวังที่เรียนรู้มาแล้วให้กับนักพัฒนาเว็บรุ่นใหม่
- นี่คือการเดินไปบนเส้นทางที่ยังไม่เคยรู้จัก และอาจนำไปสู่ผลลัพธ์ที่ไม่ตั้งใจ
- ทั้งที่ยังมีอีกเส้นทางที่เสี่ยงน้อยกว่าและอาจได้ผลลัพธ์เกือบเหมือนกัน
- แต่ดูเหมือนว่ากระแสในตอนนี้จะไม่มีทีท่าว่าจะชะลอลง
ความเห็นของ GN⁺
- การเขียนใหม่ด้วย Rust หรือ Zig อาจไม่ใช่ทางเลือกที่ดีที่สุดเสมอไป ดูเหมือนว่าในฝั่ง JavaScript ยังมีพื้นที่ให้ปรับปรุงอีกมาก เช่น compile cache
- ก็น่าตั้งคำถามว่าการทำให้นักพัฒนามือใหม่ต้องไปเจอปัญหาซับซ้อนอย่าง segfault เป็นเรื่องที่ดีจริงหรือไม่ เพราะอาจสอนให้พวกเขารู้สึกหมดหนทางมากกว่า
- ควรพิจารณาให้ดีว่าการแลกข้อดีของระบบนิเวศที่สร้างกันมานานด้วย JavaScript (เช่น การแก้ไขข้ามไลบรารีได้อย่างอิสระ สภาพแวดล้อมการดีบักที่คุ้นเคย ฯลฯ) เพื่อแลกกับความเร็ว เป็นทิศทางที่ดีจริงหรือไม่
- ก็น่าจะต้องเดินหน้าปรับปรุงไลบรารี JavaScript เดิมต่อไปด้วยเช่นกัน เพราะศักยภาพของ JavaScript ยังไม่ได้ถูกขุดค้นจนหมด
- แม้กระแสหลักอาจดูเหมือนต้านไม่อยู่ แต่ก็น่าจะยังต้องมีการถกเถียงและพิจารณาอย่างจริงจังในระดับชุมชนต่อทิศทางนี้
15 ความคิดเห็น
วิธีการดำเนินงานของร้านเล็ก ๆ กับร้านขนาดใหญ่ก็อาจต่างกันอยู่บ้างนะครับ แทนที่จะวิจารณ์การเปลี่ยนแปลงนั้นเอง ผมว่าการลองคิดดูว่าปรากฏการณ์นี้มีความหมายอย่างไรน่าจะเป็นมุมมองที่สร้างสรรค์กว่า
มันอาจดูเหมือนเปลี่ยนได้เพราะรสนิยมหรือกระแสนิยม แต่โดยปกติแล้วองค์กรก็คงไม่ได้ตัดสินใจแบบนั้นกันใช่ไหมครับ
ตัว Python หรือ JavaScript เองช้าหรือไม่? จะตอบว่าใช่ก็คงไม่เต็มปากนัก
แต่ถ้าถามว่าเครื่องมือที่ใช้ Python หรือ JavaScript ซึ่งถูกใช้งานบ่อยนั้นช้าหรือไม่? ผมคิดว่าคำตอบคือ Yes
ผมใช้อุปกรณ์พลังงานต่ำอยู่หลายเครื่อง แล้วก็มีเครื่องมือที่ช้าจนน่าหงุดหงิดอยู่เยอะจริง ๆ..
แม้แต่ฝั่งคอมมูนิตี้ Python ก็มีเรื่องเล่าแนวเดียวกันนี้วนซ้ำอยู่แทบจะเหมือนกันทุกประการ
ตัว JavaScript เองไม่ได้ถูกเขียนด้วย JavaScript แต่โดยมากแล้วนักพัฒนา JavaScript ก็ไม่ได้ใส่ใจกับส่วนนั้นนัก จะบอกว่าสำหรับ “นักพัฒนามือใหม่” หรือ “นักพัฒนาเว็บรุ่นใหม่” การที่ JavaScript ไม่ได้เขียนด้วย JavaScript ไม่ใช่ปัญหา แต่พอเครื่องมือพัฒนา JavaScript ไม่ได้เขียนด้วย JavaScript กลับกลายเป็นปัญหา แบบนี้ก็ฟังดูไม่ค่อยสมเหตุสมผลเท่าไรนัก ที่จริงแล้วนักพัฒนาที่สนใจเรื่องแบบนั้นมีอยู่เพียงส่วนน้อยมากในทั้งสองกลุ่มเสียมากกว่า
ถึงจะไม่ปฏิเสธว่าถ้าปรับแต่งประสิทธิภาพกันมากพอ สุดท้ายก็อาจทำความเร็วได้ใกล้เคียงกัน แต่คุ้มค่าจริงหรือ?
พูดง่าย ๆ คือ จากยุคที่การเขียนเครื่องมือพัฒนาด้วย JavaScript แทน C++ คุ้มค่ากว่า ได้กำลังเปลี่ยนผ่านไปสู่ยุคที่การเขียนด้วย Rust คุ้มค่ากว่าการเขียนด้วย JavaScript
วิธีที่จะรับมือกับกระแสนี้ไม่ใช่การทุ่มต้นทุนเพิ่มเพื่อผลักดันการรณรงค์ “มาปรับแต่ง JavaScript ให้ดีขึ้นกันเถอะ” แต่คือการทำให้สามารถพัฒนาเครื่องมือ JavaScript ที่มีประสิทธิภาพได้ โดยใช้ต้นทุนการพัฒนาที่ต่ำกว่าแทน (แม้จะฟังดูคล้ายกัน แต่ความต่างอยู่ที่เราจะทุ่มความพยายามไปที่ตรงไหน)
เห็นด้วยครับ ผมคิดว่าเราควรนิยามคำว่าความคุ้มค่าเสียใหม่โดยยึดผู้ใช้เครื่องมือเป็นศูนย์กลาง
ที่ผ่านมา ความคุ้มค่าน่าจะเป็นตัวชี้วัดที่คำนึงถึงนักพัฒนาเครื่องมือมากกว่าผู้ใช้เครื่องมือ ผู้ใช้เครื่องมือต้องเผชิญกับความไม่มีประสิทธิภาพและปัญหาด้านประสิทธิภาพการทำงาน แต่กลับรู้สึกว่าถูกจัดไว้เป็นเรื่องรองในลำดับความสำคัญอยู่พอสมควร ส่วนตัวผมก็ใช้ uv กับ vite ได้ดี และถ้าเป็นไปได้ก็อยากเลี่ยงเครื่องมืออย่าง pip หรือ create-react-app ครับ
ผมคิดว่าเครื่องมือ CLI ควรทำงานได้โดยไม่ต้องพึ่งรันไทม์ เลยเห็นด้วยได้ยากครับ
ถ้าจะบอกว่าสร้างไฟล์ปฏิบัติการแบบสแตนด์อโลนด้วย WASM ได้ไม่ใช่เหรอ ก็อย่างที่บทความบอกไว้ ว่าประสิทธิภาพน่าจะลดลงครับ
ผมคิดว่าเหมือนกับที่การเขียน CLI ด้วย Java ไม่ได้เป็นเรื่องแพร่หลาย JavaScript ก็คงไม่ต่างกันครับ
ดูเหมือนว่าผู้เขียนจะเข้าใจผิดว่า เพราะทั้งการพัฒนา SPA และการพัฒนาเครื่องมือ JavaScript ต่างก็ใช้ JavaScript เหมือนกัน ทักษะพื้นฐานอื่น ๆ ที่จำเป็นจึงเหมือนกันไปด้วย ผมคิดว่าเครื่องมือ JavaScript ต้องการความสามารถด้าน system programming และคอมไพเลอร์
ถึงจะเป็นภาษาเดียวกัน แต่ runtime environment ต่างกันระหว่างเบราว์เซอร์กับ NodeJS และคงมีแค่คนที่ข้ามช่องว่างนั้นได้เท่านั้นที่พอจะมีส่วนร่วมกับเครื่องมือ JavaScript ได้ แบบนี้ควรมองว่าเป็นคนละ ecosystem กันไม่ใช่หรือ
ผมคิดว่าจุดนี้ก็เหมือนกัน คือเป็นการประเมินจำนวนคนที่สามารถข้ามเส้นแบ่งระหว่างการพัฒนา SPA กับการพัฒนาเครื่องมือ JavaScript สูงเกินไป การคาดหวังให้นักพัฒนา frontend มีความรู้ในระดับใกล้เคียง system programming นั้นเกินจริง ผู้ใช้เครื่องมือก็คงเข้าใจได้แค่ข้อความ error หรืออาการที่เกิดขึ้นในระดับผิวเผินไม่ใช่หรือ ผมไม่คิดว่านี่เป็นปัญหาที่แก้ได้เพียงแค่รู้ภาษาเดียวกัน
ดูเหมือนว่ากำลังพูดปนกันระหว่างเครื่องมือกับไลบรารีนะครับ สำหรับไลบรารีผมพอจะเห็นด้วยได้ในระดับหนึ่ง แต่ถ้าเป็นเครื่องมือนี่ก็ไม่แน่ใจเท่าไร..
นักพัฒนาภาษาอื่นก็น่าจะคุ้นเคยอยู่แล้ว เพราะเครื่องมือก็มักเขียนเป็นเนทีฟกันอยู่แล้วนี่ครับ
โดยส่วนตัวแล้ว ไม่ว่าจะเป็นเครื่องมือหรือไลบรารี หากเขียนด้วย JavaScript นักพัฒนาที่คุ้นเคยกับ JavaScript ก็สามารถดีบักมันและมีส่วนร่วมได้หากจำเป็น แต่ถ้าถูกเขียนใหม่เป็น Rust การมีส่วนร่วมกับโอเพนซอร์สก็จะกลายเป็นสิ่งที่ทำได้เฉพาะนักพัฒนา Rust เท่านั้น เนื่องจากฐานของนักพัฒนา JavaScript มีขนาดใหญ่กว่า Rust อย่างท่วมท้น การที่เครื่องมือหรือไลบรารีในระบบนิเวศโอเพนซอร์สถูกเขียนด้วย JavaScript จึงอาจเป็นประโยชน์มากกว่า
ฉันคิดว่า JavaScript มีข้อจำกัดในฐานะข้อโต้แย้งหากจะเปรียบเทียบกันแบบง่าย ๆ ด้วยจำนวนผู้ใช้ภาษา เพราะสภาพแวดล้อมการรันของมันกระจัดกระจายอยู่ทั้งในเบราว์เซอร์และ NodeJS ผู้พัฒนา Spring ฝั่งแบ็กเอนด์กับผู้พัฒนา JDK รวมถึงผู้พัฒนา React/Angular/Vue กับผู้พัฒนาเครื่องมือ JavaScript มีความสนใจและจุดยืนที่ต่างกัน และเป็นความสัมพันธ์แบบผู้บริโภคกับผู้ผลิต
หากเป้าหมายคือการปรับปรุงประสิทธิภาพและการใช้งานของเครื่องมือ JavaScript โดยส่วนตัวผมคิดว่าการเปลี่ยนภาษา implementation ซึ่งเป็นเพียงเครื่องมือ ก็เป็นตัวเลือกที่สามารถเลือกได้เช่นกัน
ผมคิดว่าเป็นเรื่องยากที่จะจะแยกผู้บริโภคกับผู้ผลิตเครื่องมือพัฒนาออกจากกันอย่างชัดเจน เมื่อบริษัทมีขนาดใหญ่ขึ้น ก็มักมีหลายกรณีที่มีการปรับแต่ง toolchain หรือปลั๊กอินเพิ่มเติมให้เข้ากับกฎที่พวกเขาต้องการ หรือพัฒนาขึ้นมาเอง และในกรณีแบบนี้ ผมคิดว่าแค่การใช้ภาษาเดียวกันก็เป็นข้อได้เปรียบอย่างมาก
และก็มักมีหลายกรณีที่ผู้ใช้เครื่องมือเองสนใจการปรับปรุงหรือการพัฒนาตัวเครื่องมือ จนมีส่วนร่วมช่วยพัฒนาอย่างเป็นธรรมชาติด้วย
ผมคิดว่าคนที่เริ่มสนใจการปรับแต่ง toolchain หรือทำงานด้านนั้น กำลังทำหน้าที่เกินกว่าผู้บริโภค ไปเป็นระดับ prosumer หรือแม้แต่ผู้ผลิตเอง และในกรณีของปลั๊กอิน ผมมองว่ามันทำงานอยู่ภายใต้ข้อตกลงของปลั๊กอินระหว่างผู้ผลิตกับผู้บริโภค ในสถานการณ์แบบนั้น ผมก็เห็นด้วยว่าการใช้ภาษาเดียวกันย่อมเป็นประโยชน์กว่าการต้องจัดเตรียมรูปแบบไฟล์ตั้งค่าแยกต่างหากหรือ extension point เพิ่มเติม ทั้งในเชิงเทคนิคและในแง่ต้นทุนการสื่อสาร
อย่างไรก็ตาม ผมไม่คิดว่าปัญหาด้านประสิทธิภาพของเครื่องมือ JavaScript หรือปัญหาความหน่วงของ JIT ใน NodeJS จะอยู่ในขอบเขตการตัดสินใจของผู้บริโภค เพราะผู้ที่กำหนดสถาปัตยกรรมและสเปกการทำงานเหล่านั้นคือผู้ผลิตเครื่องมือและนักพัฒนารันไทม์
ผมสงสัยว่าการที่ JavaScript มีฐานผู้ใช้ขนาดใหญ่จะหมายความว่าจะมีนักพัฒนาที่สามารถมีส่วนร่วมกับโค้ดเบสของคอมไพเลอร์/ทรานสไพเลอร์ได้มากขึ้นจริงหรือไม่ ผมคิดว่าไลบรารี เฟรมเวิร์ก และเครื่องมือพื้นฐานนั้นเป็นคนละโลกกันโดยสิ้นเชิง
แต่การเขียนใหม่อาจเป็นเหตุผลที่ทำให้มันเร็วขึ้นก็ได้ -> พอมาย้อนคิดดูแล้ว นี่เป็นคำพูดที่จริงมาก...
ฉันเห็นด้วยกับคำพูดของเขา เพราะมันค่อนข้างเลือกใช้เฉพาะกรณีมาก
อย่างไรก็ตาม ในอีกมิติหนึ่ง การที่ยังมีแนวทางแก้ปัญหาหลากหลาย ไม่ได้มีแค่ JS ก็เป็นองค์ประกอบที่สำคัญมากในแง่ของความก้าวหน้าทางเทคโนโลยี ดังนั้นฉันคิดว่ามุมมองฝั่งตรงข้ามก็ควรได้รับความเคารพเช่นกัน!
ความคิดเห็นจาก Hacker News
มีความเห็นว่า JavaScript ช้าโดยธรรมชาติ แม้ว่าวิศวกรจำนวนมากจะพยายามทำให้มันเร็วขึ้น แต่ก็ยังช้ากว่าภาษาที่มี static type อยู่ดี สำหรับโปรแกรมขนาดใหญ่ ภาษาที่มี type ชัดเจนเหมาะสมกว่า
JavaScript ไม่ได้เรียนรู้ง่ายนัก และมีทั้งระบบ prototype และระบบ type ที่ซับซ้อน TypeScript ช่วยอุดช่องโหว่นี้ได้บ้าง แต่ก็ยังซับซ้อนอยู่ดี
แค่เปลี่ยนภาษาอย่างเดียวก็อาจเพิ่มประสิทธิภาพได้มาก เคยมีประสบการณ์เปลี่ยนระบบเดิมจาก JS และ PHP ไปเป็น Go แล้วได้ประสิทธิภาพดีขึ้น 8-10 เท่า
ความสำคัญของการประมวลผลแบบขนานมักถูกมองข้าม Rust เหมาะกับการเขียนโค้ดแบบขนาน ส่วน JS ไม่เหมาะกับงานลักษณะนี้
ปัจจุบัน JavaScript มีความเร็วใกล้เคียงกับ Java แล้ว และช้ากว่า C++ ราว 2-4 เท่า หากต้องการเพิ่มประสิทธิภาพก็ต้องก้าวออกจากพื้นที่ที่คุ้นเคย
โปรแกรมที่เขียนด้วย Rust, Zig และ Go สามารถตรวจสอบซอร์สโค้ดและคอมไพล์ได้ง่าย การเรียนรู้ภาษาใหม่ยังส่งผลต่อวิธีคิดในการแก้ปัญหา
ยังคิดว่ายังไม่ได้ใช้ศักยภาพทั้งหมดในการเพิ่มประสิทธิภาพให้เครื่องมือ JavaScript และการสร้างบนรากฐานที่ดีกว่าย่อมมีประสิทธิภาพกว่า
Rspack เป็นเวอร์ชันเขียนใหม่ของ Webpack ที่เข้ากันได้และพัฒนาด้วย Rust โดยมีประสิทธิภาพดีขึ้น 5-10 เท่า และสามารถใช้แทน Webpack ได้ง่าย
การแก้ไข dependency ของ JavaScript ในเครื่องทำได้ง่าย แต่ Rust มีบั๊กน้อยกว่าจึงแทบไม่จำเป็นต้องแก้ Rust เรียนรู้ยาก แต่จะช่วยให้เป็นโปรแกรมเมอร์ที่ดีขึ้นในภาษาอื่นด้วย