Pada modul terakhir, ringkasan web worker telah diberikan. Web worker dapat meningkatkan responsivitas input dengan memindahkan JavaScript dari thread utama ke thread web worker terpisah, yang dapat membantu meningkatkan Interaksi ke Paint Berikutnya (INP) situs Anda jika Anda memiliki tugas yang tidak memerlukan akses langsung ke thread utama. Namun, ringkasan saja tidak cukup, dan dalam modul ini, kasus penggunaan konkret untuk web worker ditawarkan.
Salah satu kasus penggunaan tersebut adalah situs yang perlu menghapus metadata Exif dari gambar—konsep ini tidak terlalu sulit dipahami. Faktanya, situs seperti Flickr menawarkan cara kepada pengguna untuk melihat metadata Exif guna mempelajari detail teknis tentang gambar yang dihostingnya, seperti kedalaman warna, merek dan model kamera, serta data lainnya.
Namun, logika untuk mengambil gambar, mengonversinya ke ArrayBuffer
,
dan mengekstrak metadata Exif berpotensi mahal jika dilakukan sepenuhnya
di thread utama. Untungnya, cakupan pekerja web memungkinkan pekerjaan ini dilakukan di luar thread utama. Kemudian, menggunakan pipeline pesan web worker, metadata Exif dikirim kembali ke thread utama sebagai string HTML, dan ditampilkan kepada pengguna.
Tampilan thread utama tanpa pekerja web
Pertama, amati tampilan thread utama saat kita melakukan pekerjaan ini tanpa pekerja web. Caranya, lakukan langkah-langkah berikut:
- Buka tab baru di Chrome, lalu buka DevTools-nya.
- Buka panel performa.
- Buka https://chrome.dev/learn-performance-exif-worker/without-worker.html.
- Di panel performa, klik Rekam di sudut kanan atas panel DevTools.
- Tempelkan link gambar ini—atau link lain pilihan Anda yang berisi metadata Exif—di kolom dan klik tombol Dapatkan JPEG itu!.
- Setelah antarmuka diisi dengan metadata Exif, klik Rekam lagi untuk berhenti merekam.

Perhatikan bahwa—selain thread lain yang mungkin ada, seperti thread rasterizer dan sebagainya—semua yang ada di aplikasi terjadi di thread utama. Di thread utama, hal berikut terjadi:
- Formulir mengambil input dan mengirimkan permintaan
fetch
untuk mendapatkan bagian awal gambar yang berisi metadata Exif. - Data gambar dikonversi menjadi
ArrayBuffer
. - Skrip
exif-reader
digunakan untuk mengekstrak metadata Exif dari gambar. - Metadata di-scrap untuk membuat string HTML, yang kemudian mengisi penampil metadata.
Sekarang bandingkan dengan penerapan perilaku yang sama—tetapi menggunakan web worker.
Tampilan thread utama dengan pekerja web
Setelah melihat tampilan proses ekstraksi metadata Exif dari file JPEG di thread utama, lihat tampilannya saat web worker terlibat:
- Buka tab lain di Chrome, lalu buka DevTools-nya.
- Buka panel performa.
- Buka https://chrome.dev/learn-performance-exif-worker/with-worker.html.
- Di panel performa, klik tombol rekam di pojok kanan atas panel DevTools.
- Tempelkan link gambar ini di kolom, lalu klik tombol Get that JPEG!.
- Setelah antarmuka diisi dengan metadata Exif, klik tombol rekam lagi untuk berhenti merekam.

Inilah kekuatan pekerja web. Daripada melakukan semuanya di thread utama, semuanya kecuali mengisi penampil metadata dengan HTML dilakukan di thread terpisah. Artinya, thread utama dibebaskan untuk melakukan tugas lain.
Keuntungan terbesar di sini adalah, tidak seperti versi aplikasi ini yang tidak menggunakan pekerja web, skrip exif-reader
tidak dimuat di thread utama, melainkan di thread pekerja web. Artinya, biaya
download, penguraian, dan kompilasi skrip exif-reader
dilakukan di luar
thread utama.
Sekarang mari kita pelajari kode pekerja web yang memungkinkan semua ini terjadi.
Melihat kode pekerja web
Tidak cukup hanya melihat perbedaan yang dihasilkan web worker, tetapi juga membantu memahami—setidaknya dalam kasus ini—tampilan kode tersebut sehingga Anda mengetahui apa yang mungkin terjadi dalam cakupan web worker.
Mulai dengan kode thread utama yang harus terjadi sebelum pekerja web dapat berperan:
// scripts.js
// Register the Exif reader web worker:
const exifWorker = new Worker('/js/with-worker/exif-worker.js');
// We have to send image requests through this proxy due to CORS limitations:
const imageFetchPrefix = 'https://res.cloudinary.com/demo/image/fetch/';
// Necessary elements we need to select:
const imageFetchPanel = document.getElementById('image-fetch');
const imageExifDataPanel = document.getElementById('image-exif-data');
const exifDataPanel = document.getElementById('exif-data');
const imageInput = document.getElementById('image-url');
// What to do when the form is submitted.
document.getElementById('image-form').addEventListener('submit', event => {
// Don't let the form submit by default:
event.preventDefault();
// Send the image URL to the web worker on submit:
exifWorker.postMessage(`${imageFetchPrefix}${imageInput.value}`);
});
// This listens for the Exif metadata to come back from the web worker:
exifWorker.addEventListener('message', ({ data }) => {
// This populates the Exif metadata viewer:
exifDataPanel.innerHTML = data.message;
imageFetchPanel.style.display = 'none';
imageExifDataPanel.style.display = 'block';
});
Kode ini berjalan di thread utama, dan menyiapkan formulir untuk mengirim URL gambar ke
pekerja web. Dari sana, kode pekerja web dimulai dengan pernyataan importScripts
yang memuat skrip exif-reader
eksternal, lalu menyiapkan
pipeline pesan ke thread utama:
// exif-worker.js
// Import the exif-reader script:
importScripts('/js/with-worker/exifreader.js');
// Set up a messaging pipeline to send the Exif data to the `window`:
self.addEventListener('message', ({ data }) => {
getExifDataFromImage(data).then(status => {
self.postMessage(status);
});
});
JavaScript ini menyiapkan pipeline pesan sehingga saat pengguna mengirimkan formulir dengan URL ke file JPEG, URL tersebut akan tiba di web worker.
Dari sana, bagian kode berikutnya ini mengekstrak metadata Exif dari file JPEG,
membuat string HTML, dan mengirimkan HTML tersebut kembali ke window
untuk akhirnya
ditampilkan kepada pengguna:
// Takes a blob to transform the image data into an `ArrayBuffer`:
// NOTE: these promises are simplified for readability, and don't include
// rejections on failures. Check out the complete web worker code:
// https://chrome.dev/learn-performance-exif-worker/js/with-worker/exif-worker.js
const readBlobAsArrayBuffer = blob => new Promise(resolve => {
const reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.readAsArrayBuffer(blob);
});
// Takes the Exif metadata and converts it to a markup string to
// display in the Exif metadata viewer in the DOM:
const exifToMarkup = exif => Object.entries(exif).map(([exifNode, exifData]) => {
return `
<details>
<summary>
<h2>${exifNode}</h2>
</summary>
<p>${exifNode === 'base64' ? `<img src="data:image/jpeg;base64,${exifData}">` : typeof exifData.value === 'undefined' ? exifData : exifData.description || exifData.value}</p>
</details>
`;
}).join('');
// Fetches a partial image and gets its Exif data
const getExifDataFromImage = imageUrl => new Promise(resolve => {
fetch(imageUrl, {
headers: {
// Use a range request to only download the first 64 KiB of an image.
// This ensures bandwidth isn't wasted by downloading what may be a huge
// JPEG file when all that's needed is the metadata.
'Range': `bytes=0-${2 ** 10 * 64}`
}
}).then(response => {
if (response.ok) {
return response.clone().blob();
}
}).then(responseBlob => {
readBlobAsArrayBuffer(responseBlob).then(arrayBuffer => {
const tags = ExifReader.load(arrayBuffer, {
expanded: true
});
resolve({
status: true,
message: Object.values(tags).map(tag => exifToMarkup(tag)).join('')
});
});
});
});
Memang agak panjang, tetapi ini juga merupakan kasus penggunaan yang cukup rumit untuk pekerja web.
Namun, hasilnya sebanding dengan upaya yang dilakukan, dan tidak hanya terbatas pada kasus penggunaan ini.
Anda dapat menggunakan pekerja web untuk berbagai hal, seperti mengisolasi panggilan fetch
dan memproses respons, memproses data dalam jumlah besar tanpa memblokir thread utama—dan itu baru permulaan.
Saat meningkatkan performa aplikasi web, mulailah memikirkan apa pun yang dapat dilakukan secara wajar dalam konteks pekerja web. Peningkatan yang didapat bisa signifikan, dan dapat menghasilkan pengalaman pengguna yang lebih baik secara keseluruhan untuk situs Anda.