Skia เป็นไลบรารีกราฟิก 2D ประสิทธิภาพสูงแบบโอเพนซอร์สที่เขียนด้วยภาษา C++ ซึ่งทำหน้าที่เป็นเอนจินการเรนเดอร์หลักของ Flutter โดยรับผิดชอบการแปลงวิดเจ็ตระดับสูงและองค์ประกอบอินเทอร์เฟซเป็นพิกเซลบนหน้าจอ รองรับการเรนเดอร์ซอฟต์แวร์ผ่าน CPU และการเร่งด้วยฮาร์ดแวร์ผ่าน OpenGL, Vulkan และ Metal ตามข้อมูลจาก Skia Documentation (2025) Skia ประมวลผลเฟรมที่เรนเดอร์มากกว่า 2 พันล้านเฟรมทุกวันบนอุปกรณ์ Android, Chrome และ Flutter
ประเด็นสำคัญ
Skia เป็นไลบรารีกราฟิก 2D ข้ามแพลตฟอร์มที่พัฒนาโดย Google และให้ใช้ภายใต้ใบอนุญาต BSD โดยมี API แบบรวมสำหรับการวาดรูปทรงเรขาคณิต ข้อความ รูปภาพ และเงา โดยไม่ขึ้นกับแบ็กเอนด์กราฟิกพื้นฐาน Skia เขียนด้วยภาษา C++ และปรับให้เหมาะสมสำหรับการทำงานบนอุปกรณ์ที่หลากหลาย ตั้งแต่โทรศัพท์มือถือไปจนถึงเซิร์ฟเวอร์
ประวัติของ Skia เริ่มต้นในปี 2005 ในฐานะไลบรารีกรรมสิทธิ์ของบริษัท Skia Inc. ในปี 2007 Google ซื้อกิจการ เปิดซอร์สโค้ด และเริ่มใช้ในผลิตภัณฑ์ของตน ปัจจุบัน Skia เป็นเอนจินกราฟิกหลักของ Google Chrome (รวมถึง Chrome OS), Android (ตั้งแต่เวอร์ชัน 4.0) และแน่นอน Flutter ไลบรารี ได้รับการดูแลโดยทีม Google และได้รับการปรับปรุงอย่างต่อเนื่อง มีการเพิ่มแบ็กเอนด์ใหม่ การปรับปรุงประสิทธิภาพ และการรองรับ API กราฟิกสมัยใหม่
คุณสมบัติหลักของ Skia คือไม่ใช่แค่ชุดฟังก์ชันสำหรับวาดไพรミทีฟเท่านั้น แต่เป็นไปป์ไลน์กราฟิกที่สมบูรณ์ซึ่งรวมถึงการแรสเตอร์เส้นโค้ง (พาธ), การลดรอยหยัก (anti-aliasing), การซ้อนทับมาสก์, การจัดการความโปร่งใส และการแก้ไขสี Skia รองรับรูปแบบภาพ PNG, JPEG, WebP และ GIF และสามารถเรนเดอร์ข้อความผ่านเอนจิน HarfBuzz สำหรับการจัดรูปทรงกลิฟ
แตกต่างจาก Cairo (ใช้ใน GTK) หรือ Quartz 2D (ใช้ใน macOS) Skia ถูกออกแบบตั้งแต่แรกให้ทำงานบนหลายแพลตฟอร์มที่มี API กราฟิกต่างกัน ซึ่งทำให้ได้เปรียบในเฟรมเวิร์กข้ามแพลตฟอร์มอย่าง Flutter Cairo มุ่งเน้นการเรนเดอร์ซอฟต์แวร์ ในขณะที่ Skia รองรับการเร่ง GPU ตั้งแต่เริ่มต้น ซึ่งสำคัญอย่างยิ่งสำหรับแอนิเมชันอินเทอร์เฟซ
สถาปัตยกรรมของ Skia ถูกสร้างเป็นไปป์ไลน์หลายชั้น โดยแต่ละชั้นรับผิดชอบขั้นตอนเฉพาะของการแปลงคำสั่งกราฟิกเป็นพิกเซล โครงสร้างนี้ช่วยให้สามารถใช้ชั้นบนซ้ำได้โดยไม่ขึ้นกับ API กราฟิกพื้นฐาน
ชั้นบนสุด — Canvas API — มอบนามธรรมสำหรับการวาดให้กับนักพัฒนา เมธอด drawRect, drawCircle, drawPath, drawText รับพารามิเตอร์เรขาคณิตและสไตล์ (สี, ความโปร่งใส, การแปลง) Canvas แปลงคำสั่งเหล่านี้เป็นลำดับของการดำเนินการที่ส่งต่อไปยัง Skia Pipeline — กราฟคำสั่งภายในที่ถูกปรับให้เหมาะสมก่อนการดำเนินการ
ชั้นกลาง — Surface และ Device — จัดการบัฟเฟอร์เป้าหมายที่ใช้ในการเรนเดอร์ Surface ถูกสร้างขึ้นด้วยขนาด พื้นที่สี และประเภทแบ็กเอนด์ที่ระบุ Device ดำเนินการแบ็กเอนด์การเรนเดอร์เฉพาะ: ตัวแรสเตอร์ CPU (Raster), OpenGL (GL), Vulkan (Vk) หรือ Metal (Mt) Device มีการดำเนินการที่ปรับให้เหมาะสมของการวาดแต่ละครั้งสำหรับแบ็กเอนด์เฉพาะ
ชั้นล่างสุด — Ganesha (แบ็กเอนด์ GPU) — ดำเนินการเรนเดอร์แบบเร่งด้วยฮาร์ดแวร์ Ganesha ใช้ GPU สำหรับการแรสเตอร์พาธ การเติมเกรเดียนต์ และการซ้อนทับเอฟเฟกต์ โดยรวบรวมคำสั่งเป็นแบตช์และลดการสลับสถานะ GPU แต่ละ API กราฟิกมีการดำเนินการ Ganesha ของตนเอง: Skia GL สำหรับ OpenGL, Skia Vulkan สำหรับ Vulkan, Skia Metal สำหรับ Metal
Skia ใช้ภาษาเชเดอร์ของตนเอง SkSL (Skia Shading Language) เพื่ออธิบายเอฟเฟกต์ โค้ด SkSL ถูกคอมไพล์เป็น SPIR-V (การแสดงผลตัวกลาง) ซึ่งจากนั้นจะถูกแปลเป็นรูปแบบเชเดอร์เฉพาะแบ็กเอนด์ (GLSL, HLSL, MSL) ซึ่งเป็นวิธีแบบรวมสำหรับอธิบาย เอฟเฟกต์กราฟิก โดยไม่ขึ้นกับแพลตฟอร์ม
Flutter ใช้ Skia เป็นเอนจินการเรนเดอร์หลักบนทุกแพลตฟอร์ม: Android, iOS, Web, Windows, macOS และ Linux เมื่อแอปพลิเคชัน Flutter เรนเดอร์เฟรม วิดเจ็ตจะถูกแปลงเป็นต้นไม้ RenderObject ซึ่งจากนั้นจะถูกส่งไปยังชั้น Engine (ในภาษา C++) และ Engine ใช้ Skia สำหรับการเรนเดอร์ขั้นสุดท้าย
กระบวนการเรนเดอร์เฟรมประกอบด้วยหลายขั้นตอน ขั้นแรก Flutter Engine สร้าง Display List — ลำดับของการเรียก Canvas API ที่อธิบายว่าจะวาดอะไรและอย่างไร จากนั้นรายการนี้จะถูกส่งไปยัง Skia ซึ่งแบ่งการดำเนินการเป็นพาร์ติชัน (พื้นที่หน้าจอ) จัดเรียงตามความลึก และส่งต่อไปยังแบ็กเอนด์การเรนเดอร์ที่เกี่ยวข้อง การเร่ง GPU จะเปิดใช้งานโดยอัตโนมัติหาก Skia ตรวจพบ API กราฟิกที่พร้อมใช้งาน
ข้อดีหลักประการหนึ่งของ Skia ใน Flutter คือ Flutter Impeller Preview — ความสามารถในการดูตัวอย่างเชเดอร์ล่วงหน้า Skia คอมไพล์เชเดอร์ในขณะที่ใช้งานครั้งแรก ซึ่งอาจทำให้เกิดความล่าช้า (shader jank) เพื่อแก้ปัญหานี้ Flutter กำลังเปลี่ยนไปใช้ Impeller — เอนจินการเรนเดอร์ใหม่ แต่ Skia ยังคงเป็นตัวเลือกหลักสำหรับ Flutter เวอร์ชันเสถียร
Flutter ใช้แนวคิดของ Layer Tree — ต้นไม้ของเลเยอร์ แต่ละเลเยอร์แสดงส่วนหนึ่งของ UI Skia รับคำสั่งการวาดสำหรับแต่ละเลเยอร์และพิจารณาว่าสามารถรวมหลายเลเยอร์เป็นพาสการเรนเดอร์เดียวได้หรือไม่ การประกอบเลเยอร์ เป็นงานที่ซับซ้อน เนื่องจากสำหรับแต่ละพิกเซลต้องพิจารณาความโปร่งใสและโหมดการผสม (blend modes) ซึ่ง Skia ดำเนินการผ่านเชเดอร์ GPU
Skia เรนเดอร์ข้อความผ่านการรวมกับไลบรารี HarfBuzz (การจัดรูปทรง) และ ICU (ยูนิโคด) ใน Flutter วิดเจ็ตข้อความแต่ละตัวสร้างออบเจกต์ Paragraph ซึ่งแปลงข้อความเป็นชุดคำสั่ง Skia สำหรับวาดกลิฟ Skia รองรับการลดรอยหยักระดับย่อยพิกเซล (subpixel anti-aliasing), การแนะนำฟอนต์ (font hinting) และการทำงานกับอิโมจิผ่านไลบรารี SkUnicode
ประสิทธิภาพของ Skia เป็นผลจากการปรับให้เหมาะสมหลายปีและการผสมผสานของเทคนิคหลายอย่าง: การจัดกลุ่มคำสั่งเป็นแบตช์, การแคชเท็กซ์เจอร์ และการลดการสลับบริบท GPU ซึ่งสำคัญอย่างยิ่งสำหรับ Flutter เนื่องจากแต่ละเฟรมต้องเรนเดอร์ภายใน 16 มิลลิวินาที (60 FPS) หรือ 8 มิลลิวินาที (120 FPS)
| เทคนิค | คำอธิบาย | การปรับปรุง |
|---|---|---|
| การจัดกลุ่ม | การรวมการดำเนินการที่คล้ายกันเป็นคอลการวาดเดียว | สูงถึง 3x |
| แคชเท็กซ์เจอร์ | การใช้เท็กซ์เจอร์ที่โหลดแล้วใน GPU ซ้ำ | สูงถึง 2x |
| Atlas | การรวมเท็กซ์เจอร์ขนาดเล็กเป็นแอตลาสเท็กซ์เจอร์ขนาดใหญ่เดียว | สูงถึง 1.5x |
| การเรนเดอร์แบบรอการดำเนินการ | การดำเนินการคำสั่งที่เลื่อนออกไปพร้อมการเรียงลำดับใหม่ | สูงถึง 2x |
| การคอมไพล์เชเดอร์ล่วงหน้า | การคอมไพล์เชเดอร์ล่วงหน้าสำหรับ Spark/Dart | สูงถึง 4x |
ตามเกณฑ์มาตรฐานของ ทีม Flutter การใช้ Skia พร้อมการเร่ง GPU บนอุปกรณ์ระดับกลาง (Qualcomm Snapdragon 700 series) ให้ 60 FPS ที่เสถียรเมื่อเรนเดอร์อินเทอร์เฟซที่ซับซ้อนที่มีวิดเจ็ตมากกว่า 30 รายการบนหน้าจอ ด้วยการเรนเดอร์ซอฟต์แวร์ (CPU) ประสิทธิภาพลดลง 40–60% แต่ยังคงยอมรับได้สำหรับหน้าจอที่เรียบง่าย
ปัญหาด้านประสิทธิภาพหลักของ Skia ใน Flutter คือ shader jank (อาการกระตุกจากเชเดอร์) เมื่อองค์ประกอบภาพใหม่ที่มีการผสมผสานเอฟเฟกต์ที่ไม่เคยรู้จักมาก่อนปรากฏบนหน้าจอ Skia จะคอมไพล์เชเดอร์ใหม่ทันที การคอมไพล์อาจใช้เวลา 50–200 มิลลิวินาที ในระหว่างนั้นแอปพลิเคชัน จะ dropped เฟรม ซึ่งสังเกตได้ชัดเป็นพิเศษเมื่อเลื่อนรายการยาวที่มีการตกแต่งแบบกำหนดเอง Google กำลังแก้ปัญหานี้ด้วย Impeller เอนจินการเรนเดอร์ใหม่ที่คอมไพล์เชเดอร์ล่วงหน้า
Skia รองรับแพลตฟอร์มที่หลากหลาย แต่ละแพลตฟอร์มใช้แบ็กเอนด์การเรนเดอร์ของตนเอง การเลือกแบ็กเอนด์จะถูกกำหนดระหว่างการสร้าง Flutter Engine ตามแพลตฟอร์มเป้าหมายและ API กราฟิกที่พร้อมใช้งาน
บน Android Skia ทำงานผ่าน OpenGL ES (บนทุกอุปกรณ์) และ Vulkan (บนอุปกรณ์ Android 7.0+ ที่รองรับ Vulkan) การเลือกแบ็กเอนด์เป็นไปโดยอัตโนมัติ: Vulkan เป็นที่ต้องการเนื่องจากมีความหน่วงของไดรเวอร์ต่ำกว่า Android ยังใช้ Skia สำหรับการเรนเดอร์ UI ของระบบผ่าน HWUI (Hardware Accelerated UI) ทำให้ Skia เป็นส่วนหนึ่งของระบบปฏิบัติการ ไม่ใช่แค่ Flutter
บน iOS Skia ใช้ Metal — API กราฟิกกรรมสิทธิ์ของ Apple Metal ให้การเข้าถึง GPU ระดับต่ำพร้อมโอเวอร์เฮดน้อยที่สุด ก่อนการเปิดตัว Metal (2014) Skia บน iOS ใช้ OpenGL ES แต่ใน Flutter เวอร์ชันปัจจุบัน Metal เป็น แบ็กเอนด์ GPU เพียงตัวเดียวสำหรับ iOS ซึ่งให้ประสิทธิภาพดีขึ้นถึง 30% เมื่อเทียบกับ OpenGL
บนเดสก์ท็อป Skia ใช้ OpenGL (macOS, Linux) และ Direct3D 12 (Windows) การรองรับ Direct3D 12 ถูกเพิ่มใน Flutter 3.13 สำหรับ Windows และให้การปรับปรุงประสิทธิภาพอย่างมีนัยสำคัญเมื่อเทียบกับ OpenGL บน Windows Skia ยังรองรับการเรนเดอร์ซอฟต์แวร์ผ่าน ANGLE (OpenGL บน Direct3D) บน Windows เพื่อความเข้ากันได้ย้อนหลังกับไดรเวอร์กราฟิกเก่า
ใน Flutter for Web Skia ถูกคอมไพล์เป็น WebAssembly (ผ่าน Emscripten) และเรนเดอร์ผ่าน WebGL ในโหมดนี้ Skia ทำงานในเบราว์เซอร์อย่างสมบูรณ์โดยไม่ใช้โค้ดเนทีฟ ประสิทธิภาพของเวอร์ชัน WebGL ของ Skia ต่ำกว่าแบ็กเอนด์เนทีฟ แต่สำหรับแอปพลิเคชันเว็บส่วนใหญ่ 60 FPS สามารถทำได้บนเบราว์เซอร์สมัยใหม่ที่มีการเร่งฮาร์ดแวร์ WebGL
คำถามที่พบบ่อย
Shader jank คือความล่าช้าในการเรนเดอร์เนื่องจากการคอมไพล์เชเดอร์ทันที เมื่อ Skia พบการผสมผสานเอฟเฟกต์ภาพแบบใหม่ มันจะคอมไพล์เชเดอร์ซึ่งอาจใช้เวลา 50–200 มิลลิวินาที ในระหว่างนั้น เฟรมจะถูก dropped ปัญหานี้แก้ไขได้ใน Impeller ด้วยการคอมไพล์เชเดอร์ล่วงหน้า
ได้ Skia สามารถใช้เป็นไลบรารีกราฟิกแบบอิสระได้ มันถูกใช้ใน Google Chrome, Android, Mozilla Firefox (ผ่านชั้น Skia) และในโปรเจกต์ที่ต้องการกราฟิก 2D ประสิทธิภาพสูง Skia API พร้อมใช้งานในภาษา C++, Python และผ่านการเชื่อมต่อในภาษาอื่น
Flutter ใช้ฟอร์กของ Skia (โดยปกติคือคอมมิตเสถียรล่าสุดจากพื้นที่เก็บหลักของ Google) เวอร์ชันจะอัปเดตทุกครั้งที่มีการปล่อย Flutter Engine คอมมิตปัจจุบันสามารถพบได้ในไฟล์ DEPS ในพื้นที่เก็บ flutter/engine บน GitHub
Skia คอมไพล์เชเดอร์ในระหว่างรันไทม์ ซึ่งทำให้เกิด shader jank Impeller คอมไพล์เชเดอร์แบบออฟไลน์ (ล่วงหน้า) ใช้ SPIR-V และทำงานโดยตรงผ่าน Vulkan/Metal/Direct3D 12 Impeller ไม่ประสบปัญหาหน่วงจากเชเดอร์และให้ประสิทธิภาพที่คาดเดาได้มากกว่า
Skia ไม่ใช่เอนจินแอนิเมชันในตัวเอง — มันรับผิดชอบการเรนเดอร์เฟรมแต่ละเฟรม แอนิเมชันใน Flutter ดำเนินการในระดับเฟรมเวิร์ก (AnimationController, Tween) ในขณะที่ Skia รับประกันการเรนเดอร์ที่รวดเร็วของแต่ละเฟรมด้วย Canvas API และการเร่งด้วยฮาร์ดแวร์
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ