Rumah > hujung hadapan web > tutorial js > Penghidratan Bertambah dalam Sudut Bawa Prestasi Apl Anda ke Tahap Seterusnya

Penghidratan Bertambah dalam Sudut Bawa Prestasi Apl Anda ke Tahap Seterusnya

Linda Hamilton
Lepaskan: 2024-11-04 08:14:31
asal
626 orang telah melayarinya

Incremental Hydration in Angular  Take Your App’s Performance to the Next Level

Dalam dunia pembangunan web yang pantas, prestasi dan pengalaman pengguna adalah penting untuk kejayaan mana-mana aplikasi. Dengan Angular 19, pasukan Angular memperkenalkan ciri revolusioner: Penghidratan Bertambah. Keupayaan baharu ini meningkatkan proses penghidratan sedia ada dan membolehkan pembangun mengoptimumkan pemuatan dan interaktiviti komponen dengan ketepatan. Artikel ini menyelidiki lebih mendalam tentang Penghidratan Tambahan, pelaksanaannya dan analisis terperinci tentang pencetus penghidratan untuk digunakan dalam pelbagai senario.

Memahami Penghidratan dalam Sudut

Penghidratan ialah proses mengaktifkan aplikasi yang diberikan bahagian pelayan pada bahagian klien. Ini memerlukan penggunaan semula elemen DOM yang diberikan pelayan, mengekalkan keadaan aplikasi dan memindahkan data yang telah diambil oleh pelayan. Pada asasnya, penghidratan menghapuskan keperluan untuk memaparkan semula DOM sepenuhnya, sekali gus meningkatkan metrik prestasi seperti Core Web Vitals (CWV).

Angular 19 memperkenalkan Incremental Hydration, yang melangkah lebih jauh dengan membenarkan pembangun menghidrat komponen secara selektif berdasarkan interaksi pengguna, keterlihatan atau keadaan tersuai. Ini membantu untuk memuatkan komponen yang diperlukan sahaja, meningkatkan masa muat awal dan prestasi keseluruhan aplikasi.

Selain itu, Angular's Incremental Hydration menggunakan acara ulang tayang untuk kandungan dalam blok hidrat untuk memastikan pengalaman pengguna yang lancar. Dengan memanfaatkan kefungsian withEventReplay, rangka kerja menangkap interaksi pengguna - seperti klik atau penekanan kekunci - yang berlaku sebelum proses penghidratan selesai. Setelah komponen terhidrat, peristiwa yang dirakam ini dimainkan semula dan pendengar peristiwa yang sepadan dilaksanakan, memastikan tiada interaksi pengguna hilang semasa peralihan dan aplikasi berasa responsif dan menarik sejak dari mula.

Mendayakan Penghidratan Bertambah

Sebelum menyelami pencetus penghidratan, mari pastikan kami telah bersedia untuk menggunakan Penghidratan Bertambah dalam aplikasi Sudut anda. Berikut adalah langkah-langkah yang perlu diikuti:

Prasyarat

  • Versi Angular: Pastikan aplikasi anda dikemas kini kepada versi Angular 19.0.0-rc.0 atau lebih baru.
  • Rendering Sisi Pelayan (SSR): SSR harus didayakan dalam aplikasi anda.
  • Penghidratan Didayakan: Dayakan penghidratan dalam persediaan Sudut anda.
  • Tangguhkan Blok: Gunakan @deferblocks untuk memanfaatkan Penghidratan Bertambah.

Mengemas kini Bootstrap Aplikasi Anda

Anda perlu mengimport Incremental Hydration ke dalam aplikasi anda dengan menambahkan withIncrementalHydration() pada import provideClientHydration() dalam tatasusunan penyedia:

import { provideClientHydration, withIncrementalHydration } from '@angular/platform-browser';

// Update bootstrap code
bootstrapApplication(AppComponent, {
providers: [provideClientHydration(withIncrementalHydration())]
});

Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Sintaks Penghidratan Bertambah

Fungsi penghidratan tambahan didayakan pada sekatan penangguhan bersama-sama dengan pencetus hidrat tambahan. Anda perlu menambah pencetus hidrat pada blok tangguh yang anda mahu gunakan penghidratan tambahan. Pencetus adalah sama seperti yang sedang digunakan (rujuk dokumentasi ini untuk maklumat lanjut), ditambah hidrat tambahan yang tidak pernah dicetuskan. Di bawah ialah senarai semua pencetus hidrat yang tersedia:

  1. segera
  2. terbiar
  3. pada pemasa
  4. di tuding
  5. pada interaksi
  6. pada port pandangan
  7. tidak pernah
  8. bila

Sintaks asas adalah sama dengan sintaks sedia ada untuk paparan tertunda, dengan penambahan pencetus khusus hidrat. Contohnya:

@defer (hydrate on interaction) {
  <my-deferred-cmp />
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Pencetus hidrat wujud bersama dengan pencetus penangguhan sedia ada dalam blok kod yang sama. Contohnya:

@defer (on idle; hydrate on interaction) {
  <my-deferred-cmp />
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Pengenalan pencetus penghidratan menandakan evolusi yang ketara dalam cara aplikasi mengurus pemaparan, terutamanya dalam konteks pemaparan sebelah pelayan (SSR) dan pemaparan sebelah pelanggan (CSR). Pencetus hidrat, seperti hidrat semasa interaksi, menyediakan mekanisme yang berbeza daripada pencetus penangguhan Sudut sedia ada seperti pada serta-merta.

Untuk menjelaskan fungsinya, pencetus penangguhan tradisional beroperasi semata-mata dalam konteks pemaparan sebelah pelanggan. Sebagai contoh, pencetus segera hanya diaktifkan apabila pengguna menavigasi ke komponen melalui penghalaan sisi klien, menunjukkan bahawa pemaparan serta-merta harus berlaku sebaik sahaja beban awal selesai.

Sebaliknya, pencetus hidrat mula bermain semasa pemaparan bahagian pelayan awal. Apabila komponen yang diberikan pelayan menggunakan kata kunci hidrat, ia menyediakan kandungan sebagai HTML statik, yang kekal tidak interaktif sehingga keadaan penghidratan tertentu dipenuhi atau pencetus penghidratan tertentu dijalankan. Ini bermakna semasa pemaparan bahagian pelayan awal, komponen muncul sebagai kandungan statik; bagaimanapun, sebaik sahaja syarat dipenuhi atau pencetus diaktifkan, penghidratan mengubahnya menjadi elemen interaktif sepenuhnya. Oleh kerana perbezaan fungsi ini, kita boleh menggambarkan pencetus penangguhan biasa dan pencetus hidrat sebagai saling eksklusif; hanya satu jenis pencetus boleh digunakan pada satu masa.

Keeksklusifan ini membolehkan pembangun mengurus dengan teliti apabila komponen dipaparkan dan dibuat interaktif, mengoptimumkan prestasi aplikasi. Tambahan pula, main semula acara berfungsi bersama-sama dengan pencetus hidrat untuk memastikan bahawa sebarang tindakan pengguna yang diambil semasa fasa statik dipelihara; interaksi ini akan ditangkap dan dimainkan semula selepas penghidratan.
Ia juga penting untuk memahami cara pencetus hidrat berinteraksi dengan @placeholder dan @loading:

Apabila menggunakan kata kunci hidrat, kandungan templat utama berfungsi sebagai pemegang tempat baharu semasa SSR. Sebaliknya, pemegang tempat tradisional dan templat pemuatan digunakan semasa senario CSR. Oleh itu, jika kata kunci hidrat tidak digunakan, tingkah laku menjadi lalai kepada pemaparan sebelah pelayan standard, di mana ruang letak yang ditentukan dipaparkan pada pelayan dan dihidratkan dengan penuh semangat sebagai sebahagian daripada proses pemuatan aplikasi yang lengkap. Perbezaan bernuansa ini memperkasakan pembangun untuk mengoptimumkan pengalaman pemuatan awal dan interaksi pengguna seterusnya dengan lancar.

Pelbagai Pencetus Hidrat

Sama seperti pencetus tangguh dan pencetus prefetch, anda boleh menggunakan berbilang pencetus hidrat secara serentak, membolehkan penghidratan berlaku apabila mana-mana pencetus tersebut diaktifkan. Contohnya:

import { provideClientHydration, withIncrementalHydration } from '@angular/platform-browser';

// Update bootstrap code
bootstrapApplication(AppComponent, {
providers: [provideClientHydration(withIncrementalHydration())]
});

Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Satu perkara penting untuk diberi perhatian tentang pencetus bila ialah anda tidak boleh mempunyai berbilang hidrat apabila pencetus dalam blok @defer yang sama. Sebaliknya, anda mesti menggabungkan syarat; jika tidak, ia akan membuang ralat. Sebagai contoh, kod di bawah akan menghasilkan ralat yang menunjukkan bahawa berbilang apabila blok tidak dibenarkan:

@defer (hydrate on interaction) {
  <my-deferred-cmp />
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Sebaliknya, kod di bawah akan berfungsi dengan betul:

@defer (on idle; hydrate on interaction) {
  <my-deferred-cmp />
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Pencetus Penghidratan Diterangkan

Pencetus penghidratan menentukan bila blok tertunda harus menjadi interaktif. Mari terokai setiap pencetus secara terperinci, bersama-sama dengan senario yang sesuai untuk penggunaannya.

Hydrate on Immediate: Pencetus ini memulakan penghidratan serta-merta selepas pelanggan selesai membuat komponen. Contohnya:

@defer(hydrate on interaction; hydrate when isLoggedIn()){
<li>
  <a [routerLink]="[isLoggedIn()?'/account':'/signup']">Account</a>
</li>
}
Salin selepas log masuk
Salin selepas log masuk

Contoh Kes Penggunaan: Gunakan pencetus ini untuk komponen penting yang memerlukan interaksi pengguna pantas dengan segera, seperti menu navigasi atau butang seruan tindak utama.

Hydrate on Idle: Pencetus ini memulakan penghidratan apabila penyemak imbas memasuki keadaan melahu (lihat requestIdleCallback), bermakna tiada interaksi pengguna atau tugas yang dijadualkan.

@defer(hydrate when firstCondition; hydrate when secondCondition){
<my-component />
}
Salin selepas log masuk
Salin selepas log masuk

Contoh Kes Penggunaan: Sesuai untuk elemen UI tidak kritikal yang boleh menunggu beberapa saat, seperti kad maklumat tambahan yang menyediakan konteks tanpa menghalang interaksi utama.

Hidrat pada Pemasa: Pencetus ini mengaktifkan penghidratan selepas tempoh tertentu, yang wajib dan boleh ditakrifkan sama ada dalam milisaat (ms) atau saat (s).

@defer(hydrate when (firstCondition || secondCondition)){
<my-component />
}
Salin selepas log masuk

Contoh Kes Penggunaan: Sesuai untuk komponen yang tidak sepatutnya muncul serta-merta tetapi selepas tempoh yang singkat, seperti pemberitahuan pop timbul atau tutorial yang membimbing pengguna melalui antara muka.

Hidrat pada Tuding: Pencetus ini memulakan penghidratan apabila pengguna melayang di atas komponen yang berkaitan, menggunakan masuk tetikus dan memfokuskan peristiwa.

import { provideClientHydration, withIncrementalHydration } from '@angular/platform-browser';

// Update bootstrap code
bootstrapApplication(AppComponent, {
providers: [provideClientHydration(withIncrementalHydration())]
});

Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Contoh Kes Penggunaan: Gunakan ini untuk ciri seperti petua alat atau menu butiran yang meningkatkan pemahaman pengguna tanpa mengacaukan antara muka.
Hydrate on Interaction: Pencetus ini mengaktifkan penghidratan berdasarkan peristiwa terdorong pengguna, seperti peristiwa klik atau keydown.

@defer (hydrate on interaction) {
  <my-deferred-cmp />
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Contoh Kes Penggunaan: Sesuai untuk komponen yang memerlukan penglibatan pengguna sejurus sebelum interaktiviti, seperti borang, galeri produk atau butang yang mendedahkan lebih banyak maklumat apabila diklik.

Hidrat pada Viewport: Pencetus ini menghidratkan komponen apabila ia memasuki port pandangan pengguna seperti yang ditentukan oleh Intersection Observer API.

@defer (on idle; hydrate on interaction) {
  <my-deferred-cmp />
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Contoh Kes Penggunaan: Gunakan ini untuk kandungan lipatan bawah yang tidak sepatutnya menjadi interaktif sehingga pengguna menatal ke bawah. Pendekatan ini meningkatkan masa pemuatan halaman sambil mengekalkan penglibatan pengguna, menjadikannya sesuai untuk kandungan seperti imej, artikel atau penyenaraian produk tambahan.

Jangan Sekali-kali Hidrat: Pencetus ini menandakan blok yang akan kekal statik, menandakan ia tidak boleh terhidrat.

@defer(hydrate on interaction; hydrate when isLoggedIn()){
<li>
  <a [routerLink]="[isLoggedIn()?'/account':'/signup']">Account</a>
</li>
}
Salin selepas log masuk
Salin selepas log masuk

Contoh Kes Penggunaan: Sesuai untuk unsur statik yang tidak memerlukan interaksi, seperti pengaki, maklumat hak cipta atau penafian undang-undang. Bahagian ini tidak perlu menanggung overhed penghidratan dan boleh dijadikan HTML mudah.

Menggabungkan CSR Defer dan HydrationTriggers

Dalam banyak kes, menggabungkan pencetus boleh menghasilkan lebih fleksibiliti dan prestasi:

@defer(hydrate when firstCondition; hydrate when secondCondition){
<my-component />
}
Salin selepas log masuk
Salin selepas log masuk

Dalam kes ini, kami menyatakan bahawa untuk pemaparan sisi klien (CSR), komponen harus terhidrat apabila pengguna menatal ke bawah (masuk ke port pandangan). Sebaliknya, untuk pemaparan sebelah pelayan (SSR), ia menghidratkan apabila interaksi pengguna, menjadikan proses ini cekap dan responsif kepada tindakan pengguna.

Memahami Penghidratan Bersarang dalam Penghidratan Bertambah

Dengan pengenalan Penghidratan Bertambah dalam Sudut 19, konsep penghidratan bersarang menjadi aspek penting untuk difahami. Apabila berurusan dengan berbilang blok @defer bersarang, interaksi antara keadaan penghidratannya boleh meningkatkan prestasi dan pengurusan sumber dengan ketara. Peraturan yang mengawal tingkah laku blok bersarang ini menawarkan tahap kawalan yang lebih mendalam ke atas perkara yang diberikan dan bila, akhirnya memberi kesan kepada prestasi keseluruhan aplikasi anda.

Penilaian Keadaan Serentak

Apabila berbilang blok @defer bersarang antara satu sama lain dalam keadaan dehidrasi, keadaan penghidratannya dinilai secara serentak. Sebagai contoh, pertimbangkan struktur berikut:

import { provideClientHydration, withIncrementalHydration } from '@angular/platform-browser';

// Update bootstrap code
bootstrapApplication(AppComponent, {
providers: [provideClientHydration(withIncrementalHydration())]
});

Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, blok luar ditetapkan untuk menghidrat apabila pengguna menuding pada sebarang kandungan di dalamnya. Walau bagaimanapun, walaupun blok luar tidak pernah berlegar, blok dalam masih akan mencetuskan penghidratan selepas tempoh 15 saat yang ditetapkan. Penilaian keadaan serentak ini membolehkan lebih fleksibiliti dalam cara komponen menjadi interaktif, terutamanya dalam antara muka pengguna yang masa interaksi boleh berbeza-beza dengan ketara.

Pengecualian untuk hidrat apabila

Walaupun kebanyakan pencetus hidrat berfungsi dengan betul dalam struktur bersarang, terdapat pengecualian ketara untuk hidrat apabila pencetus. Pencetus bila adalah berasaskan keadaan dan bergantung sepenuhnya pada logik yang ditakrifkan dalam komponen yang mengandunginya. Khususnya, ini bermakna apabila hanya boleh menilai logiknya jika induk terdekat atau blok yang mengandungi sudah terhidrat. Contohnya:

@defer (hydrate on interaction) {
  <my-deferred-cmp />
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam senario ini, jika blok luar (dengan hidrat pada tuding) tidak mencetuskan penghidratan apabila peristiwa tuding tetikus, blok dalam (yang menyemak sama ada objek pengguna bukan nol) tidak akan sekali-kali terhidrat. Sebab bagi tingkah laku ini adalah jelas: ungkapan untuk menilai bila tidak dapat dilaksanakan melainkan komponen induk telah diproses dan logiknya boleh diakses. Oleh itu, jika blok luar kekal dehidrasi, logik yang diperlukan untuk menilai blok dalam belum wujud lagi.

Proses Penghidratan Hierarki

Apabila penghidratan dicetuskan untuk blok bersarang, Angular mengikuti proses melata - mana-mana blok induk mesti dihidratkan terlebih dahulu sebelum komponen anak boleh diambil tindakan. Tindakan melata ini penting kerana ia membenarkan kebergantungan komponen bersarang dimuatkan dalam susunan yang betul. Proses penghidratan berfungsi dengan berkesan seperti air terjun, di mana setiap langkah bergantung pada langkah sebelumnya yang sedang diproses sepenuhnya. Akibatnya, blok dehidrasi bersarang memerlukan pendekatan berhati-hati untuk memuatkan kod yang diperlukan untuk semua peringkat sebelum mana-mana daripadanya boleh beroperasi.

Interaksi Terkenal

Apabila menggunakan pencetus campuran dalam struktur bersarang, adalah penting untuk mengingati sifat pencetus yang terlibat. Contohnya, jika anda mahu komponen tertentu terhidrat sambil memastikan komponen lain kekal statik (tidak terhidrat), anda boleh menggunakan struktur berikut secara strategik:

@defer (on idle; hydrate on interaction) {
  <my-deferred-cmp />
}
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam kes ini, blok luar akan terhidrat apabila dilayangkan, manakala blok dalam yang mengandungi unit iklan akan kekal tidak terhidrat, mengekalkan sifat statiknya. Pemisahan ini mungkin kerana pencetus berasaskan peristiwa, seperti hidrat pada tuding, tidak bergantung pada logik komponen untuk diaktifkan dan dengan itu boleh beroperasi secara bebas daripada logik yang terkandung dalam bersarang pada @deferblocks.

Memahami penghidratan bersarang adalah penting untuk memanfaatkan Penghidratan Tambahan dalam Sudut 19 dengan berkesan. Dengan menstrukturkan @deferblocks bersarang dengan teliti dan memilih pencetus penghidratan yang sesuai, pembangun boleh mengoptimumkan prestasi aplikasi sambil mengekalkan tindak balas. Keupayaan untuk mengurus masa dan cara komponen menjadi interaktif ialah ciri berkuasa yang, apabila digabungkan dengan peraturan yang mengawal penghidratan bersarang, boleh membawa kepada pengalaman pengguna dan pengurusan sumber yang dipertingkatkan secara dramatik dalam aplikasi Angular moden.

Senario Biasa untuk Menggunakan Penghidratan Bertambah

Malas Memuatkan Item Produk
Dalam platform e-dagang, apabila memaparkan senarai item produk pada halaman kategori, adalah tidak pasti sama ada pengguna akan berinteraksi dengan setiap produk. Dengan meletakkan produk ini dalam blok @defer menggunakan sintaks hidrat, komponen akan dipaparkan sebagai kandungan statik, tetapi JavaScript yang berkaitan hanya akan diambil dan dihidratkan apabila pengguna berinteraksi dengan produk tertentu. Pendekatan ini mengurangkan saiz berkas awal, mengoptimumkan prestasi sambil menyediakan butiran produk apabila diperlukan.

Menyajikan Kandungan Blog Statik
Untuk platform blog yang menampilkan artikel statik terutamanya, memanfaatkan hidrat tidak pernah syarat untuk komponen siaran membolehkan anda mengelak menghantar sebarang JavaScript yang berkaitan. Ini menghasilkan masa muat yang lebih ringan, kerana pengguna boleh mengakses artikel tanpa menanggung overhed sumber yang biasanya dikaitkan dengan interaktiviti.

Mengoptimumkan Komponen Berat Di Atas Lipatan
Apabila anda mempunyai komponen besar, seperti pengepala atau karusel, yang muncul di atas halaman tetapi menunjukkan interaksi pengguna yang minimum berdasarkan data peta haba, membalutnya dalam blok @defer dengan pencetus penghidratan boleh memberi manfaat. Strategi ini membolehkan komponen ini dipaparkan pada mulanya, manakala tingkah laku interaktif dan sumber yang berkaitan hanya dimuatkan apabila interaksi pengguna, memastikan pemindahan data yang cekap dan meningkatkan pengalaman pengguna.

Meningkatkan Interaksi Pengguna dengan Borang
Untuk borang input yang memerlukan tindak balas segera terhadap tindakan pengguna, menggunakan hidrat pada pencetus interaksi adalah sesuai. Ini menjamin bahawa komponen borang diaktifkan sebaik sahaja pengguna mula berinteraksi dengannya, sekali gus meningkatkan kebolehgunaan aplikasi.

Memuatkan Kandungan Dinamik atau Bawah Lipatan
Untuk paparan data dinamik atau bahagian berat kandungan yang hanya menjadi relevan apabila pengguna menatal, menggunakan hidrat pada pencetus viewport ialah pendekatan yang berharga. Ini terpakai bukan sahaja pada paparan produk tetapi juga pada imej atau kandungan tambahan, memberikan pengalaman pengguna yang lancar tanpa menjejaskan masa pemuatan awal.

Interaktiviti dengan Elemen Animasi
Untuk elemen interaktif yang meningkatkan penglibatan pengguna tetapi tidak penting untuk interaksi utama, seperti petua alat atau lungsur turun, menggunakan hidrat pada pencetus tuding adalah disyorkan. Ini memastikan bahawa elemen ini hanya diaktifkan apabila pengguna menuding di atasnya, memastikan beban awal ringan sambil masih menawarkan pilihan tambahan apabila diperlukan.

Kesimpulan

Penghidratan Inkremental dalam Angular 19 menandakan kemajuan yang ketara dalam mengoptimumkan aplikasi untuk prestasi dan pengalaman pengguna. Dengan menggunakan pencetus penghidratan secara strategik, pembangun boleh mengawal dengan tepat komponen mana yang harus menjadi interaktif dan bila ini sepatutnya berlaku. Pendekatan berbutir ini bukan sahaja meningkatkan kecekapan tetapi juga meningkatkan kepuasan pengguna dengan memastikan antara muka yang lancar.

Dengan menguasai selok-belok setiap pencetus penghidratan, anda boleh meningkatkan aplikasi Sudut anda, menjadikannya responsif, cekap dan bersedia untuk penglibatan pengguna. Semasa anda meneroka konsep ini, ingat keperluan pangkalan pengguna anda dan kandungan khusus yang anda bentangkan untuk membuat keputusan termaklum tentang masa dan cara untuk menghidratkan pelbagai elemen aplikasi anda. Selamat membangun!

Atas ialah kandungan terperinci Penghidratan Bertambah dalam Sudut Bawa Prestasi Apl Anda ke Tahap Seterusnya. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan