Penyajian sisi server ReactJS vs perenderan sisi klien

120

Saya baru saja mulai mempelajari ReactJS dan menemukan bahwa ini memberi Anda 2 cara untuk membuat halaman: sisi server dan sisi klien. Tapi, saya tidak bisa mengerti bagaimana menggunakannya bersama. Apakah ini 2 cara terpisah untuk membangun aplikasi, atau dapatkah keduanya digunakan bersama?

Jika kita dapat menggunakannya bersama, bagaimana melakukannya - apakah kita perlu menduplikasi elemen yang sama di sisi server dan sisi klien? Atau, bisakah kita membangun bagian statis aplikasi kita di server, dan bagian dinamis di sisi klien, tanpa koneksi ke sisi server yang sudah di-render?

Simcha
sumber
1
Jawaban singkatnya, TIDAK - Anda dapat memisahkan, mengirim html statis, dan mengubahnya sepenuhnya dalam render klien. Telah menambahkan detail dalam jawaban saya.
Kira

Jawaban:

108

Untuk situs web / aplikasi web tertentu, Anda dapat menggunakan react baik sisi klien , sisi server atau keduanya .

Sisi klien

Di sini, Anda menjalankan ReactJS sepenuhnya di browser. Ini adalah pengaturan yang paling sederhana dan mencakup sebagian besar contoh (termasuk yang ada di http://reactjs.org ). HTML awal yang dirender oleh server adalah placeholder dan seluruh UI dirender di browser setelah semua skrip Anda dimuat.

Sisi server

Pikirkan ReactJS sebagai mesin template sisi server di sini (seperti giok, setang, dll ...). HTML yang dirender oleh server berisi UI sebagaimana mestinya dan Anda tidak menunggu skrip apa pun dimuat. Halaman Anda dapat diindeks oleh mesin pencari (jika tidak ada javascript yang dijalankan).

Karena UI dirender di server, tidak ada penangan peristiwa Anda yang akan berfungsi dan tidak ada interaktivitas (Anda memiliki halaman statis).

Kedua

Di sini, render awal ada di server. Karenanya, HTML yang diterima browser memiliki UI sebagaimana mestinya. Setelah skrip dimuat, DOM virtual dirender ulang sekali lagi untuk menyiapkan penangan kejadian komponen Anda.

Di sini, Anda perlu memastikan bahwa Anda merender ulang DOM virtual yang sama persis (root komponen ReactJS) dengan yang sama propsyang Anda gunakan untuk merender di server. Jika tidak, ReactJS akan mengeluh bahwa DOM virtual sisi server dan sisi klien tidak cocok.

Karena ReactJS membedakan DOM virtual antar render ulang, DOM asli tidak bermutasi. Hanya event handler yang terikat ke elemen DOM asli.

Gautham Badhrinathan
sumber
1
Jadi dalam kasus "keduanya", saya perlu menulis kode yang sama dua kali "satu untuk rendering server, dan satu lagi untuk mereproduksi DOM ini pada klien? Benar?
Simcha
10
Anda perlu menjalankan kode yang sama dua kali. Sekali di server dan sekali di klien. Namun, Anda perlu menulis komponen Anda untuk memperhitungkannya - misalnya, Anda tidak boleh melakukan pengambilan data asinkron componentWillMount(), karena ini akan menjalankan klien dan server. Anda juga memerlukan strategi untuk mengambil data di depan pada server dan membuatnya tersedia untuk perenderan awal pada klien, untuk memastikan Anda mendapatkan keluaran yang sama.
Jonny Buchanan
3
Anda juga dapat memeriksa apakah kode yang dieksekusi berada di sisi server atau sisi klien menggunakan typeof window == "undefined"dan kemudian mengambil data Anda yang sesuai.
Gautham Badhrinathan
Apakah Anda memiliki tautan ke contoh yang sesuai dengan penerapan Anda?
Sawtaytoes
1
@IanW Biasanya dalam hal ini HTML yang dikembalikan oleh server sangat "tanpa tulang", cukup mengimpor JavaScript dan gaya Anda dan berisi <div>React yang akan menuliskannya.
Matt Holland
48

Sumber gambar: Blog Teknik Walmart Labs

SSR

CSR

NB: SSR (Server Side Rendering), CSR (Client Side Rendering).

Perbedaan utamanya adalah bahwa dengan SSR, respons server ke browser klien, termasuk HTML halaman yang akan dirender. Penting juga untuk dicatat bahwa meskipun, dengan SSR, halaman dirender lebih cepat. Halaman tidak akan siap untuk interaksi pengguna sampai file JS diunduh dan browser menjalankan React.

Satu kelemahannya adalah SSR TTFB (Time to First Byte) bisa sedikit lebih lama. Dapat dimaklumi, karena server membutuhkan beberapa waktu untuk membuat dokumen HTML, yang pada gilirannya meningkatkan ukuran respons server.

JSON C11
sumber
4

Saya sebenarnya bertanya-tanya sedikit penelitian yang sama dan sementara jawaban yang Anda cari diberikan di komentar tetapi saya merasa itu harus lebih menonjol karena itu saya menulis posting ini (yang akan saya perbarui setelah saya dapat menemukan cara yang lebih baik karena saya menemukan solusi secara arsitektural setidaknya dipertanyakan).

Anda perlu menulis komponen Anda dengan kedua cara dalam pikiran sehingga pada dasarnya meletakkan ifsakelar di mana-mana untuk menentukan apakah Anda berada di klien atau server dan kemudian melakukan baik sebagai kueri DB (atau apa pun yang sesuai di server) atau panggilan REST (di klien). Kemudian Anda harus menulis titik akhir yang menghasilkan data Anda dan memaparkannya ke klien dan begitulah.

Sekali lagi, senang belajar tentang solusi yang lebih bersih.

SGD
sumber
2

Apakah ini 2 cara terpisah untuk membangun aplikasi, atau dapatkah keduanya digunakan bersama?

Mereka bisa digunakan bersama.

Jika kita dapat menggunakannya bersama, bagaimana melakukannya - apakah kita perlu menduplikasi elemen yang sama di sisi server dan sisi klien? Atau, bisakah kita membangun bagian statis aplikasi kita di server, dan bagian dinamis di sisi klien, tanpa koneksi ke sisi server yang sudah di-render?

Lebih baik memiliki tata letak yang sama yang sedang dirender untuk menghindari operasi pengubahan posisi dan pengecatan ulang, lebih sedikit kedipan / kedipan, halaman Anda akan lebih lancar. Namun, itu bukanlah batasan. Anda dapat menyimpan html SSR dengan sangat baik (sesuatu yang dilakukan Electrode untuk mengurangi waktu respons) / mengirim html statis yang akan ditimpa oleh CSR (render sisi klien).

Jika Anda baru memulai dengan SSR, saya sarankan untuk memulai dengan sederhana, SSR bisa menjadi sangat kompleks dengan sangat cepat. Untuk membangun html di server berarti kehilangan akses ke objek seperti jendela, dokumen (Anda memilikinya di klien), kehilangan kemampuan untuk memasukkan operasi asinkron (di luar kotak), dan umumnya banyak pengeditan kode agar kode Anda kompatibel dengan SSR ( karena Anda harus menggunakan webpack untuk mengemas bundle.js Anda). Hal-hal seperti impor CSS, require vs import tiba-tiba mulai menggigit Anda (ini tidak terjadi pada aplikasi React default tanpa webpack).

Pola umum SSR terlihat seperti ini. Server Express melayani permintaan:

const app = Express();
const port = 8092;

// This is fired every time the server side receives a request
app.use(handleRender);
function handleRender(req, res) {
    const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
    console.log('fullUrl: ', fullUrl);
    console.log('req.url: ', req.url);

    // Create a new Redux store instance
    const store = createStore(reducerFn);

    const urlToRender = req.url;
    // Render the component to a string
    const html = renderToString(
        <Provider store={store}>
            <StaticRouter location={urlToRender} context={{}}>
                {routes}
            </StaticRouter>
        </Provider>
    );
    const helmet = Helmet.renderStatic();

    // Grab the initial state from our Redux store
    const preloadedState = store.getState();

    // Send the rendered page back to the client
    res.send(renderFullPage(helmet, html, preloadedState));
}

Saran saya untuk orang-orang yang memulai dengan SSR akan menyajikan html statis. Anda bisa mendapatkan html statis dengan menjalankan aplikasi CSR SPA:

document.getElementById('root').innerHTML

Jangan lupa, satu-satunya alasan untuk menggunakan SSR adalah:

  1. SEO
  2. Beban lebih cepat (saya akan mendiskon ini)

Retas: https://medium.com/@gagan_goku/react-and-server-side-rendering-ssr-444d8c48abfc

Kira
sumber