SQL Anda Cepat, Namun API Anda Lambat

Query database Anda cepat. Caching Anda berfungsi. Background job Anda berjalan baik.

Namun, API Anda tetap lambat. Penggunaan CPU Anda tinggi.

Masalahnya bukan pada database Anda. Masalahnya ada pada lapisan Ruby.

Bottleneck sering terjadi setelah data keluar dari database dan masuk ke aplikasi Anda. Hal ini terjadi melalui tiga masalah utama:

  • Serialisasi yang membengkak
  • Alokasi objek yang berlebihan
  • Komputasi yang berulang

Berikut cara memperbaikinya.

  1. Hentikan Serialisasi yang Membengkak

Banyak pengembang mengubah seluruh model menjadi JSON.

render json: @shipments

Jika sebuah pengiriman memiliki 40 kolom tetapi frontend Anda hanya membutuhkan 5, Anda membuang-buang siklus CPU. Anda juga berisiko membocorkan data pribadi seperti API key atau biaya.

Solusinya: kembalikan hanya field yang Anda butuhkan.

render json: @shipments.as_json(only: [:id, :tracking_no, :status])

Untuk kecepatan yang lebih baik lagi, gunakan pluck untuk mengambil data sebagai array. Ini sepenuhnya menghindari pembuatan objek ActiveRecord yang berat.

  1. Kurangi Alokasi Objek

Setiap objek yang dibuat Ruby memakan memori. Membuat ribuan objek selama satu request memaksa Garbage Collector (GC) bekerja lebih keras. Hal ini memperlambat seluruh sistem Anda.

Hindari membuat hash atau string baru di dalam loop.

Buruk:

@shipments.map do |s|
  { label: "#{s.tracking_no} - #{s.status.upcase}" }
end

Baik: Pindahkan data statis ke luar loop. Lakukan lebih banyak pekerjaan di database daripada di Ruby.

  1. Hindari Komputasi yang Berulang

Jika Anda memanggil metode yang sama berkali-kali dalam satu request, Anda membuang-buang waktu.

Contoh:

def total_weight
  shipments.sum(&:weight)
end

Jika view, helper, dan serializer Anda semuanya memanggil ini, Anda menghitung jumlahnya tiga kali.

Solusinya: gunakan memoization.

def total_weight
  @total_weight ||= shipments.sum(&:weight)
end

Ini memastikan perhitungan hanya terjadi satu kali per request.

Tabel Ringkasan:

  • Serialisasi yang membengkak: Kembalikan hanya field yang dibutuhkan atau gunakan pluck.
  • Alokasi tinggi: Buat lebih sedikit objek di dalam loop.
  • Komputasi berulang: Gunakan memoization untuk menggunakan kembali hasil.

Optimasi database berarti meminta lebih sedikit data. Optimasi aplikasi berarti melakukan lebih sedikit pekerjaan tambahan setelah Anda mendapatkan datanya.

Sumber: https://dev.to/danewu/your-sql-is-fast-but-the-api-is-slow-its-the-ruby-layer-2fno