Reduce Angular bundle size by remove unused locale in moment.js (without ng eject)

This is my lab test for remove a moment locale from angular app. This article will show you how to reduce Angular bundled size by remove unused locale in moment.js without ng eject

WARNING: This is my first english article. I’m not good english but i think this should be share to other people.

Prepare a lab data

Just install Angular 7 and moment by this command.

ng new ng7-moment
cd ng7-moment
npm install --save moment

And edit `app.component.ts` to something like this

import { Component, OnInit } from '@angular/core';
import * as moment from 'moment';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  time: string;

  ngOnInit() {
    this.time = moment().format('MMMM Do YYYY, h:mm:ss a');
  }
}

And build a production bundle with stats json. by

npm run build -- --prod --stats-json

Next i see how many size of moment.js that include to bundle by

webpack-bundle-analyzer dist/ng7-moment/stats.json

And this i a result

Angular bundle with a full locale of moment.js

As you can see total size is around 300KB (Gzipped around 70KB).

First try: Import min edition

After I google for solution i found someone suggest that I can import moment.min.js. That file not include any locale data. So i change code to

import { Component, OnInit } from '@angular/core';
import * as moment from 'moment/min/moment.min.js';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  time: string;

  ngOnInit() {
    this.time = moment().format('MMMM Do YYYY, h:mm:ss a');
  }
}

The bundle size after changed is

Bundle size after import min version of moment.js

Now size is reduce to around 51KB (Gzipped around 16KB). WOW! At first time I think it works. But when I import a locale data like this code.

import { Component, OnInit } from '@angular/core';
import * as moment from 'moment/min/moment.min.js';
import 'moment/locale/th';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  time: string;

  ngOnInit() {
    this.time = moment().format('MMMM Do YYYY, h:mm:ss a');
  }
}

And see a bundled size.

bundle size when import min version of moment.js and import localeAs you see we have 2 moment.js and full locale in bundled (one is full version and another one is min version). And if you import another library that use moment.js like chart.js the size will be like that too.

bundle size after import min version of moment.js and import chart.js

Second try: Use webpack plugins

I search in Google again. I see another solution to eject webpack config and add some plugin to remove locale. But for my personal reason i don’t want to eject angular config, So I will skip this solution for now.

Solution: Remove by Replace locale folders.

I found Angular has a feature that can replace environments file up to version that it build. I think I can use this folder to replace locale folder too. So let try

  1. Create a my locale folder and if you use any locale, copy it to this folder.
    mkdir src/locale
    
    # If you want to use any locale copy it to your locale folder
    cp node_modules/moment/locale/th.js src/locale/
  2. Edit angular.json to replace default locale. file fileReplacements section and add this code like this.
                  "fileReplacements": [
                    {
                      "replace": "src/environments/environment.ts",
                      "with": "src/environments/environment.prod.ts"
                    },
                    {
                      "replace": "node_modules/moment/locale/",
                      "with": "src/locale/"
                    }
                  ],
  3. Build and see a results. (You will see a warning message like “node_modules/moment/locale/af.js” does not exist. But it OK don’t worry it)

The result is

bundle size after remove unused locale.As you can see the size is around 55KB (Gzipped around 17KB) and no other locale except locale that in new locale folder. even if you import chart.js it still not include unused locale too. Like this

Bundle size after remove unused locale and import chart.js

I hope this will be useful. Thanks for reading.

เพิ่ม Index ให้ WordPress เพื่อลดโหลด

อันนี้เป็นบทความสั้นๆครับ เกิดจากการสังเกตว่าใน WordPress ของผมนั้นจะมี Query อันนึงที่ run เยอะมาก และบางทีก็นานมาก ตัวอย่างประมาณนี้ครับ

SELECT post_id FROM wp_postmeta WHERE meta_key = '_wp_attached_file' AND meta_value = '2015/11/top-5-antivirus.jpg';

ซึ่งจากที่เดาคือมันเช็คว่า Attachment ตัวนี้มี Post ไหนใช้บ้าง ผมไม่รู้ว่าตัวไหนเป็นคนเรียกใช้ แต่เนื่องจากมันเยอะมาก เลยทำการเพิ่ม index ให้มัน ทำให้มัน Query ได้เร็วขึ้น

ALTER TABLE wp_postmeta ADD INDEX first_50_key_10_value (meta_key(50),meta_value(10))

เพื่อความประหยัดผมเลย index meta_value แค่ 10 ตัวพอ (เพียงพอสำหรับ /ปี/เดือน/ ก็ลดไปได้เยอะและ)

แต่อันนี้ไม่ได้ช่วยกับทุกคนนะครับ บางทีมันอาจจะมาจาก Theme หรือ Plugin ก็ได้ ดังนั้นต่อให้ท่านใช้ไปก็ไม่อาจจะรับประกันได้ว่ามันจะช่วยท่านได้

แก้ปัญหา Laravel Error บน Appservhosting

พอดีวันนี้เจอปัญหาพิเศษ ที่เกิดขึ้นบน Share Host บางตัว (ในตัวอย่างนี้คือ Appservhosting แต่เชื่อว่าบาง Host ก็น่าจะเป็นเช่นกัน) จากโพสนี้  ซึ่งผมเห็นว่าเป็นเคสที่น่าสนใจมาก เลยเอามาแบ่งปันกันครับ

ปัญหาที่เกิดขึ้นคือ เมื่ออับโหลดขึ้นไปแล้ว Laravel ไม่ทำงาน โดยการตรวจสอบเบื้องต้นคือ

  • ผมได้ตรวจเวอร์ชัน PHP และ PHP Extension ที่ Laravel ต้องการแล้ว ซุึ่งปกติดีครับ
  • Permission ของ storage และ bootstrap/cache สามารถเขียนได้ปกติ

ต่อไปคือข้อบ่งชี้ว่าเป็นสาเหตุเดียวกัน

  • ผมได้ลองแก้ไขไฟล์ index.php และไฟล์อื่น เพื่อใส่ die(‘a’); เข้าไปเรื่อยๆ เพื่อหาว่ามันพังที่บรรทัดไหนกันแน่ แต่ปรากฏว่า เลื่อนบรรทัดไปมา เหมือนบรรทัดที่พังเปลี่ยนไปเรื่อยๆ (อันนี้เงิบมากๆ เพราะผมขยับไป 1 บรรทัดมันพัง เลยลงไปใส่ใน function ที่พัง แต่ผ่านตลอด แล้ววนกลับมา die ที่เดิมมันไม่พังเฉยเลย)
  • Error Logs ไม่มีเขียนอะไรเลย (อาจจะมีเขียน แต่ผมใช้ .htaccess เปลี่ยนที่อยู่ logs มัน เพราะที่เก่าไปอยู่ในที่ๆผมเข้าถึงไม่ได้ เพราะ share host ไม่เปิด)
  • ผมใช้  curl -v url > /dev/null เพื่อดูว่ามันมีอะไรที่ผมไม่เห็นไหม ประกฏว่ามันไม่ได้่ error 500 แต่มันตัด connection ไปดื้อๆ เลย ข้อนี้เลยค่อนข้างเดาได้ว่าน่าจะเป็นที่ระดับ php ไม่ได้เป็นที่ระดับ Code

สรุปผลการคาดเดาของผมคือ น่าจะเป็นปัญหาที่น่าจะเคยเจอกันบ่อยๆคือ OP Cache ของ PHP น่าจะเกิดปัญหา ซึ่งในที่นี้คือ Zend OPcache v7.0.6-dev ซึ่งวิธีแก้ปัญหาคือปิดมันครับ โดยการเปิด .htaccess ขึ้นมา แล้วใส่บรรทัดนี้ลงไปครับ

php_flag opcache.enable Off

โดยในสมัยก่อนนั้น ผมเคยใช้ XCache ก็มีปัญหาคล้ายๆกัน แต่คนละแบบ ของ XCache เมื่อก่อน มันไป Cache routes.php ของคนอื่นมา มันเลยพัง ซึ่งวิธีปิดคล้ายๆกันคือใส่บรรทัดนี้ลงไป .htaccess

php_flag xcache.cacher Off

WTF AR-BRO Support – บันทึกความกากของ AR-BRO Support

หมายเหตุ โปรดดูวันที่โพสก่อนตัดสินใจ ในวันที่ท่านได้อ่านบทความนี้ AR-BRO อาจจะปรับปรุงเรื่องต่างๆแล้วก็ได้ 

อันนี้จะเป็นบันทึกเตือนใจ สำหรับผู้ที่อาจจะเข้ามาใช้ AR-BRO นะครับ เป็นประสบการณ์ที่ผมได้จากการ Support ของ AR-BRO ซึ่งเป็น Cloud Provider เจ้าหนึ่งของไทย เขียนตอนเดือน 1 ปี 2017

จริงๆแล้วผมค่อนข้างอคติกับที่นี่พอสมควร ใช้วิจารณญาณในการอ่านด้วยนะครับ สาเหตุที่ผมอคติหลักๆคือมันโฆษณาว่า “ไม่ต้องจ่ายล่วงหน้าเป็นเดือน!” แต่ว่าถ้าจะสร้างเครื่องคุณต้องมีเครดิตในระบบเหลือพอจ่ายให้เครื่อง”ทั้งหมด” รวมกับเครื่องที่จะสร้างใหม่ ล่วงหน้า 21 วัน ซึ่งนั่นหมายความว่าถ้าผมต้องการขยายระบบด้วยการสร้างเครื่อง 599 บาทต่อเดือน (0.89 บาทต่อชั่วโมง) 4  เครื่อง ผมต้องเติมเงิน 1794.24 แม้ว่าจริงๆผมจะอย่างใช้แค่ 3 วัน ซึ่งคิดเป็นเงินแค่ 256.32 บาทเท่านั้น เหลือเครดิตที่ทำอะไรไม่ได้ 1537.92 บาท ยิ่งกว่านั้นถ้าผมใช้เสร็จ ลบเครื่องทิ้ง เดือนต่อไปผมมีเหตุุจำเป็นให้ต้องขยาย 4 เครื่องอีก เครดิตที่เหลือ 1537.92 ไม่สามารถใช้เครื่องขนาด 599 บาท 4 เครื่องได้อีกแล้ว เพราะเครดิตที่เหลือมีไม่พอจ่าย 21 วัน ต้องเติมเพิ่ม 256.32 ก่อนถึวจะใช้ได้  ดังนั้นถ้าใครคิดจะเอามา ขยายระบบเฉพาะหน้านี่ไม่เหมาะอย่างแรงเลยครับ เหมือนเอาเงินไปดองทำไรไม่ได้

เข้าเรื่องต่อไปจะรวมเรื่องที่ Support AR-BRO ตอบมาแบบแปลกๆกันดูครับ

[May 29, 2016 – June XX, 2016] AR-BRO MA ระบบบ่อยจนน่ากลัว

เป็นช่วงตกต่ำที่สุกของ AR-BRO เลยก็ว่าได้ ฃ่วงนั้นผมยังไม่มีเครื่องที่ใช้จริงจังเท่าไหร่ แต่เห็นหลายคนบ่นหนักว่าล่มบ่อยมาก ซึ่งในเหตุการณ์นั้นทาง AR-BRO รับมือด้วยการ ปิดระบบ Ticket, Call Center และการโพสหน้าเพจของ Facebook ไปเลย ซึ่งผมรู้สึกว่ามันดูไม่โปรอ่ะ แล้วมีครั้งนึงที่เค้าบอกว่า MA ตอน ตี 1 มั้ง แต่ผมได้ SMS แจ้งการ MA ครั้งนี้ตอนตี 4  หลัง MA เสร็จไปแล้ว โดยลูกค้าช่วงแรกอย่างพี่เนยจาก nuuneoi.com ยังย้ายกลับไปใช้ Digital Ocean เหมือนเดิมเลย (อ้างอิง)

ปัจจุบัน ปัญหาล่มทั้งระบบไม่เจอแล้วในช่วงหลัง พอไว้ใจได้ในระดับหนึ่ง ตามที่ผมเคยเจอ มีแค่ครั้งเดียวหลังจากช่วงนี้ที่ดับแล้วไม่แจ้ง (วันที่ 17 ธันวาคม 2016)

[September 9, 2016] UBUNTU 14.04 เลิกพัฒนาแล้ว ไม่ปลอดภัย

พอดีว่าผมชอบใช้ Ubuntu แต่ว่า Image ที่ AR-BRO มีให้นั้น Ubuntu 16.04 ซึ่ง ณ วันนั้น VestaCP ไม่รองรับ ผมเลยแจ้งไปทางเพจว่าขอ Image Ubuntu 14.04 ด้วยได้ไหม จริงๆแล้วเรื่องนี้มันจะไม่เป็นปัญหาเลย ถ้าเค้าไม่ดันตอบมาว่า “Ubuntu 14 เลิกพัฒนาแล้วครับมำให้มีรูรั่วจำนวนมาก” ผมนี่ถึงกับเปิดตาราง LTS เลยครับ

AR-BRO บอกว่า Ubuntu 14.04 ไม่ปลอดภัย และเลิกพัฒนาไปแล้ว WTF

สำหรับใครอยากดูว่า Ubuntu 14.04 LTS End of Life วันไหน สามารถดูได้ที่ https://wiki.ubuntu.com/LTS

ปัจจุบัน ตามที่เค้าบอก มันอาจจะจัดการระบต่างๆได้ยาก เค้าเลยไม่ใส่นะครับ และ VestaCP รองรับ Ubuntu 16.04 แล้ว ก็ใช้ Ubuntu 16.04 แทนนะครับ

[December 17, 2016] AR-BRO ปิดเครื่องโดยไม่แจ้งล่วงหน้า

ในวันที่ 17 ธันวาคน 2016 เกิดเหตุการณ์ เครื่องดับถ้วนหน้า โดยไม่มีการแจ้งล่วงหน้าว่าจะ MA หรือว่าเกิดอุบัติเหตุขึ้นอย่างไรก็มิทราบได้  (ผมจำไม่ได้ว่าดับไปช่วง 6.00 น. หรือว่าเริ่มดับช่วง 8.00 น.)  แต่ผลที่เกิดขึ้นคือเครื่องดับไป 2 ชม. ที่ผมรู้เพราะมีคนโทรมาบอกว่าเข้าเว็บไม่ได้ เห็นสถานะเครื่องดับอยู่ ต้องมาเปิดเอง เข้าใจว่าเหตุการณ์นี้น่าจะดับทุกเครื่องเลยครับ เพราะถามจากเพื่อนๆที่ใช้อยู่ก็ดับไปเหมือนกัน  (Ref) และหลังจากเหตุการณ์ AR-BRO ไม่ได้ชี้แจงใดๆทั้งสิ้น (และผมก็ไม่ได้ถามไป) แต่มีการชดเชยเครดิตให้ระดับนึง (Ref)

[January 5, 2017] Ping สูงแบบไม่ทราบสาเหตุ

เดี๋ยวจะหาว่า Support มีแต่เรื่องแย่ๆ อันนี้เรื่องดีๆบ้าง อันนี้เป็นของที่ทำงาน เค้าบอกเว็บช้ามาก ให้ลองดูหน่อย ก็เลยพบว่า PING สูงมาก (150 – 400 ms) ปกติจะประมาณ 3-5ms เท่านั้น เข้าใจว่าเฉพาะ IP 103.x.x.x เพราะเครื่องส่วนตัว IP: 150.107.29.x ปกติดี เลยเปิด Ticket แจ้งไป โดยเค้าแจ้งว่า “Network ภายในบางเส้นทางมีปัญหากำลังรีบดำเนินการแก้ไขครับ”  เค้าใช้เวลาประมาณ 10 นาทีเพื่อแก้ปัญหา แล้วทุกอย่างก็กลับมาเรียบร้อยเหมือนปกติดี

[December 16, 2016 – January 14, 2017] สั่ง npm install แล้วช้า 

อันนี้เป็นเรื่องแปลกๆคือผมไม่สามารถสั่ง npm install เพื่อลง package ต่างๆที่ใช้บน NodeJS ได้ แต่สามารถสั่งคำสั่งเดียวกันบนเครื่องที่บ้าน และที่ทำงานได้ปกติ ไฟล์ package.json ก็ตัวเดียวกัน ซึ่งยังไม่สามารถแก้ปัญหาได้ ที่สำคัญคือทาง AR-BRO ไม่ได้แจ้งอะไรกลับมาเลย ในช่วงแรกผมแจ้งไปทาง Facebook Page เค้าบอกให้ผมลองเปิด verbose mode ดู หลังจากส่งข้อมูลให้เค้าดูหลายๆอย่าง สุดท้ายก็เงียบไปและไม่ได้รับการตอบกลับอีก (เข้าใจว่าหาวิธีแก้อยู่แล้วก็ลืมไปล่ะมั้ง) หลังจากนั้นประมาณ 1 สัปดาห์ผมก็ไปเปิด ticket ในเว็บ AR-BRO อีกที ผลคือเหมือนเดิมครับ ไม่มีการตอบกลับใดๆทั้งสิ้น ถ้านับรวมเวลาตั้งแตตอนนั้นถึงตอนนี้ก็เกือบ 1 เดือนแล้วครับที่ยังไม่มีการตอบกลับใดๆทั้งสิ้น (ในระบบ Ticket) ไม่แม้แต่จะขอข้อมูลเพิ่ม

โดยข้อมูลที่ผมส่งให้มีดังนี้ (ถ้าใครพอเดาสาเหตุได้ก็ช่วยกันหน่อยนะครับ)

ตอนนี้ผมประสบปัญหาสั่ง npm install ช้ามากๆครับ

โดยจากการตรวจสอบอาการเบื้องต้น คาดว่าเป็นที่ตัวระบบ networks ครับ
อันนี้คือรูปตอนที่มันค้างไปเลยครับ http://upic.me/i/js/npm_verbose.png

โดยผมไม่คิดว่าเป็นที่ระบบของทางฝั่ง npm เนื่องจากว่าเครื่องที่ออฟฟิศสามารถใช้งานได้ปกติครับ
ดังรูป http://upic.me/i/5e/npm_compare.png
หน้าต่างซ้ายบนเป็นเครื่องของ AR-BRO ด้านขวาล่างเป็นของเครื่องออฟฟิศ เน็ต True และเน็ต 3BB ก็ปกติด้วยครับ

ในเบื้องต้นผมลอง debug ด้วยการสั่ง
time curl https://registry.npmjs.org/serve-static/-/serve-static-1.11.1.tgz > /dev/null
ผลที่ได้ดังรูปครับ http://upic.me/i/no/curl_v.png
และผ่านมา 2.30 นาทีแล้ว ไม่มีการขยับเพิ่มเติม

ตอนแรกผมคิดว่าเป็นที่ OS เลยเปลี่ยนจาก  https เป็น http
ผลคือค้างเหมือนกัน จึงคิดว่าไม่น่าใช่ครับ 
รูปประกอบ http://upic.me/i/bb/curl_v_http.png

ปัจจุบันผมจำเป็นต้องเพิ่มคำสั่งให้ใช้ http แทน และวิ่งผ่าน proxy จะสามารถทำงานได้ปกติ แต่ผมคิดว่ามันเป็นการแก้ที่ปลายเหตุ รบกวนตรวจสอบและแก้ให้ด้วยครับ

ปล ไฟล์ที่ช้าจะเปลี่ยนไปเรื่อยๆ บอกไม่ได้ว่าช้าที่ไหน และ url ที่เคยเร็วปกติ หากสั่งอีกครั้งอาจจะช้าได้เช่นกัน 

ลืมไป อันนี้ตัวอย่าง packae.json ครับ
http://pastebin.com/q0NgC9yq

จริงๆแล้ว case นี้ผมเดาว่าเค้าน่าจะ limit connection per second เพื่อป้องกันเราเอา host ไปยิงไรสักอย่างมั้งครับ (สังเกตุจากช่วงแรกๆมันจะวิ่งเร็วมาก แล้วก็จะนิ่งไปหลังอ่านไปสักพัก ถ้าลองสั่งหลายๆครั้งสักวันมันผ่านแน่นอน เพราะ npm cache ไว้ แต่บังเอิญผม build docker images ทำให้ในนั้นไม่มี cache และจะไม่ cache เด็ดขาด มันเลยไม่ผ่านสักที)

วันที่ปล่อยโพสนี้ (2017-01-04) ผมได้แจ้งข้อมูลเพิ่มไปใน ticket อีกรอบ ตามข้อสันนิษฐาน 1 ชั่วโมงหลังจากนั้นปิดเคสเลยครับ หายแล้ว รวมเวลากว่าจะตอบ เกือบเดือน ไม่แน่ใจว่าเพราะได้ Hint ไป หรือว่าเพราะระบบจัดการหลังบ้านไม่ดี เลยอาจจะข้ามปัญหานี้ไปต้องคอมเม้นตอบเพื่อดันกระทู้ให้เค้าเห็น

ในที่สุด AR-BRO ก็ตอบแล้ว

เทคนิคลดโฆษณาแบบวิดีโอที่แทรกใน Youtube

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

หลังจากผมพยายามเลี่ยงการใช้ Adblock กับหลายเว็บ เพื่อให้ผู้สร้างสรรค์เนื้อหาสามารถสร้างรายได้ได้ตามปกติ แต่ก็ยังไม่ชอบโฆษณาแบบวิดีโออยู่ดี ก็ได้ลองปรับไปเรื่อย ๆ จนพบวิธีที่ทำให้โฆษณาแบบวิดีโอน้อยลง เหลือแต่โฆษณาแบบแบนเนอร์เล็ก ๆ บนวิดีโอแทน โดยจะแสดงประมาณนี้แทน
ตัวอย่างโฆษณาแบบแบนเนอร์บน Youtube

ขั้นตอนการทำ

  1. เราต้องเข้าสู่ระบบใน Youtube ก่อน ถ้าไม่มีปัญชีก็สร้างซะ
  2. ให้เราเข้าไปที่นี่ https://www.google.com/settings/u/0/ads/authenticated
  3. เราจะเจอหน้าจอจัดการโฆษณาที่เราสนใจ ให้เรากด View 268 More Interests (ตัวเลขอาจจะเปลี่ยนไป ไม่เหมือนกันในแต่ละคน)
    หน้าจอจัดการความสนใจโฆษณา
  4. หลังจากเรากดแล้ว ให้เรากดทำเครื่องหมายถูกออก ให้เหลือเฉพาะอันที่เราสนใจจริง ๆ เท่านั้น เพื่อลดโฆษณา ก็อยากให้ทำแบบนั้น แต่ให้เราจำไว้ครับว่าโฆษณาหมวดไหนมีวิดีโอเยอะ ๆ ก็ให้เอาออกไปด้วย เช่น Snack Foods, Perfumes & Fragrances, Beauty & Fitness เป็นต้น ซึ่งเราจะเอาอันไหนออก ต้องพิจารณาเอง โดยเราควรจะเลือกเฉพะาหมวดที่มีโฆษณาแบบแบนเนอร์อย่างเดียว เช่นพวก Social Network เป็นต้น และเอาหมวดที่มีโฆษณาแบบวิดีโอออกให้เยอะที่สุด และห้ามเอาออกหมด หรือเหลือน้อย เพราะถ้าเอาออกหมด มันจะสุ่มจากสถานที่ปัจจุบันที่เราอยู่แทน ซึ่งโอกาศโดาโฆษณาแบบวิดีโอสูง อันนี้เป็นตัวอย่างที่ผมเลือก (ถ้าเลือกตามนี้ไม่ค่อยเจอแบบวิดีโอ นาน ๆ Udemy จะจัดโปรที)
    ตัวอย่างการหมวดเลือกโฆษณา
  5. หลังจากนั้นก็ไปลองเข้า Youtube แล้วดูว่ายังมีอยู่ไหม ลองปรับไปเรื่อย ๆ ครับ จะเลี่ยงได้เยอะพอสมควร และหมั่นเข้ามาเช็คบ่อย ๆ บางที Youtube ก็แอบเพิ่มให้เราเองครับ