หลีกเลี่ยงการดาวน์โหลดที่ไม่ได้เพิ่มประสิทธิภาพ

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

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

ในทํานองเดียวกัน เมื่อดาวน์โหลดรูปภาพ แนวทางปฏิบัติแนะนำคือการลดขนาดรูปภาพฝั่งเซิร์ฟเวอร์ แทนการดาวน์โหลดรูปภาพขนาดเต็มซึ่งจะลดขนาดในฝั่งไคลเอ็นต์

แคชการตอบกลับ HTTP

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

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

โปรดใช้รหัสสถานะและส่วนหัว HTTP ที่เหมาะสมเพื่อให้แน่ใจว่าการแคชจะไม่ทําให้แอปแสดงข้อมูลที่ล้าสมัย เช่น ส่วนหัว ETag และ Last-Modified ซึ่งจะช่วยให้คุณระบุได้ว่าควรรีเฟรชเนื้อหาที่เกี่ยวข้องเมื่อใด เช่น

KotlinJava
// url represents the website containing the content to place into the cache.
val conn: HttpsURLConnection = url.openConnection() as HttpsURLConnection
val currentTime: Long = System.currentTimeMillis()
val lastModified: Long = conn.getHeaderFieldDate("Last-Modified", currentTime)

// lastUpdateTime represents when the cache was last updated.
if (lastModified < lastUpdateTime) {
    // Skip update
} else {
    // Parse update
    lastUpdateTime = lastModified
}
// url represents the website containing the content to place into the cache.
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
long currentTime = System.currentTimeMillis();
long lastModified = conn.getHeaderFieldDate("Last-Modified", currentTime);

// lastUpdateTime represents when the cache was last updated.
if (lastModified < lastUpdateTime) {
    // Skip update
} else {
    // Parse update
    lastUpdateTime = lastModified;
}

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

KotlinJava
val cacheDir = Context.getCacheDir()
val cacheSize = 10L * 1024L * 1024L // 10 MiB
val client: OkHttpClient = OkHttpClient.Builder()
    .cache(Cache(cacheDir, cacheSize))
    .build()
File cacheDir = Context.getCacheDir();
long cacheSize = 10L * 1024L * 1024L; // 10 MiB
OkHttpClient client = new OkHttpClient.Builder()
    .cache(new Cache(cacheDir, cacheSize))
    .build();

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

คุณสามารถแคชข้อมูลที่ไม่ใช่ข้อมูลที่ละเอียดอ่อนในไดเรกทอรีแคชภายนอกที่ไม่มีการจัดการได้โดยใช้ Context.getExternalCacheDir() หรือจะแคชข้อมูลในแคชแอปพลิเคชันที่ปลอดภัยซึ่งมีการจัดการก็ได้โดยการใช้ Context.getCacheDir() โปรดทราบว่าแคชภายในอาจถูกล้างเมื่อระบบเหลือพื้นที่เก็บข้อมูลที่ใช้ได้เหลือน้อย

ใช้ที่เก็บ

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