บันทึกการย้ายเข้าสู่ Angular 4.0 ของเว็บไซต์ฟังใจ

Worapong Malaiwong
Fungjai
Published in
3 min readAug 28, 2017

ขนาด Thailand ยัง 4.0 ทำไมฟังใจจะ 4.0 บ้างไม่ได้

หน้าเว็บฟังใจแบบปัจจุบัน (Fungjai 4.0)

สวัสดีครับ เมื่อช่วงเดือนมิถุนายน-สิงหาคม 2560 ผมได้มีโอกาสเข้าฝึกงานที่ฟังใจ โดยตำแหน่งที่ผมเข้าไปฝึกนั่นก็คือ Front-End Developer ซึ่งได้พบเพื่อนใหม่ที่ฝึกงานตำแหน่งเดียวกันนั่นก็คือเจ้าจอห์นนั่นเอง สิ่งที่ได้รับมอบหมายให้ทำนั้น ก็ตามชื่อบล็อกนี่แหละครับ ฮ่าๆๆ

ปัญหาที่พบจากเว็บเก่าสิ่งที่ใช้แก้ปัญหา

ปัญหาของเว็บไชต์ที่ทุกคนมักจะเจอเวลาเข้าใช้งานเว็บไซต์มีอาการกะพริบครับ

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

ถัดไปก็คือ Angular ที่ใช้นั้นค่อนข้างเก่าแล้วคือ Angular 2 RC4 ถ้าหากมองในอนาคตคงไม่เหมาะเท่าไหร่ที่จะใช้ยาวๆ (ตอนที่เขียนบล็อกนี้ล่าสุดคือเวอร์ชั่น 4.3.6) เราควรก้าวไปใช้เวอร์ชั่นที่เสถียรดีกว่า ซึ่งจริงๆ แล้วก็เป็นผลดีกับประสิทธิภาพของเว็บครับ นอกจากที่เราจะอัพเดทตัวเวอร์ชั่นของ Angular แล้ว ผมก็ได้ไปเจอสิ่งหนึ่งมา เป็นการรวมเทคนิคการรีดประสิทธิภาพของ Angular ว่าอะไรควรทำไม่ทำ เขียนโดยคุณ Minko Gechev ซึ่งเขียนได้ดีทีเดียว ต้องขอขอบคุณด้วยครับ :D ในกรณีของผมอาจจะไม่ได้ทำตามทั้งหมด เพราะบางเทคนิคก็กระทบกับโปรเจคพอสมควรครับ เนื่องด้วยระยะเวลาฝึกงานของผม

เนื่องจากจอห์นได้เข้ามาฝึกงานก่อนผม 1 สัปดาห์ ซึ่งจอห์นเองก็ได้ศึกษาค้นคว้าหาข้อมูลจนได้มาพบกับสิ่งๆ หนึ่ง นั่นก็คือเจ้า Preboot นั่นเอง

เพราะว่าเว็บฟังใจใช้การเทคนิค Server-side Rendering ในการวาดหน้าเว็บคูลๆ ให้เราได้ใช้งาน แต่ทว่าก็เกิดปัญหาอย่างที่ได้กล่าวเอาไว้ แล้วเราได้ตัวช่วยดีๆ อย่าง Preboot เข้ามาแก้ปัญหานี้ให้กับเรา

Source: http://laco0416.github.io/slides/a-way-for-happy-angular-days/#/32

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

ต่อไปก็เป็นในส่วนของพวก SEO เนื่องจากแต่ก่อนเวลา Search จาก Google แล้วมักจะขึ้นผลลัพธ์แบบนี้

ผลลัพธ์เมื่อ Search จาก Google (Before)

จะเห็นได้ว่าส่วนของ Title นั้นแสดงผลได้ไม่เป็นไปตามที่ต้องการ ซึ่งสิ่งที่ควรจะเป็นก็คือ

ผลลัพธ์เมื่อ Search จาก Google (After)

ซึ่งเป็นผลมาจากตัว Angular Universal ในสมัยก่อนยังไม่ได้มีตัวจัดการ Meta Tag จากทาง Angular โดยตรง พี่ๆ ในทีมก็เลยทำการเขียนตัว Meta Tag Builder ขึ้นมาเองโดยการให้มันเขียนแทรกส่วน head ของเว็บ แต่ก็สามารถทำงานได้ดีในระดับนึง จนกระทั่ง Angular ได้ออกเวอร์ชั่น 4 ก็มีการพัฒนาตัว Meta Service อย่างเป็นทางการเพื่อจัดการพวก Meta tag ตรงนี้จอห์นก็ได้ทำการย้ายจากระบบเก่ามาใช้งานของใหม่ที่ Angular มีให้ ซึ่งผลลัพธ์ก็ออกมาด้วยดี ส่วนมากขึ้นผลลัพธ์เป็นแบบใหม่กันหมดแล้ว

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

Source: https://youtu.be/m2a9hlUFRhg?t=8m49s

จากการหาข้อมูลในหลายๆ แหล่ง พบว่ามันทำตัวเป็น Proxy ก่อนเข้าสู่ Server ของเว็บจริงๆ ก็เลยใช้งานมันให้ทำการ Cache เว็บในส่วนที่เป็น Static Content (พวก Gtaphics, CSS, Font, Script ต่างๆ บลาๆๆ) โดยใช้ Tools ช่วยที่ทำให้ชีวิตง่ายขึ้นก็คือเจ้า Workbox นั่นเอง โดยเราสามารถให้มัน Scan file ตามเงื่อนไขไฟล์ที่เราต้องการแล้วเตรียมเป็น Script ให้เราจากนั้นเราจะจัดการยังไงก็แล้วแต่เราเลย Doc ของมันสามารถดูในเว็บได้เลย (โดยส่วนตัวผมใช้ Plugins ที่ใช้ร่วมกับ Webpack ก็ทำให้ชีวิตดียิ่งขึ้นไปอีก) ซึ่งจากการใช้งานจริงและในช่วงของรายการ The Unicorn Startup ออกอากาศพบว่าการใช้ทรัพยาการของเว็บตัวใหม่มีประสิทธิภาพดีกว่าตัวเก่าครับ (แต่ขอเอาใจช่วย Streaming Server นะครับ ได้ข่าวว่าลุยศึกหนักเลยทีเดียว)

ขั้นตอนการย้าย

เริ่มจากการสร้าง Angular Project ใหม่แยกขึ้นมา เหตุผลที่สร้างเพราะว่าตัว Package มีการเปลี่ยนแปลงเยอะมาก (ทั้งตัวเก่าที่ใช้ 2 RC และตัว Angular Universal) อีกทั้งโค้ดเก่ามีส่วนที่ไม่ได้ใช้งานจริงก็เลยทำการย้ายเฉพาะส่วนที่ใช้งานจริงและสำหรับผมการย้ายแบบนี้ทำให้ผมเรียนรู้โครงสร้างการทำงานได้ไว้ขึ้น เพราะมันชอบฟ้องส่วนประกอบขาดๆ หายๆ นั่นเอง ฮ่าๆๆ

จากนั้นเราก็ทำการ eject ตัว Project ที่ default มันพึ่งพา angular-cli เป็นหลัก มาใช้ webpack แบบเต็มตัว เนื่องจากว่าเรามีการใช้ plugins เข้ามาช่วยในการ build เช่นพวก extract css หรืออะไรหลายๆ อย่าง จึงจำเป็นต้องใช้เพราะปรับแต่งได้หลากหลายกว่า

เมื่อเราได้ config ตัว Project เปล่าๆ ของเราเสร็จแล้ว เราก็ทำการเริ่มย้ายโค้ดจาก Project เก่าที่เป็น Angular 2 RC4 มาอยู่ภายใต้ Project ใหม่ที่เป็น Angular 4 โดยไล่จากหน้าแรกๆ แล้วดูตาม Component ที่ใช้งานจริง

โดยรวมแล้วโค้ดไม่ได้เปลี่ยนแปลงแบบยิ่งใหญ่มโหฬาร แต่ก็มีการเปลี่ยนแปลงในหลายๆ ส่วนบ้าง เช่น ทำการจัดระเบียบพวก Component โดยทำการรวมกลุ่มเป็นหมวด Module เปลี่ยนคำสั่งที่เก่าที่ล้าสมัยมาใช้ตามคำแนะนำของ Angular 4 ตัดส่วนโค้ดที่ไม่จำเป็นออก เพิ่มโค้ดที่ในการแก้ปัญหาของเว็บ ส่วนที่คิดว่าเปลี่ยนเยอะสุดคิดว่าน่าจะเป็นพวก Angular Universal เพราะว่ามีการเปลี่ยนแปลง Package และวิธีการเขียนอยู่บ้าง

เมื่อทำการย้ายเสร็จแล้วและทำการทดสอบโดยการใช้งานทุกส่วนของเว็บไซต์จนคิดว่าไม่น่ามีปัญหาอะไรแล้ว ผมก็ทำการติดตั้งในส่วนของ Service Worker ทำให้เว็บนั้นสามารถใช้งานแบบออฟไลน์ได้ (แต่ถ้าจะฟังเพลง ดูชาร์ตก็ต้องต่อเน็ตอยู่ดีนะจ๊ะ) ผลดีของมันก็คือลดภาระการโหลดตัวเว็บจาก Server และผู้ใช้จะไม่มีโอกาสได้เจอกับไดโนเสาร์อีกแล้ว T_T

พอเว็บเริ่มจะนิ่งๆ แล้วเราก็ส่งเว็บให้พี่เค้าทำการขึ้นเว็บบน Server ที่มีอยู่ ซึ่งช่วงระยะแรกๆ เราใช้ Enviroment แบบ Dev พบข้อผิดพลาดอะไรเราก็แก้ตาม ลองพวก Performance เทียบกับเว็บไซต์จริงนะขณะนั้น ผลก็เป็นที่น่าพอใจ จากนั้นก็เราก็ลองไปใช้ Enviroment แบบ Staging ก็จะมีค่าต่างกันบ้าง และสุดท้ายก็ใช้แบบ Production ซึ่งถ้าเว็บโอเคแล้วก็รอขึ้น Production จริงกันได้เลย

สรุป

เอาจริงๆ แล้วนี่ก็เป็นการเขียนบล็อกครั้งแรกในชีวิตของผมเหมือนกัน ก็หวังว่าจะได้รับประสบการณ์การใช้งานที่ดีในเว็บฟังใจนะครับ ทางฟังใจมีการพัฒนา Feature ใหม่อยู่เสมอนะครับ ขอให้อดทนรอกันหน่อย :) ถ้าหากผมเขียนผิดพลาดตรงไหนก็ขออภัยมายัง ณ ที่นี้ด้วยครับ สุดท้ายก็ขอขอบคุณพี่แชมป์ พี่บอล ที่เลือกผมเข้ามาฝึกงานนะครับ (ปล. ตอนสัมภาษณ์กับพี่ทั้งสองคนนึกว่าจะไม่รอดเสียแล้ว ฮ่าๆๆ) ขอบคุณพี่ๆ ทุกคนในทีม Product ที่ผมได้ใช้ชีวิตตลอด 2 เดือนที่ผ่านมา ถ้าเขียนขอบคุณจริงๆ ปีหน้าก็ยังเขียนไม่หมดครับ ฮ่าๆๆๆๆ เป็นการเปิดโลกอีกมุมของผมให้ชัดเจนยิ่งขึ้น แล้วที่ขาดไปไม่ได้เลย ขอบคุณฟังใจที่ให้โอกาสผมได้มาฝึกงานที่นี่ อ้อ ขอบคุณจอห์นด้วยสำหรับเพื่อนฝึกงานที่ดี(และกวนติง)คนนึงเลยและขอลาไปด้วยข้อความนี้

แล้วพบกันใหม่ สวัสดีครับ :)

--

--

Worapong Malaiwong
Fungjai
Writer for

ITKMITL#12 | Front-end guy and sometimes back-end. Now I’m a software developer at somewhere