แต่งโปรแกรม ASP ให้เร็วสุดๆ

อะไรคือความแตกต่างระหว่างโปรแกรม ASP ที่น่าใช้กับที่ไม่น่าใช้ คำตอบคือ "ความเร็ว" บทความนี้จะสอนเคล็ดลับการปรับแต่งโปรแกรม ASP ของคุณให้หลุดพ้นจากข้อจำกัดทางความเร็วทั้งปวง

พิมพ์ครั้งแรกในนิตยสาร QuickPC ฉบับที่ 114

 

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

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

ปัจจัยแห่งความเร็ว

ก่อนอื่นเราต้องมาพิจารนากันก่อนว่า มีปัจจัยอะไรบ้างที่จะมีผลกระทบต่อความเร็วของโปรแกรมในอินเทอร์เน็ต โชคร้ายหน่อยทีมีปัจจัยต่างๆ มาเกี่ยวข้องเพียบเลย อาทิ

  • แบนวิดธ์ของช่องการสื่อสาร (ใช้โมเด็มธรรมดา หรือดิจิตอลโมเด็ม)
  • ประสิทธิภาพของเครื่องเซิร์ฟเวอร์ (ความเร็วของซีพียู ปริมาณของแรม การเชื่อมต่อ)
  • มีงานอะไรบ้างที่กำลังวิ่งอยู่ในเซิร์ฟเวอร์ขณะนั้น (ถ้ากำลังวิ่งโปรแกรมกันจอไหม้รุ่นใหม่ที่ใช้ OpenGL และก็แย่หน่อย)
  • รูปแบบการเชื่อมต่อกับฐานข้อมูล ขนาดของฐานข้อมูล (เช่นใช้ออราเคิลหรือใช้เอ็กเซส)
  • ภาษาที่ใช้ (มีรายงานว่าในการทำงานบางอย่างภาษา Perlscript ทำงานได้เร็วกว่า VBScript)
  • รหัสของภาษา SQL เก็บแยกต่างหากหรือแทรกเข้าไปในบรรทัดของรหัสภาษาอื่นเลย
  • ใช้ ASP script หรือใช้ COM object

ที่ยกตัวอย่างมานี่เป็นแค่ปัจจัยบางประการ ที่มีผลกระทบต่อความเร็วเท่านั้น ถ้าคุณเป็นผู้ควบคุมเซิร์ฟเวอร์ด้วย คุณยังสามารถปรับแต่งประสิทธิภาพของเซิร์ฟเวอร์ได้อีกเยอะ ซึ่งการปรับแต่งเซิร์ฟเวอร์จะขึ้นอยู่กับปัจจัยปลีกย่อยอีกมากมาย ทำให้มันเป็นทั้งศาสตร์และศิลป์ที่ละเอียดอ่อนแขนงหนึ่ง

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

ระวังขนาดของ ASP script

เรื่องสำคัญอันดับแรงที่ควรหยิบยกขึ้นมาพิจารณาก่อนเลยคือ ขนาดของแฟ้ม ASP script ของคุณยาวมากหรือเปล่า เพราะปริมาณของจำนวนบรรทัดในแฟ้ม script มีผลโดยตรงต่อความเร็ว สาเหตุที่เป็นอย่างนั้นเนื่องจาก script จะถูกแปลทีละบรรทัด ยิ่งมีจำนวนบรรทัดมาก การทำงานก็ยิ่งใช้เวลานานมาก ถ้า script ของคุณยาวมากคุณควรจะปรับแก้ให้สั้นลง โดยใช้วิธีการดังต่อไปนี้

  • เปลี่ยน script ให้เป็น server-side component ซึ่งก็ไม่ใช่อะไรพิสดาร แค่เอามาทำเป็นแฟ้มแบบ DLL โดยใช้ Visual Basic หรือภาษาที่คุณถนัด คุณจะเรียกมันว่า ActiveX component ก็ได้ เสร็จแล้วก็จัดการลงทะเบียน (Register)เข้าไปในเซิร์ฟเวอร์ การใช้ ActiveX component นอกจากจะทำให้โปรแกรมเร็วขึ้นเยอะแล้ว ยังรักษาความลับของตัวโปรแกรมได้ด้วย โดยเฉพาะอย่างยิ่งถ้าคุณโฮสต์เว็บไซต์ของคุณไว้ในเซิร์ฟเวอร์ของคนอื่น ข้อจำกัดของวิธีนี้คือ ถ้าคุณไม่ได้เป็นผู้ดูแลระบบ หรือคุ้นเคยชอบพอกับผู้ดูแลระบบ โอกาสที่จะได้ลงทะเบียน ActiveX component มีน้อยมาก เพราะผู้ดูแลระบบมักไม่ค่อยจะยอมให้ใครมาลงติดตั้งโปรแกรมอะไรในเซิร์ฟเวอร์ของเขาได้ง่ายๆ ส่วนมากเป็นเพราะกลัวว่า component ของเราจะไปทำให้เครื่องของเขาทำงานช้าลง หรือที่แย่กว่านั้นคือไปทำลายระบบรักษาความปลอดภัยของเขา
  • แบ่ง script ออกเป็นส่วนๆ เช่นส่วนสำหรับผู้ใช้งาน ส่วนประมวลผลทางตรรก สวนจัดการฐานข้อมูล ตรวจดูว่าทำไม script ถึงได้ยาวมากนัก จำเป็นจะต้องมีโพรซีเชอร์ที่ยืดยาวมากขนาดนั้นจริงๆ หรือไม่ สามารถลดทอนหรือเขียนใหม่ให้กระชับกว่าเดิมได้หรือไม่ ปรกติแล้วใน script หนึ่งๆ จะมีส่วนที่ติดต่อกับฐานข้อมูล ส่วนรับและแสดงข้อมูลกับผู้ใช้ ส่วนการจัดหน้าจอแสดงผล แล้วก็มีส่วนประมวลผลจัดการด้านธุรกรรม ดังนั้นคุณจึงน่าจะสามารถแบ่งโปรแกรมแต่ละส่วนที่ว่ามานี้ออกเป็นโมดูลย่อยๆ ที่มีขนาดเล็กกว่าได้ เมื่อทำอย่างนี้แล้วคุณอาจพบว่ามีบางส่วนที่ใช้งานซ้ำได้ ซึ่งจะทำให้โปรแกรมสั้นลงไปอีก ยกตัวอย่างเช่น ถ้ามีหลายตอนในโปรแกรมที่ต้องแสดงผลข้อมูลออกมาในรูปตาราง แทนที่จะเขียนโปรแกรมสร้างภาพตารางทุกครั้ง คุณก็สามารถนำคำสั่งเฉพาะส่วนการแสดงภาพตารางแยกออกไปเป็นโมดูลย่อย เมื่อต้องการสร้างตารางก็เรียกใช้งานโมดูลนี้ได้หลายๆ ครั้ง การทำอย่างนี้นอกจากจะทำให้โปรแกรมสั้นลงแล้ว ยังเปลี่ยนแปลงแก้ไขได้ง่ายขึ้นด้วย
  • ควรระวังเมื่อใช้คำสั่ง #include เพราะคำสั่งนี้จะดึงโปรแกรมที่อ้างถึงเข้ามาต่อกับโปรแกรมที่กำลังวิ่งอยู่ ทำให้ความยาวของโปรแกรมกลายเป็นความยาวของโปรแกรมที่กำกลังวิ่งอยู่ บวกกับขนาดของโปรแกรมที่ #include เข้ามา ดังนั้นถ้าคุณ #include แฟ้มโปรแกรมขนาดใหญ่ ที่ประกอบไปด้วยการนิยามตัวแปร method และ definition ต่างๆ มากมาย ASP จะทำการดึง #include ไฟล์มาพักไว้ในแคชทั้งหมด แม้คุณจะเรียกใช้แค่บางอันเท่านั้น การดึงเข้าทั้งหมดจะทำให้การค้นหาตัวแปร method หรือ definition เป็นไปได้ช้า เพราะต้องไล่หาในรายการที่ยืดยาว ดังนั้นคุณจึงควรหาทางแบ่ง #include ไฟล์ ออกเป็นแฟ้มย่อยๆ ที่มีขนาดเล็กกว่าหลายๆ แฟ้ม
  • ถ้า script ของคุณยาวมากให้ใส่คำสั่ง Response.IsClientConnected ไว้ในโปรแกรมด้วย คำสั่งนี้จะทำให้ซีพียูไม่เสียเวลาติดต่อกับ client ที่หลุดไปแล้วโดยเปล่าประโยชน์

อย่าผสม ASP กับ HTML

โปรแกรมเมอร์ ASP ชอบเขียน script ASP ผสมกันกับ HTML เป็นเรื่องปรกติ ยกตัวอย่างเช่นเมื่อต้องการสร้างตาราง ก็อาจเขียนโปรแกรมดังนี้

<table>
<tr><td>Name</td><td>Number</td><td>Department</td></tr>
<tr><td>
<%=RS("Name")%>
</td><td>
<%=RS("Number")%>
</td><td>
<%=RS("Department")%>
</td><tr></table>

ตัวอย่างการผสม ASP กับ HTML อีกอันหนึ่งที่เราทำกันบ่อยๆ คือการใช้คำสั่ง if แบบนี้

<%
If not Session("DBOpen") then
%>
<h1>Database not connected</h1>
<%
Else
%>
<h1>Database open</h1>
<%
End If
%>

การเขียนแบบนี้ไม่ใช่วิธีเขียน ASP ที่มีประสิทธิภาพสูงสุด คุณสามารถปรับปรุงความเร็วการทำงานได้โดยแปลงคำสั่งทั้งหมดให้กลายเป็น script ฝั่งเซิร์ฟเวอร์ แล้วใช้คำสั่ง Response.Write เพื่อสร้างโค้ดภาษา HTML ขึ้นมาแทน ดังตัวอย่างนี้

<%
If not Session ("DBOpen") then
Response.Write "<h1>Database not connected</h1>"
Else
Response.Write "<h1>Database open</h1>"
End If
%>

เมื่อแปลงเแล้ว คุณจะพบว่าโปรแกรมทำงานได้รวดเร็วขึ้นอย่างเห็นได้ชัด

งดใช้ Session object

ในโลกของเว็บโปรแกรมมิ่ง การเขียนโปรแกรมให้รักษาสถานะภาพระหว่าง Session เอาไว้ได้เป็นสิ่งที่โปรแกรมเมอร์ต้องการ แต่การทำแบบนี้มีผลกระทบต่อประสิทธิภาพครับ เพราะเมื่อมีผู้ใช้เข้ามาเรียกใช้โปรแกรมพร้อมกันหลายๆ คน การเก็บสถานะภาพของ session ก็จะต้องแยกกันไปสำหรับผู้ใช้แต่ละคน ซึ่งกินทรัพยากรของเซิร์ฟเวอร์มาก

การรักษาสถานะภาพระหว่าง Session ปรกติแล้วเราจะใช้ตัวแปร session ซึ่งจะรักษาค่าไว้ได้แม้โปรแกรมจะย้ายการทำงานจาก session หนึ่งไปยังอีก session หนึ่ง การใช้ตัวแปร session นี้แหละครับเป็นตัวกินทรัพยากรของเซิร์ฟเวอร์ แต่คุณสามารถหลีกเลี่ยงไม่ใช้ตัวแปร session ได้ ในขณะที่ยังสามารถรักษาสถานะภาพระหว่าง session ไว้ได้โดยใช้กลเม็ดเล็กน้อย นั่นคือการเปลี่ยนมาใช้ประโยชน์จาก hidden form field และ query sting ไงครับ จากนั้นก็ยกเลิกการติดตามสถานะของ session โดยใช้คำสั่ง

@EnableSessionState = False

แค่นี้ ASP ก็จะไม่ติดตามสถานะของแต่ละ session อีกแล้ว ความเร็วของการประมวลผลจะสูงขึ้นอีกเยอะ แต่ถ้าคุณจำเป็นต้องใช้ session object จริงๆ ก็ให้หลีกเลี่ยงการใส่ข้อมูลจำนวนมากเข้าไปใน session object เพราะการรักษาสถานะของ session ใน IIS เป็นแบบอยู่นานครับ คือจะยอมปล่อยทรัพยากรกลับคืนไปก็ต่อเมื่อได้รับสัญญาณ session time out หรือ session terminated ซึ่งกว่าจะถึงตอนนั้นโปรแกรมอาจจะทำงานอืดเป็นเรือเกลือไปแล้ว

ฐานข้อมูลคือตัวช้าใหญ่

ถ้าไม่ติดต่อกับฐานข้อมูล โปรแกรม ASP ก็คงจะมีประโยชน์น้อย แต่การติดต่อกับฐานข้อมูลนี่แหละครับ ที่เป็นตัวการใหญ่ที่ทำให้โปรแกรมของคุณทำงานช้าเป็นเต่าคลาน ต่อไปนี้เป็นข้อแนะนำที่จะช่วยปรับปรุงความเร็วในการติดต่อกับฐานข้อมูลครับ

  • ควรใช้ฐานข้อมูลที่เรียงข้อมูลแบบ index การทำแบบนี้จะทำให้ความเร็วเพิ่มขึ้นทันทีอย่างเห็นได้ชัด
  • ตรงไหนในโปรแกรมที่สามารถเก็บข้อมูลโดยไม่จำเป็นต้องใช้ SQL ได้ก็ควรหลีกเลี่ยงไปใช้วิธีอื่นเช่นใช้ stored procedures แทน
  • ตรวจดูโค้ด SQL ให้แน่ใจว่า การเรียกข้อมูลเป็นการเรียกมาเฉพาะข้อมูลที่ต้องการจริงๆ ไม่ได้เรียกทุกอย่างมาหมด ซึ่งทำได้โดยใส่ filter เพื่อกรองข้อมูลที่ไม่ต้องการออกไป filter ที่โปรแกรมเมอร์ส่วนใหญ่นิยมใช้คือ where แต่ไม่ค่อยมีใครใช้ having ซึ่งในหลายๆ กรณีจะมีประโยชน์มากเช่นกัน
  • ควรใช้ SQL Server ไม่ใช่ Access เพราะ SQL Server ทำงานได้รวดเร็วกว่าเมื่อต้องรองรับผู้ใช้หลายคนพร้อมๆ กัน
  • ควรใช้ OLEDB และการเชื่อมต่อฐานข้อมูลแบบ DSN-less เพราะได้รับการทดสอบแล้วว่าให้การตอบสนองได้รวดเร็วกว่า เมื่อมีผู้ใช้งานหลายคนพร้อมๆ กัน อย่าใช้ DAO หรือ RDO เพราะมันถูกออกแบบมาสำหรับผู้ใช้เดี่ยว ส่วน ADO ยิ่งไม่น่าใช้ใหญ่ เพราะมันถูกออกแบบมาเพื่อทดสอบการใช้งานในเว็บเท่านั้น
  • เมื่อคุณสร้าง recordset ให้กำหนดหน้าที่ของ cursor และ locktype ให้ชัดเจน cursor ทำหน้าที่กำหนดวิธีอัพเดตข้อมูล recordset ใน dataset ส่วน locktype ทำหน้าที่กำหนดวิธีที่ recordset จะทำการอัพเดตข้อมูล ลองทดสอบการตั้งค่า cursor และ locktype ดูหลายๆ แบบว่าอย่างไหนจะให้ผลดีสุด ยกตัวอย่างเช่นถ้าเปิดฐานข้อมูลเพื่ออ่านอย่างเดียว ไล่ตั้งแต่รายการแรกจนถึงรายการสุดท้ายแล้วปิด อย่างนี้กำหนดให้ cursor เป็น forward only และกำหนดให้ locktype เป็น read only จะให้ผลการทำงานดีที่สุด
  • อย่าใช้ตัวแปร ADO ถ้าจำเป็นจะต้องใช้ข้อมูลจาก recordset หลายครั้งในหน้านั้นให้ใช้ตัวแปรแบบท้องถิ่นแทน โดยก็อปปี้ข้อมูลจาก recordset เข้าไปเก็บไว้ใน local variable จะแล้วเรียกใช้จากที่นั่นจะเร็วกว่ามาก และประหยัดทรัพยากรของระบบด้วย

เขียนคำสั่ง ASP ต้องระวัง

  • ถ้าคุณไม่ต้องการเขียนคำสั่งอะไรใน method Session_OnStart หรือ Session_OnEnd ก็อย่าปล่อยว่างเอาไว้ เพราะแม้จะไม่มีคำสั่งอะไรอยู่ข้างในเลย IIS ก็ยังต้องเสียเวลาเรียกมันขึ้นมาอยู่ดี ถ้าไม่ต้องการใช้ ทางที่ดีควรลบ method สองอันนี้ออกไปจะดีกว่า
  • การตรวจสอบความถูกต้องของข้อมูลที่ผู้ใช้ป้อนเข้ามา ควรทำด้วยคำสั่งทางฝั่ง client เพื่อลดความล่าช้าที่เกิดจากการเปลี่ยนการทำงานกลับไปกลับมาระว่าง client กับเซิร์ฟเวอร์
  • ควรใช้ตัวแปรท้องถิ่น ไม่ควรใช้ตัวแปรสาธารณะ เพราะตัวแปลภาษาจะค้นข้อมูลจากตัวแปรท้องถิ่นได้เร็วกว่า
  • หลีกเลี่ยงการทำ redimension กับตัวแปรแบบ array ให้ใช้ขนาดเต็มไปตั้งแต่แรกเลย อาจเปลืองหน่วยความจำหน่อยแต่ทำงานได้รวดเร็วกว่าการมาทำ redimension ภายหลัง
  • ถ้าต้องการสร้าง object ที่อาจจะไม่ต้องการใช้จริง ควรสร้างโดยใช้คำสั่ง <OBJECT> อย่าสร้างด้วยคำสั่ง Server.CreateObject เพราะคำสั่ง <OBJECT> จะสร้าง object เมื่อต้องเรียกใช้ขึ้นมาจริงๆ เท่านั้น ขณะที่คำสั่ง Server.CreateObject จะสร้าง object ทันทีโดยไม่สนใจว่าจะใช้จริงหรือไม่
  • อย่าใช้ Server.MapPath โดยไม่จำเป็น ควรอ้างถึงตำแหน่งโดยตรงแบบ full qualified path ไปเลย โปรแกรมอาจจะยืดหยุ่นน้อยกว่านิดหน่อย แต่รับรองว่าเร็วกว่ากันเยอะ

จับเวลาการทำงาน

ผมได้แนะนำวิธีปรับปรุงความเร็วของ ASP มาพอสังเขปแล้ว เมื่อคุณได้ลองปรับปรุงตามคำแนะนำแล้วก็ต้อง ลองตรวจสอบดูว่าเร็วขึ้นจริงหรือไม่ ถ้าเร็วขึ้นจริงเร็วขึ้นเท่าใด วิธีจับเวลาการทำงานของโปรแกรมทำได้โดยใส่คำสั่งข้างล่างนี้เข้าไป (โปรแกรมจับเวลา ASP เขียนโดย Richard A. Lowe)

โปรแกรมสำหรับจับเวลาการทำงานของ ASP

ตัวอย่างการปรับปรุง

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

สารบัญ