Imej pra-caching dengan ketegangan reaksi
Ciri ketegangan React adalah menarik, dan ia akan datang, dan akan membolehkan pemaju mudah menangguhkan rendering komponen mereka sehingga mereka "bersedia", menghasilkan pengalaman pengguna yang lebih lancar. "Sediakan" boleh merujuk kepada banyak aspek di sini. Sebagai contoh, utiliti pemuatan data anda boleh digunakan bersempena dengan ketegangan untuk membolehkan status pemuatan yang konsisten dipaparkan semasa sebarang data dipindahkan tanpa mengesan status beban secara manual untuk setiap pertanyaan. Kemudian, apabila data anda tersedia dan komponen anda adalah "siap", ia akan diberikan. Inilah topik yang paling sering dibincangkan dengan ketegangan, dan saya telah menulis tentangnya sebelum ini; Walau bagaimanapun, pemuatan data hanyalah salah satu daripada banyak kes penggunaan di mana ketegangan dapat meningkatkan pengalaman pengguna. Satu lagi kes penggunaan yang ingin saya bicarakan hari ini ialah Pramuat Imej.
Pernahkah anda membuat atau menggunakan aplikasi web di mana kedudukan anda terjejas dan melompat sebagai imej dimuat turun dan diberikan apabila mencapai skrin? Kami menyebutnya penyusunan semula kandungan, dan ia mengejutkan dan tidak menyenangkan. Ketegangan dapat membantu menyelesaikan masalah ini. Adakah anda tahu saya mengatakan bahawa keseluruhan titik ketegangan adalah untuk mengelakkan komponen rendering sehingga siap? Nasib baik, "siap" sangat terbuka di sini - untuk tujuan kami, ia boleh termasuk "imej yang dimuatkan yang kami perlukan". Mari lihat bagaimana melakukannya!
Permulaan cepat ketegangan
Sebelum menggali butiran, mari kita faham dengan cepat bagaimana ketegangan berfungsi. Ia mempunyai dua bahagian utama. Pertama sekali, terdapat konsep komponen hang. Ini bermakna React cuba untuk menjadikan komponen kami, tetapi ia tidak "siap". Apabila ini berlaku, "sandaran" yang paling dekat dalam pokok komponen akan diberikan. Kami akan melihat bagaimana untuk membuat kejatuhan tidak lama lagi (yang agak mudah), tetapi komponen itu memberitahu React bahawa ia belum siap lagi untuk membuang janji. React akan menangkap janji, menyedari bahawa komponen belum siap, dan menjadikan sandaran. Apabila Janji Parses, React akan cuba membuat rendering lagi. Ulangi proses ini. Ya, saya sedikit terlalu banyak, tetapi itulah titik bagaimana ketegangan berfungsi, dan kita akan mengembangkan beberapa konsep ini seperti yang kita pergi.
Bahagian kedua ketegangan adalah pengenalan kemas kini status "peralihan". Ini bermakna kita menetapkan keadaan, tetapi memberitahu React bahawa perubahan keadaan boleh menyebabkan komponen digantung, dan jika ini berlaku, sandaran tidak diberikan. Sebaliknya, kami mahu terus melihat skrin semasa sehingga kemas kini status sudah siap, di mana ia akan diberikan. Sudah tentu, React memberikan kita penunjuk "menunggu" Boolean yang membolehkan pemaju tahu bahawa proses ini sedang berjalan supaya kita dapat memberikan maklum balas beban sebaris.
Mari kita pramuat beberapa gambar!
Pertama, saya ingin menunjukkan bahawa terdapat demo penuh yang kita buat pada akhir artikel ini. Jika anda hanya mahu melompat ke dalam kod, jangan ragu untuk membuka demo sekarang. Ia akan menunjukkan bagaimana ketegangan digunakan bersempena dengan kemas kini keadaan peralihan kepada imej pramuat. Selebihnya jawatan ini akan membina kod langkah demi langkah dan menerangkan bagaimana dan mengapa di sepanjang jalan.
Ok, mari kita mulakan!
Kami mahu komponen kami digantung sehingga semua imej dimuatkan. Untuk memudahkan operasi sebanyak mungkin, mari buat a<suspenseimage></suspenseimage>
Komponen, yang menerima atribut SRC, preleloads imej, mengendalikan pengecualian melemparkan, dan kemudian membuat a <img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174358885649082.png" class="lazy" alt="Imej pra-caching dengan ketegangan reaksi">
Gunakan imej dalam HTML, tetapi kita juga boleh membuat imej dengan cara yang penting menggunakan objek Image()
dalam JavaScript; Di samping itu, imej yang kami buat dengan cara ini mempunyai panggilan balik yang onload
kebakaran apabila imej ... dimuatkan. Nampaknya ini:
const img = imej baru (); img.onload = () => { // imej dimuatkan};
Tetapi bagaimana kita menggabungkannya dengan pengecualian membuang? Sekiranya anda seperti saya, anda mungkin memikirkan sesuatu seperti ini:
const suspenseImg = ({src, ... rest}) => { Buangkan janji baru ((menyelesaikan) => { const img = imej baru (); img.onload = () => { menyelesaikan (); }; img.src = src; }); Kembali<img alt="" src="%7Bsrc%7D"> ; };
Masalahnya, tentu saja, ini akan selalu membuang janji. Setiap kali Reacts cuba untuk diberikan<suspenseimg></suspenseimg>
Apabila suatu contoh sedang berjalan, janji baru dicipta dan dibuang dengan segera. Sebaliknya, kami hanya mahu membuang janji sebelum beban imej. Terdapat kata -kata lama bahawa setiap masalah dalam sains komputer dapat diselesaikan dengan menambahkan lapisan indirection (kecuali masalah terlalu banyak lapisan indirection), jadi mari kita lakukan dan membina cache imej. Apabila kita membaca SRC, cache akan memeriksa sama ada ia telah memuatkan imej, dan jika tidak, ia akan memulakan pramuat dan membuang pengecualian. Dan, jika imej itu dimuatkan, ia hanya akan kembali benar dan biarkan React terus memberikan imej kita.
Inilah milik kita<suspenseimage></suspenseimage>
Seperti apa komponen:
Eksport constenseMg = ({src, ... rest}) => { imgcache.read (src); Kembali<img src="%7Bsrc%7D" alt="Imej pra-caching dengan ketegangan reaksi" > ; };
Berikut adalah versi minimum yang kita sapu seperti:
const imgcache = { __cache: {}, baca (src) { jika (! ini .__ cache [src]) { Ini .__ cache [src] = janji baru ((resolve) => { const img = imej baru (); img.onload = () => { Ini .__ cache [src] = true; menyelesaikan (cache .__ ini [src]); }; img.src = src; }); } jika (ini .__ cache [src] InstanceOf Promise) { Buang ini .__ cache [src]; } kembali ini .__ cache [src]; } };
Ia tidak sempurna, tetapi sudah cukup buat masa ini. Mari terus menggunakannya.
mencapai
Ingat, di bawah adalah pautan ke demo kerja penuh, jadi jangan putus asa jika saya bergerak terlalu cepat dalam langkah tertentu. Kami akan menerangkan semasa kami pergi.
Mari kita mulakan dengan mendefinisikan sandaran kita. Kami mentakrifkan sandaran dengan meletakkan tag ketegangan dalam pokok komponen dan lulus atribut sandaran kami. Mana -mana komponen yang belum selesai akan mencari tag ketegangan yang paling terkini dan menjadikan penolakannya (tetapi jika tag ketegangan tidak dijumpai, ralat akan dibuang). Permohonan sebenar mungkin mempunyai banyak tag ketegangan sepanjang proses, menentukan kejatuhan khusus untuk modul individu, tetapi untuk demonstrasi ini kita hanya memerlukan tag yang membungkus permohonan akar kami.
aplikasi fungsi () { Kembali ( <suspense fallback="{<Loading"></suspense> }> <showimages></showimages> ); }
<loading></loading>
Komponen adalah pemutar asas, tetapi dalam aplikasi sebenar anda mungkin ingin memberikan beberapa jenis shell kosong komponen yang anda sebenarnya cuba untuk memberikan pengalaman yang lebih lancar.
Dengan ini, kita<showimages></showimages>
Komponen akhirnya akan menjadikan imej kami menggunakan yang berikut:
<div> {image.map ((img) => ( <div key="{img}"> <suspenseimg alt="" src="%7Bimg%7D"></suspenseimg> </div> ))} </div>
Pada pemuatan awal, pemuatan pemuatan kami akan dipaparkan sehingga imej awal kami siap, di mana mereka akan dipaparkan secara serentak tanpa sebarang lag penyusunan semula interlaced.
Kemas kini status peralihan
Sebaik sahaja imej -imej itu ada, apabila kita memuatkan kumpulan imej seterusnya, kita mahu mereka muncul selepas memuatkan, tentu saja, mengekalkan imej sedia ada pada skrin ketika mereka memuat. Kami menggunakan cangkuk useTransition
untuk melakukan ini. Ini mengembalikan fungsi startTransition
dan isPending
yang menunjukkan bahawa kemas kini status kami sedang berjalan tetapi telah digantung (atau walaupun ia belum digantung, mungkin masih benar jika kemas kini status hanya mengambil masa yang lama). Akhirnya, apabila useTransition
dipanggil, anda perlu lulus nilai timeoutMs
, yang merupakan jumlah maksimum masa bendera isPending
boleh benar, selepas itu bertindak balas akan meninggalkan dan menjadikan sandaran (perhatikan bahawa parameter timeoutMs
boleh dipadamkan dalam masa terdekat, dan apabila kandungan yang ada dikemas kini, keadaan Peralihan Peralihan hanya perlu menunggu lama).
Inilah yang saya nampak:
const [startTransition, isPending] = useTransition ({timeOutms: 10000});
Kami akan membenarkan 10 saat berlalu sebelum paparan sandaran kami, yang mungkin terlalu lama dalam kehidupan sebenar, tetapi sesuai untuk demonstrasi ini, terutamanya jika anda sengaja melambatkan rangkaian di DevTools untuk percubaan.
Inilah cara menggunakannya. Apabila anda mengklik butang yang memuat lebih banyak imej, kod kelihatan seperti ini:
startTransition (() => { setPage ((p) => p 1); });
Kemas kini status ini akan mencetuskan beban data baru menggunakan REACT Micro-GraphQL Client GraphQL saya, yang serasi dengan ketegangan dan akan membuang janji untuk kami apabila pertanyaan sedang berjalan. Sebaik sahaja data dikembalikan, komponen kami akan cuba membuat dan menggantung semula apabila imej kami dimuatkan. Walaupun semua ini berlaku, nilai isPending
kami akan benar, yang akan membolehkan kami memaparkan pemutar pemuatan di bahagian atas kandungan yang ada.
Elakkan air terjun Internet
Anda mungkin tertanya -tanya bagaimana React boleh menyekat rendering semasa pramuat imej sedang berjalan. Menggunakan kod di atas, apabila kita melakukan ini:
{image.map ((img) => (
... dan apa yang diberikan di dalamnya<suspenseimage></suspenseimage>
, Akan bertindak balas cuba untuk menjadikan imej pertama, menggantung, dan kemudian mencuba semula senarai, melebihi imej pertama (sekarang dalam cache kami), dan kemudian gantung imej kedua, maka yang ketiga, ke -4, dan lain -lain. Jika anda telah membaca tentang ketegangan sebelum ini, anda mungkin tertanya -tanya jika kita perlu secara manual preload semua imej dalam senarai sebelum semua penulisan ini berlaku.
Ternyata tidak perlu risau atau melakukan pramuat yang janggal, kerana React cukup pandai tentang bagaimana ia membuat perkara -perkara di dunia yang ketegangan. Apabila React melintasi pokok komponen kami, ia tidak berhenti apabila ia menemui yang belum selesai. Sebaliknya, ia terus berusaha untuk menjadikan semua laluan lain dalam pokok komponen kami. Jadi ya, apabila ia cuba membuat Imej 0, hang akan berlaku, tetapi React akan terus cuba membuat imej 1 hingga N sebelum ia digantung.
Anda boleh melihatnya dengan melihat tab Rangkaian dalam demo penuh apabila set imej baru dimuatkan. Anda harus melihat keseluruhan baldi imej dengan segera dipaparkan dalam senarai rangkaian, menghuraikan satu demi satu, dan apabila selesai, hasilnya harus dipaparkan pada skrin. Untuk benar -benar menguatkan kesan ini, anda mungkin mahu mengurangkan kelajuan rangkaian anda kepada "Fast 3G".
Untuk bersenang -senang, kita boleh memaksa ketegangan untuk melintasi imej kita dengan membaca secara manual setiap imej dari cache kita sebelum React cuba untuk menjadikan komponen kita, melintasi setiap jalan di dalam pokok komponen.
image.foreach ((img) => imgcache.read (img));
Saya mencipta demo untuk menggambarkan ini. Jika anda juga melihat tab Rangkaian apabila memuatkan set imej baru, anda akan melihat bahawa ia ditambah ke senarai rangkaian dalam urutan (tetapi tidak menjalankan ini dengan melambatkan rangkaian).
Hang tertunda
Apabila menggunakan ketegangan, anda perlu ingat satu kesimpulan: gantung secepat mungkin dalam rendering dan tahap yang lebih rendah dari pokok komponen. Sekiranya anda mempunyai beberapa gambar yang digantung<imagelist></imagelist>
, pastikan setiap imej digantung dalam komponennya sendiri supaya React dapat mengaksesnya secara berasingan supaya tiada imej menghalang imej lain, mengakibatkan air terjun.
Versi pemuatan data peraturan ini adalah bahawa data harus dimuatkan sebanyak mungkin oleh komponen yang sebenarnya memerlukannya. Ini bermakna kita harus mengelakkan melakukan perkara berikut dalam komponen:
const {data1} = UseSusPenseQuery (query1, vars1); const {data2} = UseSusPenseQuery (query2, vars2);
Alasan yang kita ingin mengelakkan ini ialah pertanyaan yang akan digantung, dan kemudian pertanyaan dua, menyebabkan air terjun. Jika ini tidak dapat dielakkan sama sekali, kita perlu secara manual pramuat kedua -dua pertanyaan sebelum digantung.
Demo
Berikut adalah demonstrasi komitmen saya. Ia sama dengan demo yang saya sambungkan di atas.
Buka demo jika anda menjalankannya dan buka alat pembangunan, pastikan anda nyahtandakan kotak cache disable yang dipaparkan dalam tab Rangkaian Devtools atau anda akan memecahkan keseluruhan demo.
Kod ini hampir sama dengan yang saya tunjukkan sebelum ini. Satu peningkatan dalam demo ialah kaedah baca cache kami mempunyai baris berikut:
setTimeout (() => menyelesaikan ({}), 7000);
Pramuat semua imej dengan baik, tetapi dalam kehidupan sebenar kita mungkin tidak mahu menyekat rendering selama -lamanya hanya kerana satu atau dua di belakang imej memuat perlahan -lahan. Jadi selepas beberapa ketika, kami hanya memberikan cahaya hijau, walaupun imej itu tidak siap. Pengguna akan melihat imej atau dua berkelip, tetapi ini lebih baik daripada menahan kekecewaan perisian pembekuan. Saya juga ingin menunjukkan bahawa tujuh saat mungkin terlalu lama, tetapi untuk demo ini, saya menganggap bahawa pengguna boleh melambatkan rangkaian di DevTools untuk melihat fungsi ketegangan lebih jelas dan diharapkan dapat menyokong ini.
Demo ini juga mempunyai kotak semak imej precache. Ia dipilih secara lalai, tetapi anda boleh nyahtandahya untuk menggunakan normal<img alt="Imej pra-caching dengan ketegangan reaksi" >
Penggantian tag<suspenseimage></suspenseimage>
Komponen, jika anda ingin membandingkan versi ketegangan ke "React Normal" (hanya jangan periksa apabila hasilnya muncul, jika tidak, keseluruhan UI boleh menggantung dan menjadikan sandaran).
Akhirnya, seperti CodesandBox, sesetengah negeri kadang -kadang mungkin tidak disegerakkan, jadi jika perkara mula kelihatan pelik atau korup, klik butang Refresh.
Pelbagai
Saya secara tidak sengaja membuat kesilapan besar ketika meletakkan demo ini bersama -sama. Saya tidak mahu demo kehilangan kesannya kerana penyemak imbas itu telah dimuat turun. Oleh itu, saya mengubahsuai semua URL secara manual menggunakan pemutus cache:
const [cachebuster, setCachebuster] = useState (initial_time); const {data} = UseSusPenseQuery (get_images_query, {page}); const images = data.allbooks.books.map ( (b) => B.Smallimage `? CacheBust = $ {CacheBuster}` );
Initial_time ditakrifkan pada tahap modul (iaitu, di seluruh dunia):
const Initial_time = tarikh baru ();
Sekiranya anda tertanya -tanya mengapa saya tidak melakukan ini:
const [cachebuster, setCacheBuster] = useState (tarikh baru ());
... Ini kerana ia boleh membawa kesan yang dahsyat dan dahsyat. Pada rendering pertama , imej cuba untuk diberikan. Cache menyebabkan hang, bertindak balas membatalkan rendering dan memaparkan sandaran kami. Apabila semua janji telah dihuraikan, React akan cuba untuk membuat semula rendering dan panggilan UseState awal kami akan dijalankan semula , yang bermaksud:
const [cachebuster, setCacheBuster] = useState (tarikh baru ());
... akan dijadikan semula dengan nilai awal baru yang menghasilkan satu set baru URL imej, yang akan digantung selama -lamanya lagi. Komponen tidak akan berjalan, dan Demo Codesandbox akan berhenti berjalan (yang membuat debugging mengecewakan).
Ini seolah -olah menjadi isu khas yang aneh yang disebabkan oleh keperluan unik demonstrasi ini, tetapi terdapat pelajaran yang lebih besar: penyerahan harus murni dan tidak mempunyai kesan sampingan. React sepatutnya dapat cuba membuat semula komponen anda beberapa kali dan (diberi prop awal yang sama) harus mendapatkan keadaan tepat yang sama dari hujung yang lain.
Atas ialah kandungan terperinci Imej pra-caching dengan ketegangan reaksi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Sekiranya anda baru -baru ini mula bekerja dengan GraphQL, atau mengkaji semula kebaikan dan keburukannya, anda tidak akan ragu -ragu mendengar perkara seperti "Graphql tidak menyokong caching" atau

Dengan pendakian harga bitcoin baru -baru ini lebih dari 20k $ USD, dan baru -baru ini melanggar 30k, saya fikir ia patut mengambil menyelam yang mendalam kembali ke dalam mewujudkan Ethereum

Tidak kira tahap tahap anda sebagai pemaju, tugas yang kami selesaikan -sama ada besar atau kecil -membuat kesan besar dalam pertumbuhan peribadi dan profesional kami.

Ia ' s! Tahniah kepada pasukan Vue untuk menyelesaikannya, saya tahu ia adalah usaha besar dan lama datang. Semua dokumen baru juga.

Saya mempunyai seseorang yang menulis dengan soalan yang sangat legit ini. Lea hanya blog tentang bagaimana anda boleh mendapatkan sifat CSS yang sah dari penyemak imbas. That ' s seperti ini.

Pada hari yang lain, saya melihat sedikit ini sangat indah dari laman web Corey Ginnivan di mana koleksi kad timbunan di atas satu sama lain semasa anda menatal.

Terdapat beberapa aplikasi desktop ini di mana matlamat menunjukkan laman web anda pada dimensi yang berbeza pada masa yang sama. Oleh itu, anda boleh menulis
