Obiekty transferowalne
Proszę wydajnie przenosić dane bez ich kopiowania.
Obiekty transferowalne to bezpłatna lekcja JavaScript Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej JavaScript Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs JavaScript Academy zawiera 4 lekcji w sumie.
Koszt klonowania
Klonowanie strukturalne kopiuje dane bajt po bajcie. W przypadku dużych buforów (obrazów, dźwięku, dużych tablic) kopiowanie jest powolne i podwaja zużycie pamięci. Obiekty transferowalne rozwiązują ten problem, przenosząc własność zamiast kopiowania.
Co można transferować
Tylko niektóre typy obiektów można transferować, przede wszystkim ArrayBuffer. Pozostałe to MessagePort, ImageBitmap i OffscreenCanvas.
ArrayBuffer— surowa pamięć binarnaMessagePort— punkt końcowy kanałuImageBitmap— zdekodowane dane obrazu
Lista transferu
postMessage przyjmuje drugi argument: listę obiektów transferowalnych. Obiekty znajdujące się na tej liście są przenoszone, a nie kopiowane.
const buffer = new ArrayBuffer(1024 * 1024); // 1 MB
worker.postMessage(buffer, [buffer]); // transfer itPrzeniesienie własności
Po transferze strona wysyłająca nie może już używać bufora; zostaje on odłączony (byteLength 0). Strona odbierająca jest teraz właścicielem tej samej pamięci bazowej, bez wykonywania kopii.
const buffer = new ArrayBuffer(8);
worker.postMessage(buffer, [buffer]);
console.log(buffer.byteLength); // 0 - now detachedTransferowanie tablic typowanych
Należy transferować bazowy ArrayBuffer tablicy typowanej za pośrednictwem właściwości .buffer. Sam widok nie jest transferowalny, ale jego bufor już tak.
const data = new Float64Array(100000);
worker.postMessage(data, [data.buffer]);
// data is now detached on this side.Odbieranie transferu
Strona odbierająca odczytuje transferowany obiekt z event.data dokładnie tak samo jak sklonowany komunikat. Różnica polega wyłącznie na tym, że nie wykonano kopii.
// worker.js
self.onmessage = (e) => {
const buffer = e.data; // we now own this memory
const view = new Uint8Array(buffer);
view[0] = 255;
};Odsyłanie wyników
Worker może po przetworzeniu przenieść bufor z powrotem, ponownie bez kopiowania, oddając własność głównemu wątkowi.
// worker.js
self.onmessage = (e) => {
const buffer = e.data;
// ...process the bytes...
self.postMessage(buffer, [buffer]); // transfer back
};Wydajność transferu a klonowania
W przypadku kilku kilobajtów różnica jest pomijalna. W przypadku megabajtów danych binarnych transfer jest zdecydowanie szybszy i pozwala uniknąć nagłego wzrostu zużycia pamięci. Należy używać go w przypadku dużych buforów.
Unikanie błędów użycia po transferze
Częstym błędem jest odczytywanie bufora po jego transferze. Zawsze należy traktować bufor jako niedostępny, gdy tylko pojawi się na liście transferu.
worker.postMessage(buffer, [buffer]);
// BUG: buffer is detached here; this reads zero length.
// const len = buffer.byteLength; // 0Łączenie klonowanych i transferowanych danych
Można wysłać obiekt zawierający bufor i transferować tylko ten bufor. Obiekt jest klonowany, a bufor wymieniony na liście jest przenoszony.
const msg = { type: 'frame', pixels: buffer };
worker.postMessage(msg, [buffer]);
// msg.type is cloned; buffer is transferred.Kiedy używać transferu
Obiektów transferowalnych należy używać do przetwarzania obrazów, dźwięku i wideo, dużych obliczeń numerycznych oraz każdego potoku, który przenosi duże bloki danych binarnych między wątkami. W przypadku małych danych podobnych do JSON zwykłe klonowanie jest prostsze i wystarczające.
Szybki test
Proszę sprawdzić, czy rozumieją Państwo działanie obiektów transferowalnych.
Podsumowanie
Poznali Państwo obiekty transferowalne:
- Listę transferu należy przekazać jako drugi argument metody
postMessage. ArrayBuffer(i kilka innych typów) są przenoszone zamiast kopiowane.- Bufor nadawcy zostaje później odłączony.
- Tablicę typowaną należy transferować za pomocą jej właściwości
.buffer. - Transferu należy używać w przypadku dużych danych binarnych, a klonowania w przypadku małych danych.
Następnie omówimy zastosowania i ograniczenia workerów.
Często zadawane pytania
Czy lekcja „Obiekty transferowalne” jest bezpłatna?
Tak — pełny tekst „Obiekty transferowalne” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu JavaScript Academy, przejdź na CoddyKit PRO. Kurs JavaScript Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Obiekty transferowalne”?
Proszę wydajnie przenosić dane bez ich kopiowania. Ćwiczysz JavaScript Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć JavaScript Academy?
Nie wymagamy żadnego doświadczenia. JavaScript Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Obiekty transferowalne”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji JavaScript Academy?
Tak. Każda lekcja JavaScript Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Tworzenie Web Workera
- Komunikacja za pomocą postMessage
- Obiekty transferowalne
- Zastosowania i ograniczenia