Melihat Kecepatan React Front-End mu Dengan Lazy Loading



Tantangan dari Front-End developers adalah performa aplikasi. Bagaimana kita dapat menyampaikan sebuah kekuatan dan fitur lengkap aplikasi kepada user tanpa harus memaksa mereka menunggu loading halaman Teknik yang digunakan untuk meningkatkan kecepatan website sangat banyak sekali dan itu dapat membuat bingung dimana cara yang paling tepat untuk mengoptimisasi performa dan kecepatan.

Untungnya, Solusinya tidak terlalu rumit seperti yang terlihat. Di postingan kali ini saya akan menjelaskan salah satu cara efektif yang dipakai oleh aplikasi web berskala besar untuk melihat kecepatan dan pengalaman pengguna. Saya akan memeriksa 1 paket fasilitas dan memastikan kita dapat mengirimkan aplikasi kita kepada user dengan cepat tanpa harus mereka memperhatikan sesuatu yang telah berubah.


Baca Juga : Berkenalan Dengan React Framework


Apa artinya sebuah website menjadi Cepat?


Pertanyaan tentang performa web sangat dalam dan luas. Demi untuk pos ini saya akan mencoba mendefinisikan performa secara bahasa sederhana: kirimkan sesedikit mungkin secepat yang Anda bisa. Tentunya, ini mungkin sangat menyederhanakan masalah, tetapi secara praktis, kita dapat mencapai peningkatan kecepatan yang dramatis dengan hanya mengirim lebih sedikit data bagi pengguna untuk mengunduh dan mengirim data dengan cepat.

Untuk tujuan posting ini, saya akan fokus pada bagian pertama dari definisi ini mengirimkan jumlah informasi yang paling sedikit ke peramban pengguna.

Selalu, masalah terbesar yang selalu datang ketika ada pertanyaan soal "Apa yang memperlambat aplikasi kita ..?" Jawabannya adalah gambar dan JavaScript. Dalam posting ini saya akan menunjukkan kepada Anda bagaimana menangani masalah kumpulan aplikasi besar dan mempercepat situs web kita dalam prosesnya.


React Loadable


React Loadable adalah paket yang memungkinkan kita untuk memuat JavaScript kita hanya ketika diperlukan oleh aplikasi. Tentu saja, tidak semua situs web menggunakan react, tetapi demi keringkasan saya akan fokus pada penerapan React Loadable di sisi server yang menggunakan webpack. Hasil akhirnya adalah beberapa file JavaScript yang dikirimkan ke browser pengguna secara otomatis ketika kode itu diperlukan.


Baca Juga : 3 Alasan Untuk Memilih AngularJS Untuk Project Anda Selanjutnya 

Menggunakan definisi kita dari sebelumnya, yang artinya kita mengirim lebih sedikit ke pengguna di muka sehingga data dapat diunduh lebih cepat dan pengguna kita akan merasakan situs yang lebih berkinerja.



1. Tambahkan React Loadable ke Komponen Anda


Saya akan mengambil contoh komponen React, MyComponent. Saya berasumsi komponen ini terdiri dari dua file, MyComponent / MyComponent.jsx dan MyComponent / index.js.

Dalam dua file ini saya mendefinisikan komponen React persis seperti yang biasanya saya lakukan di MyComponent.jsx. Di index.js, saya mengimpor komponen react dan mengekspornya kembali, kali ini dibungkus dalam fungsi Loadable. 

Dengan menggunakan fitur impor ECMAScript, saya dapat menunjukkan kepada Webpack bahwa saya berharap file ini dimuat secara dinamis. Pola ini memungkinkan saya untuk dengan mudah memuat komponen apa pun yang sudah saya tulis. Ini juga memungkinkan saya untuk memisahkan logika antara pemuatan-lambat dan rendering. Mungkin terdengar rumit, tetapi inilah yang akan kita praktekan:

1:  // MyComponent/MyComponent.jsx  
2:  export default () => (  
3:   <div>  
4:    This component will be lazy-loaded!  
5:   </div>  
6:  )  


1:  // MyComponent/index.js  
2:  import Loadable from 'react-loadable'  
3:  export default Loadable({  
4:   // The import below tells webpack to   
5:   // separate this code into another bundle  
6:   loader: import('./MyComponent')  
7:  })  

Saya kemudian dapat mengimpor komponen saya persis seperti biasanya:

1:  // anotherComponent/index.js  
2:  import MyComponent from './MyComponent'  
3:  export default () => <MyComponent />  

Saya telah memperkenalkan React Loadable ke MyComponent. Saya dapat menambahkan lebih banyak logika ke komponen ini nanti jika saya memilih ini mungkin termasuk memperkenalkan paket pemuatan atau pengendali kesalahan ke komponen. Berkat Webpack, ketika kita menjalankan build kita, saya sekarang akan diberikan dengan dua paket JavaScript terpisah: app.min.js adalah bundel aplikasi reguler kita dan myComponent.min.js berisi kode yang baru saja kita tulis. Saya akan membahas cara mengirimkan bundel ini ke browser sebentar lagi.


Sederhanakan pengaturan dengan Babel


Biasanya, saya harus menyertakan dua opsi tambahan saat mengirimkan objek ke fungsi Loadable, modul dan webpack. Ini membantu Webpack mengidentifikasi modul mana yang harus kita masukkan. Untungnya, kita dapat meniadakan kebutuhan untuk memasukkan dua opsi ini dengan setiap komponen dengan menggunakan plugin react-loadable / babel. Ini secara otomatis menyertakan opsi-opsi ini untuk kita:

1:  // input file  
2:  import Loadable from 'react-loadable'  
3:  export default Loadable({  
4:   loader: () => import('./MyComponent')  
5:  })  


1:  // output file   
2:  import Loadable from 'react-loadable'  
3:  import path from 'path'  
4:  export default Loadable({  
5:   loader: () => import('./MyComponent'),  
6:   webpack: () => [require.resolveWeak('./MyComponent')],  
7:   modules: [path.join(__dirname, './MyComponent')]  
8:  })  

Saya dapat menyertakan plugin ini dengan menambahkannya ke daftar plugin saya di file .babelrc saya, seperti:

1:  {  
2:   "plugins": ["react-loadable/babel"]  
3:  }  

Saya sekarang selangkah lebih dekat untuk lazy loading komponen kita. Namun, dalam kasus saya, saya berurusan dengan rendering sisi server. Saat ini, server tidak akan dapat membuat komponen kita yang bermuatan-lambat.

Baca Juga : 8 Golden Rules Untuk Interface Design

3. Rendering Components pada Server


Di aplikasi server saya, saya memiliki konfigurasi standar yang terlihat seperti ini:

1:  // server/index.js  
2:  app.get('/', (req, res) => {  
3:   const markup = ReactDOMServer.renderToString(  
4:    <MyApp/>  
5:   )  
6:   res.send(`  
7:    <html>  
8:     <body>  
9:      <div id="root">${markup}</div>  
10:      <script src="/build/app.min.js"></script>  
11:     </body>  
12:    </html>  
13:   `)  
14:  })  
15:  app.listen(8080, () => {  
16:   console.log('Running...')  
17:  })  

Langkah pertama adalah menginstruksikan React Loadable yang saya inginkan agar semua modul di-preload. Ini memungkinkan saya untuk memutuskan mana yang harus dimuat langsung pada klien. Saya melakukan ini dengan memodifikasi file server / index.js saya seperti ini:

1:  // server/index.js   
2:  Loadable.preloadAll().then(() => {  
3:   app.listen(8080, () => {  
4:    console.log('Running...')  
5:   })  
6:  })  

Langkah selanjutnya adalah mendorong semua komponen yang ingin saya render menjadi array sehingga nantinya kita dapat menentukan komponen mana yang memerlukan pemuatan segera. Ini agar HTML dapat dikembalikan dengan bundel JavaScript yang benar termasuk melalui tag skrip (lebih lanjut tentang ini saya jelaskan nanti). Untuk saat ini, saya akan memodifikasi file server saya seperti ini:

1:  / server/index.js  
2:  import Loadable from 'react-loadable'  
3:  app.get('/', (req, res) => {  
4:   const modules = []  
5:   const markup = ReactDOMServer.renderToString(  
6:    <Loadable.Capture report={moduleName => modules.push(moduleName)}>  
7:     <MyApp/>  
8:    </Loadable>  
9:   )  
10:   res.send(`  
11:    <html>  
12:     <body>  
13:      <div id="root">${markup}</div>  
14:      <script src="/build/app.min.js"></script>  
15:     </body>  
16:    </html>  
17:   `)  
18:  })  
19:  Loadable.preloadAll().then(() => {  
20:   app.listen(8080, () => {  
21:    console.log('Running...')  
22:   })  
23:  })  

Setiap kali komponen digunakan yang membutuhkan React Loadable, komponen itu akan ditambahkan ke array modules. Ini adalah proses otomatis yang dilakukan oleh React Loadable, jadi ini semua yang diperlukan pada bagian kita untuk proses ini.

Sekarang kita memiliki daftar modul yang kita tahu perlu segera diberikan. Masalah yang sekarang kita hadapi adalah memetakan modul-modul ini ke bundel yang telah diproduksi secara otomatis oleh Webpack.

4. Memetakan Paket Webpack ke Modul


Jadi sekarang saya telah menginstruksikan Webpack untuk membuat myComponent.min.js dan saya tahu bahwa MyComponent sedang digunakan dengan segera, jadi saya perlu memuat bundel ini dalam payload HTML awal yang kita berikan kepada pengguna. Untungnya, React Loadable menyediakan cara bagi kita untuk mencapai ini juga. Di file konfigurasi Webpack klien saya, saya perlu menyertakan plugin baru:

1:  // webpack.client.config.js  
2:  import { ReactLoadablePlugin } from 'react-loadable/webpack'  
3:  plugins: [  
4:   new ReactLoadablePlugin({  
5:    filename: './build/loadable-manifest.json'  
6:   })  
7:  ]  

File loadable-manifest.json akan memberikan saya pemetaan antara modul dan bundel sehingga saya dapat menggunakan modules array yang saya atur sebelumnya untuk memuat bundel yang saya tahu dan yang saya perlukan. Dalam kasus saya file ini mungkin terlihat seperti ini:

1:  // build/loadable-manifest.json  
2:  {  
3:   "MyComponent": "/build/myComponent.min.js"  
4:  }  

Ini juga akan membutuhkan file manifes Webpack umum untuk menyertakan pemetaan antara modul dan file untuk keperluan Webpack internal. Saya bisa melakukan ini dengan memasukkan plugin Webpack lain:

1:   new webpack.optimize.CommonsChunkPlugin({  
2:    name: 'manifest',  
3:    minChunks: Infinity  
4:   })  
5:  ]  

5. Menyertakan bundle kedalam HTML mu


Langkah terakhir dalam memuat bundel dinamis kita di server adalah memasukkannya ke dalam HTML yang kita berikan kepada pengguna. Untuk langkah ini saya akan menggabungkan keluaran langkah 3 dan 4. Saya bisa mulai dengan memodifikasi file server yang saya buat di atas:

1:  // server/index.js  
2:  import Loadable from 'react-loadable'  
3:  import { getBundles } from 'react-loadable/webpack'  
4:  import manifest from './build/loadable-manifest.json'  
5:  app.get('/', (req, res) => {  
6:   const modules = []  
7:   const markup = ReactDOMServer.renderToString(  
8:    <Loadable.Capture report={moduleName => modules.push(moduleName)}>  
9:     <MyApp/>  
10:    </Loadable>  
11:   )  
12:   const bundles = getBundles(manifest, modules)  
13:   // My rendering logic below ...  
14:  })  
15:  Loadable.preloadAll().then(() => {  
16:   app.listen(8080, () => {  
17:    console.log('Running...')  
18:   })  
19:  })  

Dalam hal ini saya telah mengimpor manifes dan meminta React Loadable untuk membuat array dengan pemetaan modul / bundel. Satu-satunya hal yang tersisa untuk saya lakukan adalah membuat bundel ini menjadi string HTML:

1:  / server/index.js  
2:  app.get('/', (req, res) => {  
3:   // My App & modules logic  
4:   res.send(`  
5:    <html>  
6:     <body>  
7:      <div id="root">${markup}</div>  
8:      <script src="/build/manifest.min.js"></script>  
9:      ${bundles.map(({ file }) =>  
10:       `<script src="/build/${file}"></script>`  
11:      }).join('\n')}  
12:      <script src="/build/app.min.js"></script>  
13:     </body>  
14:    </html>  
15:   `)  
16:  })  
17:  Loadable.preloadAll().then(() => {  
18:   app.listen(8080, () => {  
19:    console.log('Running...')  
20:   })  
21:  })  

6. Muat Kumpulan Server-Rendered pada Klien


Langkah terakhir untuk menggunakan bundel yang telah kita muat di server adalah dengan mengirimnya pada klien. Melakukan hal ini sangat ederhana, Saya dapat menginstruksikan React Loadable untuk melakukan pramuat modul apa pun yang ditemukan akan segera tersedia:

Baca Juga : Scrolling Vertical dan Horizontal Dengan Fullpage.js

1:  // client/index.js  
2:  import React from 'react'  
3:  import { hydrate } from 'react-dom'  
4:  import Loadable from 'react-loadable'  
5:  import MyApplication from './MyApplication'  
6:  Loadable.preloadReady().then(() => {  
7:   hydrate(  
8:    <MyApplication />,  
9:    document.getElementById('root')  
10:   );  
11:  });  

Kesimpulan


Setelah proses ini, saya dapat membagi bundel aplikasi saya ke dalam banyak bundel yang lebih kecil yang saya butuhkan. Dengan cara ini, aplikasi saya mengirimkan lebih sedikit kepada pengguna dan hanya ketika mereka membutuhkannya. Saya telah mengurangi jumlah kode yang perlu dikirim sehingga dapat dikirim lebih cepat. Ini dapat memiliki peningkatan kinerja yang signifikan untuk aplikasi yang lebih besar. Ini juga dapat mengatur aplikasi yang lebih kecil untuk pertumbuhan yang cepat jika diperlukan.

Oke menurut saya itu saja untuk tutorial kali ini, samapai jumpa di potingan selanjutnya :).