ทำไมต้องลดจำนวน HTTP Request + วิธีใช้ Data URI

Suranart Niamcome
SiamHTML
Published in
2 min readJun 21, 2014

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

http requests

เราสามารถดู request ที่เกิดขึ้นได้จาก Developer Tools ของ Google Chrome

ทำไมมี HTTP Request เยอะๆ ถึงได้ช้า ?

  • มี Overhead เกิดขึ้นพร้อมกับ HTTP Requestในการเชื่อมต่อระหว่าง browser กับ server จะต้องใช้เวลาเสมอ (HTTP overhead) ถึงแม้ว่าไฟล์นั้นๆ จะติดแคชไปแล้ว แต่ web browser ก็ยังจะต้องส่ง HTTP request เพื่อไปเช็คกับ server ว่าไฟล์นั้นมีการอัพเดทหรือเปล่าอยู่ดี
  • เปลือง Persistent Connectionในแต่ละ web browser จะมีการจำกัดจำนวนของ persistent connection ซึ่งก็คือปริมาณของการเชื่อมต่อที่ web browser ทำพร้อมกันได้ใน hostname เดียวกันนั่นเอง โดย persistent connection นี้มักจะถูกจำกัดเอาไว้ที่ประมาณ 4–6 connection หากมี HTTP request เข้ามามากๆ จะทำให้ persistent connection ถูกใช้จนหมดและจะทำให้ request ที่เข้ามาทีหลังนั้นเข้าสู่สถานะ blocked
  • Cookies ถูกส่งไปพร้อมกับ HTTP Requestอย่าลืมว่า web browser จะต้องส่ง cookie ไปพร้อมกับ HTTP request ด้วยเสมอ ยิ่งถ้าข้อมูล cookie นั้นมีขนาดใหญ่ เวลาที่เราจะต้องใช้ในการอัพโหลดก็จะยิ่งมากขึ้น (ความเร็วในการอัพโหลดมักจะช้ากว่าการดาวน์โหลดอยู่แล้วด้วย)

แล้วเราจะลดจำนวน HTTP Request ได้อย่างไร ?

  • Combineวิธีนี้จะเป็นการรวมไฟล์พวก CSS หรือ JS เข้าด้วยกันให้เป็นไฟล์เดียว สมมติเดิมเรามีไฟล์ CSS อยู่ 10 ไฟล์ๆ ละ 10KB หากเรารวมไฟล์ให้เป็นไฟล์เดียว ถึงแม้ว่าขนาดรวมจะยังเป็น 100KB เท่าเดิมก็จริง แต่เวลาที่จะเสียไปกับ HTTP overhead นั้นจะเหลือเพียงแค่ครั้งเดียวเท่านั้น (แทนที่จะเป็น 10 ครั้ง) ในขั้นตอนนี้เราไม่จำเป็นต้องเขียนโค้ดลงไปในไฟล์เดียวกันทั้งหมดตั้งแต่แรก เพราะจะทำให้การกลับมาแก้ทีหลังนั้นทำได้ลำบาก การใช้ tool อย่าง Prepros เข้ามาช่วยดูจะสะดวกมากกว่า
  • CSS Spriteวิธีนี้จะเป็นการรวมรูปเล็กๆ หลายๆ รูป ให้อยู่ในไฟล์เดียวกัน สมมติเดิมเรามีรูปไอคอนขนาด 32x32 อยู่ 100 รูป ก็ให้เรานำทั้ง 100 รูป นั้นมาเรียงต่อๆ กันไป เราก็จะได้รูปขนาด 320x320 มาเพียงรูปเดียว ส่วนเวลาจะนำแต่ละรูปไปใช้ ก็ให้กำหนด css background-position เอา แต่ถ้ารู้สึกว่าขั้นตอนนี้ยุ่งยาก เราก็อาจใช้ tool อย่าง SpriteMe หรือ Sprite Cow เข้ามาช่วยก็ได้
  • Data URIหลังจากทำ 2 ขั้นตอนแรกเรียบร้อยแล้ว HTTP request ของหน้าเว็บจะลดลงอย่างมาก อย่างไรก็ตาม เรายังสามารถลด HTTP request ลงได้อีกด้วยการนำไฟล์ที่มีการเรียกใช้ในหน้าเว็บไปเข้ารหัสจนกลายเป็นเพียงโค้ดที่สามารถฝังลงในหน้าเว็บได้เลย (web browser จะทำหน้าที่ถอดรหัสเพื่อให้โค้ดที่แปลงมานั้น สามารถแสดงผลได้ตามรูปแบบที่เราระบุไว้)

ทำความรู้จักกับ Data URI

Data URI คือการ “ฝัง” ไฟล์ (พวก html, css และรูปต่างๆ) เอาไว้ในหน้าเว็บเลย โดยการนำไฟล์นั้นๆ ไปเข้ารหัสแบบ Base64 ซึ่ง web browser ที่รองรับการใช้ Data URI แล้ว จะสามารถถอดรหัสนี้ออกมาได้ พร้อมกับแสดงผลออกมาตามประเภทของไฟล์ที่เราได้ระบุไว้

Syntax

หลังจากที่เราได้นำไฟล์ไปเข้ารหัสแบบ Base64 แล้ว ให้เราแทนที่ url ของไฟล์เดิมด้วยโค้ดด้านล่างนี้

data:[ประเภทของไฟล์];base64,[โค้ดที่ได้จากการเข้ารหัส]

สมมติว่าเราจะใช้กับรูป ประเภทของไฟล์ที่ต้องระบุก็จะเป็นพวก image/png, image/jpg, image/gif เป็นต้น เราลองมาดูตัวอย่างการนำไปใช้จริงกันเลยดีกว่า

Img element

สำหรับ img element ให้เราใส่โค้ด Data URI ลงไปที่ src ได้เลย

<img width="5" height="5" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" />

CSS Background

ส่วนการนำไปใช้ใน css ก็ให้เราใส่โค้ด Data URI แทนที่ url ของรูปได้เลย

div { 
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==');
width: 5px;
height: 5px;
}

Tool

ในขั้นตอนของการเข้ารหัสแบบ Base64 และการกำหนดประเภทของไฟล์ ขอแนะนำให้ใช้ Data URI convertor เข้ามาช่วยเลยจะดีกว่า เพราะเพียงแค่เลือกไฟล์ที่ต้องการจะนำไปใช้ tool ก็จะจัดการให้เราทั้งหมด

เปรียบเทียบข้อดี-ข้อเสีย ของ Data URI

ข้อดี

  • เร็วเพราะไม่ทำให้เกิด HTTP request ขึ้นเลย และยังช่วยให้มี persistent connection เหลืออีกด้วย
  • ไม่ต้องไปเรียกไฟล์ภายนอกพูดง่ายๆ ก็คือ เราสามารถทำหน้าเว็บที่จบในตัวได้ เพราะทุกอย่างถูกฝังลงใน html หมดแล้ว (เหมาะกับการใส่รูปใน email เพราะโปรแกรมจะไม่มาถามว่าต้องการจะโหลดรูปมาหรือไม่ เพราะมันไม่ได้อ้างอิงถึงไฟล์ภายนอกเลย)

ข้อเสีย

  • ไม่ติดแคชweb browser ไม่สามารถแคชไฟล์ที่ใช้ Data URI ได้ เพราะมันจะเป็นเนื้อเดียวกับ html เลย
  • ขนาดไฟล์หลังเข้ารหัสใหญ่กว่าเดิมสมมติเดิมไฟล์มีขนาด 10KB หากเรานำไปเข้ารหัสแบบ Base64 แล้วนำรหัสที่ได้ไปเซฟลงในไฟล์เปล่าๆ ก็จะพบว่ามันมีขนาดเพิ่มขึ้นประมาณ 1 ใน 3 เลยทีเดียว (กลายเป็นประมาณ 13KB)
  • ติดตามผลไม่ได้เราไม่สามารถเก็บสถิติใดๆ จากการเข้าถึงไฟล์ที่ใช้ ​Data URI ได้เลย จึงไม่เหมาะในการใช้กับรูปที่เป็นตัวเนื้อหา เพราะ search engine ไม่สามารถ index ได้
  • ดูแลลำบากการใช้ Data URI ทำให้โค้ด html หรือ css ของเรายาวขึ้นมากๆ ซึ่งจะทำให้ไม่สะดวกในการไล่โค้ด นอกจากนั้น หากมีการแก้ไขรูปเพียงนิดเดียวก็ต้องมาเข้ารหัสกันใหม่
  • Browser Supportถึงแม้ว่า Data URI จะใช้ได้ตั้งแต่ Internet Explorer เวอร์ชัน 8 เป็นต้นมา แต่อาจติดปัญหาตรงที่ IE8 รองรับเฉพาะขนาดที่ไม่เกิน 32KB เท่านั้น

แบบนี้ยังควรใช้ Data URI อยู่มั้ย ?

หากดูจากข้อดีและข้อเสียแล้ว เราอาจจะลังเลอยู่บ้างในการใช้ Data URI เพราะถึงแม้ว่า HTTP request จะลดลงก็จริง แต่ก็แลกมาด้วยขนาดของไฟล์ html หรือ css ที่ใหญ่ขึ้นมากเช่นกัน

เราอาจเลือกใช้วิธีฝังเอาไว้ในไฟล์ css แทน html เพราะอย่างน้อยเราก็สามารถสั่งให้ web browser แคชไฟล์ css ทั้งไฟล์ได้ โดยรูปที่จะเอามาฝังไว้นั้น ก็ควรจะเป็นรูปที่จะนำไปใช้ในทุกๆ หน้าของเว็บ มิฉะนั้นจะไปทำให้ user ต้องมาโหลดไฟล์ css ขนาดใหญ่โดยใช่เหตุ อย่างไรก็ตาม เราไม่ควรปล่อยให้ขนาดของไฟล์ css นั้นใหญ่จนเกินไปนัก

บางทีเราอาจจะคิดว่า “ไม่เห็นเป็นไรเลย พอเข้าครั้งต่อไปมันก็ติดแคชแล้ว” นั่นแสดงว่าเราลืมนึกถึงความรู้สึกของผู้ที่เข้ามาใช้งานในครั้งแรก อย่าลืมว่า web browser จะต้องโหลดไฟล์ css มาจนหมดทั้งไฟล์ก่อน แล้วถึงจะเริ่มอ่าน css rule ต่างๆ หากไฟล์ css มีขนาดใหญ่มากๆ (เพราะเอารูปมาฝังไว้เต็มไปหมด) หน้าเว็บจะแสดงผลช้าลงกว่าปกติอย่างเห็นได้ชัดเลยทีเดียว

สรุปหลักในการใช้ Data URI

หลังจากที่วิเคราะห์ข้อดี-ข้อเสียของการใช้ Data URI แล้ว การตัดสินใจว่าจะเลือกใช้กับไฟล์ไหนนั้น จึงต้องมาวัดกันที่ขนาดของไฟล์ดั้งเดิม โดยปกติแล้ว HTTP overhead นั้นจะมีขนาดประมาณ 1KB หากขนาดของไฟล์ที่เพิ่มขึ้นมาหลังจากนำไปเข้ารหัสนั้น มากกว่าขนาดของ HTTP overhead การใช้ Data URI ก็ดูไม่น่าสนใจเท่าไรนัก

สมมติว่าเรามีไฟล์รูปขนาด 100KB พอนำไปเข้ารหัสแล้วขนาดจะอยู่ที่ประมาณ 133KB จะเห็นว่าส่วนต่างขนาด 33KB นั้น มีค่ามากกว่า HTTP overhead ที่หายไปเยอะเลยทีเดียว ในกรณีนี้ เราไม่ควรใช้วิธี Data URI ในทางกลับกัน หากรูปของเรามีขนาดเพียงแค่ 2KB ถึงแม้จะนำไปเข้ารหัสแล้วรูปก็ยังมีขนาดไม่ถึง 3KB อยู่ดี การเลือกใช้วิธี Data URI กับรูปนี้จึงมีความเหมาะสมกว่า

จากเหตุผลข้างต้น เราสามารถสรุปได้ว่า เราจะใช้วิธี Data URI ก็ต่อเมื่อไฟล์นั้นมีขนาดเล็กมากๆ เท่านั้น (ไม่เกิน 4KB) แต่ถ้าไฟล์นั้นเป็นรูปและยังมีไฟล์ในลักษณะแบบเดียวกันนี้มากๆ การใช้วิธี css sprite ดูจะเป็นวิธีที่ดีกว่า

--

--