Memantau semua memori yang digunakan oleh halaman web: performance.measureMemory ()

Penulis artikel, terjemahan yang kami terbitkan hari ini, berbicara tentang cara memonitor memori yang dialokasikan untuk halaman web. Perhatian yang cermat terhadap memori halaman yang bekerja dalam produksi membantu menjaga produktivitas proyek web pada tingkat tinggi.



Browser secara otomatis mengontrol memori yang dialokasikan ke halaman web. Ketika sebuah halaman membuat objek, browser, menggunakan mekanisme internal, mengalokasikan memori untuk menyimpan objek ini. Karena memori bukan sumber daya tak terbatas, peramban secara berkala melakukan pengumpulan sampah, di mana objek yang tidak perlu terdeteksi dan memori yang ditempatinya dihapus. Namun, proses mendeteksi objek semacam itu tidak ideal. Sudah terbuktibahwa identifikasi objek semacam itu benar-benar akurat dan lengkap adalah tugas yang tidak dapat dipecahkan. Akibatnya, browser mengganti gagasan untuk menemukan "objek yang tidak perlu" dengan gagasan menemukan "objek yang tidak terjangkau". Jika halaman web tidak dapat mengakses objek melalui variabel dan bidang objek lain yang dapat diakses, ini berarti browser dapat dengan aman menghapus memori yang ditempati oleh objek tersebut. Perbedaan antara "tidak perlu" dan "tidak terjangkau" menyebabkan kebocoran memori, seperti yang diilustrasikan dalam contoh berikut:

const object = { a: new Array(1000), b: new Array(2000) };
setInterval(() => console.log(object.a), 1000);

Ada array yang tidak perlu besar di sini b, tetapi browser tidak membebaskan memori yang ditempatinya karena fakta bahwa itu dapat dicapai melalui properti objek object.bdi callback. Akibatnya, memori yang ditempati oleh array ini bocor.

Kebocoran memori adalah kejadian umum dalam pengembangan web. Mereka sangat mudah muncul dalam program ketika, misalnya, pengembang lupa untuk berhenti berlangganan dari pendengar acara, ketika mereka secara tidak sengaja menangkap objek dalam suatu elemen iframe, ketika mereka lupa untuk menutup pekerja, ketika mereka mengumpulkan objek dalam array. Jika halaman web mengalami kebocoran memori, ini mengarah pada fakta bahwa seiring waktu pemakaian memori halaman meningkat. Halaman seperti itu tampaknya lambat dan lambat bagi pengguna.

Langkah pertama dalam memecahkan masalah ini adalah melakukan pengukuran. API performance.measureMemory () yang baru memungkinkan pengembang untuk mengukur penggunaan memori berdasarkan halaman web dalam produksi dan, sebagai hasilnya, mendeteksi kebocoran memori yang lolos tes lokal.

Apa perbedaan antara API performance.measureMemory () yang baru dengan performance.memory yang lama?


Jika Anda terbiasa dengan API non-standar yang ada performance.memory, maka Anda mungkin tertarik dengan pertanyaan tentang bagaimana API baru berbeda dari yang lama. Perbedaan utama adalah bahwa API lama mengembalikan ukuran tumpukan JavaScript, dan yang baru mengevaluasi penggunaan memori seluruh halaman web. Perbedaan ini penting ketika Chrome mengatur berbagi timbunan antara beberapa halaman web (atau beberapa contoh dari halaman yang sama). Dalam kasus seperti itu, hasil yang dikembalikan oleh API lama dapat terdistorsi. Karena API lama didefinisikan dalam istilah khusus untuk implementasi, seperti heap, menstandarkanasinya adalah bisnis tanpa harapan.

Perbedaan lainnya adalah bahwa di Chrome, API baru melakukan pengukuran memori saat mengumpulkan sampah. Ini mengurangi "noise" dalam hasil pengukuran, tetapi mungkin perlu waktu untuk mendapatkan hasilnya. Harap perhatikan bahwa pembuat browser lain dapat memutuskan untuk menerapkan API baru tanpa mengikat ke pengumpulan sampah.

Cara yang Disarankan untuk Menggunakan API Baru


Penggunaan memori oleh halaman web tergantung pada kejadian, pada tindakan pengguna, pada pengumpulan sampah. Itulah sebabnya API performance.measureMemory()dirancang untuk mempelajari tingkat penggunaan memori dalam produksi. Hasil memanggil API ini di lingkungan pengujian kurang bermanfaat. Berikut adalah contoh opsi untuk menggunakannya:

  • - .
  • A/B- , .
  • .
  • , . .


Saat ini, API yang dipermasalahkan hanya didukung di Chrome 83, sesuai dengan skema Uji Coba Asal. Hasil yang dikembalikan oleh API sangat tergantung pada implementasi, karena browser yang berbeda menggunakan cara yang berbeda untuk mewakili objek dalam memori dan cara yang berbeda untuk menilai tingkat penggunaan memori. Browser dapat mengecualikan beberapa area memori dari akuntansi jika akuntansi lengkap dari semua memori yang digunakan adalah tugas yang terlalu sulit atau tidak mungkin dilakukan. Sebagai hasilnya, kita dapat mengatakan bahwa hasil yang dihasilkan oleh API ini di browser yang berbeda tidak dapat dibandingkan. Masuk akal untuk membandingkan hanya hasil yang diperoleh di browser yang sama.

Kemajuan pekerjaan saat ini


Langkahkondisi
1. Membuat Penjelasan API
Lengkap
2. Membuat spesifikasi konsep
Dilakukan
3. Mengumpulkan umpan balik dan menyelesaikan proyek
Dilakukan
4. Uji Coba Asal
Dilakukan
5. Luncurkan
Belum mulai

Menggunakan performance.measureMemory ()


▍ Aktifkan Dukungan Uji Coba Asal


API performance.measureMemory()tersedia di Chrome 83 sesuai dengan skema Uji Coba Asal. Fase ini diharapkan berakhir dengan rilis Chrome 84.

Origin Trial memungkinkan pengembang untuk mengambil keuntungan dari fitur baru Chrome dan berbagi umpan balik tentang kenyamanan, kegunaan, dan keefektifan fitur-fitur ini dengan komunitas web. Detail tentang program ini dapat ditemukan di sini . Anda dapat berlangganan program di halaman pendaftaran.

▍ Pendaftaran dalam program Origin Trial


  1. Minta token untuk kesempatan yang menarik bagi Anda.
  2. Tambahkan token ke halaman proyek percontohan. Ada 2 cara untuk melakukan ini:

    • Tambahkan <meta>tag origin-trialke judul setiap halaman. Sebagai contoh, mungkin terlihat seperti ini: <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">.
    • Jika Anda memiliki akses ke pengaturan server, itu dapat menambahkan token menggunakan header HTTP Origin-Trial. Akibatnya, respon header akan muncul sesuatu seperti berikut ini: Origin-Trial: TOKEN_GOES_HERE.

▍Mengaktifkan fitur baru melalui bendera Chrome


Dalam rangka untuk bereksperimen dengan performance.measureMemory(), sementara pengeluaran dengan token Asal Trial, Anda perlu mengaktifkan bendera #experimental-web-platform-featuresdi chrome://flags.

▍Periksa Penggunaan API


Panggilan fungsi performance.measureMemory()mungkin gagal, dengan SecurityError dilemparkan . Ini dapat terjadi jika lingkungan tidak memenuhi persyaratan keamanan untuk kebocoran informasi. Selama uji Coba Asal di Chrome, API ini membutuhkan penyertaan Isolasi Situs . Ketika API siap untuk penggunaan normal, itu akan bergantung pada properti crossOriginIsolated . Halaman web dapat beroperasi dalam mode ini dengan mengatur COOP dan COEP header .

Berikut ini contoh kode:

if (performance.measureMemory) {
  let result;
  try {
    result = await performance.measureMemory();
  } catch (error) {
    if (error instanceof DOMException &&
        error.name === "SecurityError") {
      console.log("The context is not secure.");
    } else {
      throw error;
    }
  }
  console.log(result);
}

▍ Pengujian lokal


Chrome melakukan pengukuran memori saat mengumpulkan sampah. Ini berarti bahwa mengakses API tidak secara instan menyelesaikan janji. Untuk mendapatkan hasilnya, Anda harus menunggu sesi pengumpulan sampah berikutnya. API secara paksa memulai pengumpulan sampah setelah batas waktu tertentu, yang saat ini diatur ke 20 detik. Jika Anda menjalankan Chrome dengan bendera baris perintah --enable-blink-features='ForceEagerMeasureMemory', batas waktu akan dikurangi menjadi nol, yang berguna untuk debugging lokal dan pengujian lokal.

Contoh


Disarankan agar Anda menggunakan API baru dengan menetapkan monitor memori global yang mengukur tingkat penggunaan memori seluruh halaman dan mengirimkan hasilnya ke server, di mana mereka dapat dikumpulkan dan dianalisis. Cara termudah untuk bekerja dengan API ini adalah dengan melakukan pengukuran berkala. Misalnya, mereka dapat berjalan setiap Mmenit. Ini, bagaimanapun, memperkenalkan distorsi ke dalam data, karena puncak dalam penggunaan memori dapat terjadi di antara pengukuran. Contoh berikut menunjukkan bagaimana, menggunakan proses Poisson , untuk membuat pengukuran bebas dari kesalahan sistematis. Pendekatan ini memastikan bahwa sesi pengukuran dapat, dengan probabilitas yang sama, terjadi di setiap titik waktu (di sini adalah demonstrasi dari pendekatan ini,di sini adalah kode sumber).

Pertama, mendeklarasikan fungsi yang merencanakan awal sesi berikutnya untuk mengukur jumlah memori yang dikonsumsi menggunakan fungsi setTimeout()dengan interval yang ditetapkan secara acak. Fungsi ini harus dipanggil setelah memuat halaman di jendela browser.

function scheduleMeasurement() {
  if (!performance.measureMemory) {
    console.log("performance.measureMemory() is not available.");
    return;
  }
  const interval = measurementInterval();
  console.log("Scheduling memory measurement in " +
      Math.round(interval / 1000) + " seconds.");
  setTimeout(performMeasurement, interval);
}

//       .
window.onload = function () {
  scheduleMeasurement();
}

Fungsi measurementInterval()menemukan interval acak, dinyatakan dalam milidetik, diatur sedemikian rupa sehingga satu pengukuran akan dilakukan kira-kira setiap lima menit. Jika Anda tertarik pada konsep matematika yang menjadi dasar fungsi ini, baca tentang distribusi eksponensial .

function measurementInterval() {
  const MEAN_INTERVAL_IN_MS = 5 * 60 * 1000;
  return -Math.log(Math.random()) * MEAN_INTERVAL_IN_MS;
}

Akibatnya, fungsi asinkron performMeasurement()memanggil API kami, mencatat hasilnya, dan merencanakan pengukuran berikutnya.

async function performMeasurement() {
  // 1.  performance.measureMemory().
  let result;
  try {
    result = await performance.measureMemory();
  } catch (error) {
    if (error instanceof DOMException &&
        error.name === "SecurityError") {
      console.log("The context is not secure.");
      return;
    }
    //    .
    throw error;
  }
  // 2.  .
  console.log("Memory usage:", result);
  // 3.   .
  scheduleMeasurement();
}

Hasil pengukuran mungkin terlihat seperti ini:

// ,    :
{
  bytes: 60_000_000,
  breakdown: [
    {
      bytes: 40_000_000,
      attribution: ["https://foo.com"],
      userAgentSpecificTypes: ["Window", "JS"]
    },
    {
      bytes: 20_000_000,
      attribution: ["https://foo.com/iframe"],
      userAgentSpecificTypes: ["Window", "JS"]
    }
  ]
}

Perkiraan tingkat keseluruhan penggunaan memori ditampilkan di bidang bytes. Saat memperoleh estimasi ini, pemisah digit angka digunakan. Nilai-nilai ini sangat tergantung pada implementasi. Jika mereka diterima untuk browser yang berbeda, maka Anda tidak dapat membandingkannya. Cara mereka diperoleh dapat bervariasi bahkan dalam berbagai versi browser yang sama. Selama program Origin Trial berlangsung, nilai kembali mencakup indikator penggunaan memori JavaScript oleh jendela utama, indikator penggunaan elemen memori dari iframesitus yang sama, dan indikator jendela terkait. Ketika API siap, nilai ini akan mewakili informasi tentang memori yang dikonsumsi oleh JavaScript, DOM, semua elemen yang iframeterkait dengan windows dan pekerja web.

Daftarbreakdownmemberikan informasi lebih rinci tentang memori yang digunakan. Setiap entri menggambarkan sepotong memori dan mengaitkan fragmen ini dengan satu set jendela, elemen, iframeatau pekerja yang diidentifikasi oleh URL. Bidang ini userAgentSpecificTypesmencantumkan jenis memori yang ditentukan oleh fitur implementasi.

Penting untuk mempertimbangkan daftar-daftar ini secara umum dan tidak mencoba, bergantung pada fitur-fitur browser tertentu, untuk menganalisis semuanya berdasarkan pada mereka. Misalnya, beberapa browser dapat mengembalikan daftar breakdownkosong atau bidang kosong attribution. Peramban lain dapat mengembalikan attributionbeberapa URL dalam suatu elemen , yang menunjukkan bahwa mereka tidak dapat menentukan dari URL mana memori ini berada.

Umpan balik


Grup Komunitas Kinerja Web dan tim pengembangan Chrome akan dengan senang hati mengetahui apa yang Anda pikirkan performance.measureMemory()dan pelajari tentang pengalaman Anda menggunakan API ini.

Bagikan ide Anda tentang perangkat API dengan kami


Apakah ada sesuatu dalam API ini yang tidak berfungsi seperti yang diharapkan? Mungkin itu kekurangan sesuatu yang Anda butuhkan untuk mengimplementasikan ide Anda? Buka tugas baru di pelacak proyek atau komentari tugas yang ada.

Laporkan masalah implementasi


Menemukan bug dalam implementasi Chrome Anda? Atau mungkin ternyata implementasinya berbeda dengan spesifikasinya? Catat kesalahan di sini: new.crbug.com . Cobalah untuk memasukkan sebanyak mungkin detail dalam pesan Anda, sertakan instruksi sederhana tentang cara mereproduksi kesalahan, dan tunjukkan bahwa masalahnya terkait Blink>PerformanceAPIs. Glitch adalah cara yang sangat baik untuk menunjukkan kesalahan .

Dukung kami


performance.measureMemory()Apakah Anda berencana untuk menggunakannya ? Jika memang begitu, katakan kepada kami tentang itu. Kisah-kisah ini membantu memprioritaskan tim pengembangan Chrome. Kisah-kisah ini menunjukkan kepada pencipta browser lain pentingnya mendukung fitur baru. Jika Anda mau, kirim tweet ke @ChromiumDev dan beri tahu kami di mana dan bagaimana Anda menggunakan API baru.

Pembaca yang budiman! Sudahkah Anda mencoba performance.measureMemory()?


All Articles