Thursday, 30 August 2007

5 วิธีที่ทำให้ Javascript เร็วขึ้น

ไม่พูดพร่ำทำเพลงไปดู 5 วิธีนี้เลยครับ

1. ใช้วิธีบีบอัด file ด้วย compressor

การใช้ composser ในที่นี้คือการนำ file javascript ที่มีอยู่ ไปให้ "JS Compressor" กรองคำต่าง ๆ เหล่านี้ออกไปเช่น white space, comment หรืออื่น ๆ การบีบอัดนี้จะทำให้ขนาด file ของ javascript ลดลงได้มากถึง 50% ผลที่ตามมาคือช่วยให้การโหลด javascipt เร็วขึ้น "ตัว JS Compresor" ที่แนะนำคือ JSMin จะให้ดูการทำงานของ compressor คร่าว ๆ ดังนี้

source code ที่ยังไม่บีบอัด


// is.js

// (c) 2001 Douglas Crockford
// 2001 June 3


// is

// The -is- object is used to identify the browser. Every browser edition
// identifies itself, but there is no standard way of doing it, and some of
// the identification is deceptive. This is because the authors of web
// browsers are liars. For example, Microsoft's IE browsers claim to be
// Mozilla 4. Netscape 6 claims to be version 5.

var is = {
ie: navigator.appName == 'Microsoft Internet Explorer',
java: navigator.javaEnabled(),
ns: navigator.appName == 'Netscape',
ua: navigator.userAgent.toLowerCase(),
version: parseFloat(navigator.appVersion.substr(21)) ||
parseFloat(navigator.appVersion),
win: navigator.platform == 'Win32'
}
is.mac = is.ua.indexOf('mac') >= 0;
if (is.ua.indexOf('opera') >= 0) {
is.ie = is.ns = false;
is.opera = true;
}
if (is.ua.indexOf('gecko') >= 0) {
is.ie = is.ns = false;
is.gecko = true;
}

source code ที่ผ่านการบีบอัดแล้ว


var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'}
is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;}
if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}

2. พยายามที่จะลด file .js ลง อันไหนรวมกันได้ก็รวมกันไป

การเรียก file .js หนึ่ง file เข้ามาในหน้า web page จะเกิด http request ขึ้นหนึ่งครั้งต่อหนึ่ง file ลองคิดดูว่าถ้าในหน้า web page นั้นมีการอ้างถึง file .js หลายๆ file แสดงว่าต้องเกิด http request ขึ้นอีกหลายอัน ดังนั้น file .js ตัวไหนนั้น สามารถรวมกันเป็น file เดียวได้ก็ให้รวมกัน แต่ไม่ใช่ว่าจะเอาทุก .js ไปรวมกันเป็น file เดียวเพราะว่าอาจจะทำให้ file ตัวนั้นใหญ่เกินไปทำให้การเรียกนั้นก็ช้าลง

3. ลองใช้ tool พวก profiler และ tool ที่ใช้วัดเวลาการทำงานของ java script เรา

tool พวกนี้ที่จะแนะนำคือ Firebug ซึ่งเป็น plugin เสริมของ filefox นั้นเองผมว่า web developer ทุกคนคงมีกันอยู่แล้ว เจ้าตัวนี้สามารถ debug javascript ได้ด้วย ให้ลองตรวจดูว่า script ที่เราเขียนบางที่อาจจะรันได้จริง แต่ว่าทำงานช้าไปหรือเปล่า ลองให้ Firebug ตรวจดูว่ามันเป็นที่ตรงไหน แล้วเราจึงไปปรับปรุงแก้ไข code ตรงนั้น

4. การทำ asynchronize ให้กับ code javascript

ปกติแล้ว browser นั้น run javascript เป็นแบบ synchronously ในที่นี้คือหมายถึงว่า เมื่อ browser เจอ tag <script> การทำงานทุกๆสิ่งใน web page นั้นจะถูกหยุดไป จนกระทั่ง browser นั้นทำงาน tag <script> เสร็จ
แต่ถ้าหากว่าใน tag <script> เกิดมี code javascript ที่มีการทำงานที่นานขึ้นมา แสดงว่าส่วนอื่นนั้นจะไม่มีทางโหลดขึ้นมาได้เลย ดังนั้นเราควรที่จะเขียนให้ javascript เราเป็นแบบ asynchronize เพื่อที่จะไม่จำเป็นต้องรอให้ code javascript นั้นทำงานเสร็จก่อน ก็ให้ไปทำงานส่วนอื่น ๆ พร้อมกันเลย
การเขียนอย่างนี้เราจะใช้ function setTimeout() เข้ามาช่วย คือ setTimeout จะเรียก function ของ javascript ขึ้นมาทำงานในตามเวลาที่กำหนด และถ้ามีส่วนอื่นที่ทำงานอยู่ เมื่อถึงเวลามันก็จะทำงานไปพร้อมกับส่วนนั้นไป ซึ่งจะเห็นได้ว่าถ้าเราเอา setTimeout() เข้ามาช่วย browser ก็จะได้ไม่ต้องรอให้ function ที่ถูกเรียกธรรมดาทำเสร็จ ก็สามารถทำงานในส่วนต่อได้

ตัวอย่างการเรียก function แบบ asynchronize


function testfunc()
{
var x1="test1";
var x2="test2";

alert(x1+x2);
}
testfunc(); //normal way to execute the function
window.setTimeout(testfunc,0); //asynchronous execution of testfunc()

5. ควรระวังในการอ้างถึง DOM variable

เป็นที่รู้กันอยู่แล้วว่าการ binding ใน javascript มันช้า ดังนั้นการเขียน code ที่จะเข้าไป access ถึง IE DOM เมื่อเราเรียกในแต่ละครั้ง มันจะไป search เข้าไปในแต่ละ element ว่าเจอ DOM ที่เราต้องการเรียกหรือเปล่า ซึ่งถ้าใน element นั้นมี sub element ก็จะเข้าไปเรื่อย ๆ จนครบทุกส่วนใน element จึงไปยัง element ต่อไป ถ้า element เยอะก็จะช้าด้วย ดังนั้นการอ้างถึง DOM variable แต่ละครั้งนั้น ควรที่จะเรียกใช้อยากระมัดระวัง จะยกตัวอย่างที่เรียกใช้ DOM variable ที่ไม่ดีและที่ดีให้ดู

การเรียกใช้ DOM variable ที่ไม่ดี


function buildString()
{
var newElement = document.getElementById("myitem");
newElement.innerHTML = ""; // Clear out the previous
newElement.innerHTML += addHeader();
newElement.innerHTML += addBody();
}

การเรียกใช้ DOM variable ที่่ดี


function buildString()
{
var newText = addHeader() + addBody();
document.getElementById(”myitem”).innerHTML = newText;
}
ที่มา : http://www.whenpenguinsattack.com/2007/08/20/5-ways-to-speedup-javascript/

11 comments:

Anonymous said...

พอดีตอนนี้ต้องมาเขียน Web Applciation อยากให้ช่วย Post บทความที่เกี่ยวกับการเพิ่ม Performance ให้ Web Application ที่เขียนด้วย JSP หน่อยได้ไหมค่ะ

ขอบคุณมากค่ะ

erawat said...

ใช้ Connection Pool สิครับ :)

ใช้ logging แทน System.out.println();

Anonymous said...

จะจัดให้ครับอีกไม่นานเกินรอครับ

ขอบคุณครับที่ช่วยแสดงความคิดเห็น

ปล. ถ้ามีเรื่องไหนที่ต้องการให้ทางเราเขียนบทความก็แนะนำได้มาทาง comment ครับ

Rice Cooker said...

logging แทน System.out.println(); ในที่นี้หมายถึงว่าเวลา trace error แทนที่จะให้แสดงออกทาง System.out.println(); ให้แสดงออกมาทาง logging แทนใช่ไหมครับ ไม่ทราบว่าผมเข้าใจถูกหรือเปล่าถ้ายังไงแนะนำด้วยครับ

ปล. 1 logging นี้ไม่ทราบว่าคุณ idome ใช้ตัวไหนอยู่ครับผมใช้ logging log4j ของ Apache อยู่ครับ

ปล. 2 ขอบคุณครับที่ช่วยตอบคำถาม

ปล. 3 ด้านบนนี้ผมลืม loggin

NUL said...

แจ่มๆ อีกแล้ว บล็อกนี้มีอะไรดีดีเยอะแฮะ

ว่าแล้วก็เอาไป optimize เจ้า Prototype JS กับ Script.aculo.us โอย ขนาดไฟล์ลดลงเยอะเลย

ขอบคุณมากๆ สำหรับ JSMin

Rice Cooker said...

ขอบคุณ คุณ iake ครับสำหรับคำชมทางเราจะพยายามรักษาคุณภาพไว้ครับ

Anonymous said...

เยี่ยมครับบทความนี้ 8/10 กันไปเลย !

Anonymous said...

บทความนี้มีประโยชน์อย่างสูงสำหครับคนเขียนสคริปต์ แต่ปัญหาใหญ่อย่างหนึ่งคือ พวกที่อยู่บน host อื่น อย่าง script ของโฆษณาอย่าง adsense เราพอจะมีวิธีแก้ไขไหมครับ นอกจากย้ายไปไว้ footer

Rice Cooker said...

ขอบคุณครับสำหรับความเห็นเดี๋ยวผมลองไปหามาดูก่อนถ้าได้ยังไงจะเอามาแปะไว้ที่บทความครับ

Anonymous said...

หาที่ดาวน์โหลด Jmeter ไม่เจออ่ะ

Anonymous said...

http://mirrors.issp.co.th/apache/jakarta/jmeter/binaries/jakarta-jmeter-2.3.2.zip