Press ESC to close

Bedah Google Maps: Saat Protobuf Diurai Langsung di Browser

Setelah drama IVS Player di Twitch dan kisah patah hati dengan VEWorker TikTok, saya pikir perjalanan NetMeter Web bakal sedikit tenang. Tapi ternyata tidak ada tenang-tenangnya, pemirsa! 😂

Masalah pelik lain adalah ketika mencoba melakukan benchmark bandwidth pada situs maps paling populer di tata surya kita, Google Maps.

Google Maps bukanlah situs buatan anak kemarin sore. Website ini dibangun dan dipelihara oleh para profesor dan engineer yang bukan lagi senior, tapi mbahnya senior. 🥸

Bayangkan! Satu dunia divisualisasikan dalam bentuk peta, lengkap dengan label, jalan, gedung, dan bahkan data lalu lintas realtime. Google Maps bukanlah proyek yang lahir dari kopi sachet dan semangat saja. Maps lahir dari riset bertahun-tahun dan optimasi teknologi gila-gilaan.

Dan ketika saya mencoba mengukur trafik data mereka untuk NetMeter Web, itu sama seperti mencoba menimbang berat ikan paus pakai timbangan digital dapur emak-emak. 😅

Secara garis besar, (hasil kongsi gelap saya dengan ChatGPT, Claude, dan Gemini), pipeline Maps kurang lebih seperti ini:

Penggunaan Protobuf di Worker Google Maps

Saat membuka Google Maps, apa pun jenis akun kalian (akun baru, akun lama, atau akun yang penuh label custom), Maps selalu mengirim vector tiles berbasis protobuf. Tile ini berisi data mentah seperti:

  • garis dan geometri jalan
  • polygon gedung
  • posisi label & icon
  • metadata zoom
  • layer & style aktif pengguna
Encoded Protobuf Google Maps

Semua tile ini berbentuk protobuf binary encoded, yang artinya bahwa browser tidak bisa menggambarnya langsung sehingga butuh proses decode, transform, dan rasterisasi sebelum muncul di layar.

Jika kalian bertanya, kenapa Google Maps menggunakan protobuf. Jawabannya adalah:

Protobuf mengirimkan data dalam format biner yang jauh lebih kecil dan lebih cepat untuk di-parse dibandingkan format lain seperti JSON atau XML.”

Lanjut lagi, siapa yang memproses vector tiles di Google Maps ini bergantung pada “profil” pengguna. Dan inilah hal menariknya:

Google Maps ternyata juga memiliki dua engine rendering berbeda:

  1. MapCore (WASM), biasanya dipakai untuk user-user Google baru.
  2. VTW (Vector Tile Worker, JS Worker), engine ini lebih fleksibel, khusus personalisasi kompleks.

Keduanya memproses data tile yang sama, tetapi melalui jalur berbeda.

MapCore WASM dan VTW Worker

Sedikit menelisik, ternyata MapCore WASM ini dipakai untuk user bersih atau minim personalisasi seperti akun baru, atau akun yang tidak punya banyak saved places, label custom atau mungkin label-label rumah pacar rahasia. 😆

Pada user baru yang saya uji coba, Google memilih mode MapCore, yaitu engine berbasis WebAssembly, contohnya file seperti:

maps/_/wa/w.jrS-1DvTO_w.mapcore.O.loader.js
maps/_/wa/w.jrS-1DvTO_w.mapcore.O.wasm

Di mode ini:

  • decode protobuf dilakukan oleh WASM (bukan JS)
  • rendering jauh lebih cepat
  • banyak komputasi berpindah dari worker ke WASM module
  • sebagian besar request muncul sebagai /proto?bpb=...

Inilah mode “high-performance” dari Google Maps, WASM on the hood.

Singkatnya, MapCore WASM (Mode A) adalah engine full speed untuk rendering dari A sampai Z, sedangkan VTW Worker (Mode B) adalah engine yang lebih fleksibel. Namun, file WASM tetap bertindak sebagai pustaka komputasi high-performance yang dapat dipanggil oleh VTW Worker untuk tugas-tugas tertentu

Kenapa Kita Tak Bisa Patch Worker Maps Dengan Teknik “Twitch-style”?

Ini pertanyaan yang mungkin akan muncul, dan jawaban simpelnya adalah:

“Karena Maps tidak dirancang untuk di-patch pihak ketiga. [DANGER Zone].”

CSP Google Maps itu super ketat. Sama ketatnya dengan TikTok, dipembahasan ini. Mereka mengirim header seperti:

Google Maps Protobuf Strict CSP

Yang artinya:

  • kita tidak boleh menggunakan Blob worker
  • tidak boleh menggunakan inline script
  • worker hanya boleh memuat script dari domain Maps, exact URL

Jadi ketika kita melakukan teknik inject “Blob dan importScripts()” seperti yang sukses untuk Twitch. Hal itu tidak akan berjalan di Google Maps.

Alasan lain selain CSP adalah Worker mereka signed dan strict, URL worker Maps sangat panjang dan selalu berubah:

.../js/k=maps.w.en.<signature>/...

Ketika saya mencoba mengganti dan mem-patching worker dengan Blob yang terjadi adalah:

  • Strukturnya berubah
  • Signature berubah
  • Loader gagal
  • Worker mati

Dan yep… setelah trial, Google Maps mendadak tidak meload tile sama sekali. Zoom-in, zoom-out masih bisa, tapi Maps seakan stuck tidak bisa merender gambar. Membuat kepala cenat-cenut! 😂

PerformanceObserver adalah Kunci?

Setelah mengetahui kenyataan diatas, akhirnya saya mencoba eksplor patch baru yang sebenarnya sudah lama saya commented di code patcher NetMeter, yakni patch PerformanceObserver.

Karna sudah tidak mungkin lagi melihat traffic dari worker Google Maps, saya berharap pada patch ini. Setelah melakukan trial, ada beberapa hal yang membuat saya bingung sekaligus chaotic:

  • Banyak request tidak muncul di Network Tab
  • Tetapi ada aktivitas jaringan,
  • Bahkan sebagian request hanya terlihat lewat PerformanceObserver

Intinya adalah PerformanceObserver (PO) bisa melihat yang tidak bisa dilihat fetch/XHR patcher. Tapi penggunaan PO ini juga harus berhati-hati karna PO akan melaporkan:

  • transferSize (wire network size)
  • encodedBodySize (yang sudah terkompres)
  • decodedBodySize (bisa 2–10x lipat dari ukuran kompresnya <– INI BERBAHAYA)

Di kasus Google Maps, dimana terjadi banyak request terselubung menjadikan penggunaan PerformanceObserve ini lebih mendekati masuk akal secara networking bandwidth. Tapi tidak serta merta menjadi akurat 100%.

DevTools bukanlah Source Of Truth

Mengalami kebingungan itu, saya jadi bertanya-tanya dan bingung, sebenarnya DevTools network bisa dijadikan source of truth bandwidth monitoring atau tidak?.

Saya pun akhirnya tersadar, bahwa DevTools network memang bukan sumbernya, dia memiliki blind spot di request berbasis non-http seperti Websocket, webRTC hingga WebTransport (paling gress), dan beberapa kasus networking lain.

Coba lihat jawaban yang agak membagongkan dari Gemini ini:

Please! Don’t Trust This 😂

Meski begitu, saya pribadi tidak menjamin 100% keakuratannya, dan tetap perlu deep dive lebih dalam lagi.

Akhir Kata

Mengukur bandwidth di web modern itu seperti menangkap ikan menggunakan tangan kosong. Karena request web modern itu sebagian bisa lewat Worker, ada yang lewat WASM, dari cache, dari SSE, webRTC, webSocket dan lainnya.

Karena itu NetMeter Web memang saya buat dengan memakai kombinasi:

  • webRequest background
  • patch fetch (reader)
  • patch XHR
  • WebSocket interceptor
  • WebRTC stats
  • native DOM decoded bytes
  • PerformanceObserver

Meski begitu, tidak ada satu API pun yang bisa melihat semuanya. Tapi jika kita coba menggabungkannya, maka kita bisa melihat gambaran real-time yang cukup akurat untuk analisis penggunaan bandwidth di browser.

Google Maps dan web modern lainnya mengajari saya satu hal penting:

Web modern itu jauh lebih kompleks dari hanya request -> response.

Many thanks to Google Maps Team!

Muhammad K Huda

A non exhausted blogger person within fullstack engineer (spicy food), open source religion, self-taught driver and maybe you know or don't like it. Simply says, Hello from Me!

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *

Cek untuk notifikasi e-mail jika komentar dibalas.

This site uses Akismet to reduce spam. Learn how your comment data is processed.