Miten toteutat palvelinpuolen renderöinnin React-sovelluksessasi kolmessa yksinkertaisessa vaiheessa

Toimittaja Rohit Kumar

Tässä opetusohjelmassa rakennamme tällaisen hienon React-kortin.

Tässä opetusohjelmassa hyödynnämme palvelinpuolen renderöintiä toimittaaksemme HTML-vastauksen, kun käyttäjä tai indeksoijapalvelun indeksoijapalvelun käyttäjä tai indeksoijapalvelun indeksoijapalvelin osuu sivun URL-osoitteeseen. Käsittelemme jälkimmäiset pyynnöt asiakaspuolella.

Mihin tarvitsemme sitä?

Anna minun opastaa sinut vastaukseen.

Mitä eroa on asiakaspuolen renderöinnillä ja palvelinpuolen renderöinnillä?

Asiakaspuolen renderöinnissä selaimesi lataa minimaalisen HTML-sivun. Se renderöi JavaScriptin ja täyttää siihen sisällön.

Palvelinpuolen renderöinti taas renderöi React-komponentit palvelimella. Tuloksena on HTML-sisältö.

Voit yhdistää nämä kaksi ja luoda isomorfisen sovelluksen.

Cons of Rendering React on the Server

  • SSR voi parantaa suorituskykyä, jos sovellus on pieni. Mutta se voi myös heikentää suorituskykyä, jos se on raskas.
  • Se kasvattaa vasteaikaa (ja se voi olla pahempi, jos palvelin on kiireinen).
  • Se kasvattaa vastauksen kokoa, mikä tarkoittaa, että sivun lataaminen kestää kauemmin.
  • Se lisää sovelluksen monimutkaisuutta.

Milloin kannattaa käyttää palvelinpuolen renderöintiä?

Näistä SSR:n seurauksista huolimatta on joitakin tilanteita, joissa sitä voi ja kannattaa käyttää.

SEO

Jokainen verkkosivusto haluaa näkyä haussa. Korjatkaa, jos olen väärässä.

Hakukoneiden indeksoijat eivät valitettavasti vielä ymmärrä/renderöi JavaScriptiä.

Tämähän tarkoittaa, että he näkevät tyhjän sivun riippumatta siitä, kuinka hyödyllinen sivustosi on.

Monet sanovat, että Googlen indeksoija renderöi nyt JavaScriptiä.

Testaillakseni tätä otin sovelluksen käyttööni Herokussa. Näin näin Google Search Consolessa:

Googlen indeksoija ei renderöi Reactia

Tyhjä sivu.

Tämä oli suurin syy, miksi tutkin palvelinpuolen renderöintiä. Varsinkin kun kyseessä on kulmakivisivu, kuten laskeutumissivu, blogi ja niin edelleen.

Varmistaaksesi, renderöiikö Google sivustosi, käy:

Search Console Dashboard > Crawl > Fetch as Google. Syötä sivun URL-osoite tai jätä se tyhjäksi kotisivua varten.

Valitse FETCH AND RENDER. Kun olet valmis, klikkaa nähdäksesi tuloksen.

Suorituskyvyn parantaminen

SSR:ssä sovelluksen suorituskyky riippuu palvelimen resursseista ja käyttäjän verkon nopeudesta. Tämä tekee siitä erittäin hyödyllisen sisällöltään raskaille sivustoille.

Esimerkiksi sanotaan, että sinulla on keskihintainen matkapuhelin, jossa on hidas internet-nopeus. Yrität käyttää sivustoa, joka lataa 4 Mt dataa, ennen kuin näet mitään.

Pystyisitkö näkemään mitään näytölläsi 2-4 sekunnissa?

Käyisitkö kyseisellä sivustolla uudestaan?

En usko, että kävisit.

Toinen merkittävä parannus on käyttäjän ensimmäisen vuorovaikutuksen aika. Tämä on ero ajassa, joka kuluu siitä, kun käyttäjä osuu URL-osoitteeseen, siihen, kun hän näkee sisällön.

Tässä on vertailu. Testasin sitä kehitys-Macilla.

React Rendered on Server

SSR-suorituskykyraportti (Chrome)

Ensimmäinen vuorovaikutusaika on 300 ms. Hydrate päättyy 400 ms:ssa. Kuormitustapahtuma poistuu noin 500ms:n kohdalla. Voit nähdä tämän yllä olevasta kuvasta.

React Rendered on Client’s Browser

Client side performance report (Chrome)

Ensimmäinen vuorovaikutusaika on 400ms. Lataustapahtuma poistuu 470 ms:ssa.

Tulos puhuu puolestaan. Ensimmäisessä käyttäjän vuorovaikutusajassa on 100 ms ero näin pienessä sovelluksessa.

Miten se toimii? – (4 yksinkertaista vaihetta)

  • Luo uusi Redux Store jokaisella pyynnöllä.
  • Vaihtoehtoisesti lähetä joitain toimintoja.
  • Hae tila Storesta ja suorita SSR.
  • Lähetä edellisessä vaiheessa saatu tila yhdessä vastauksen kanssa.

Käytämme vastauksessa välitettyä tilaa alustavan tilan luomiseen asiakaspuolella.

Ennen kuin aloitat, kloonaa/lataa täydellinen esimerkki Githubista ja käytä sitä referenssinä.

Aloitetaan asettamalla sovelluksemme

Avaa ensin suosikkieditori ja komentotulkki. Luo uusi kansio sovellukselle. Aloitetaan.

npm init --yes

Täytä tiedot. Kun package.json on luotu, kopioi siihen alla olevat riippuvuudet ja skriptit.

Asenna kaikki riippuvuudet ajamalla:

npm install

Tarvitaan Babelin ja webpackin konfigurointi, jotta build-skriptimme toimii.

Babel muuttaa ESM:n ja reactin Noden ja selaimen ymmärtämäksi koodiksi.

Luo uusi tiedosto .babelrc ja laita siihen alla oleva rivi.

{ "presets": }

webpack niputtaa sovelluksemme ja sen riippuvuudet yhteen tiedostoon. Luo toinen tiedosto webpack.config.js , jossa on seuraava koodi:

const path = require('path');module.exports = { entry: { client: './src/client.js', bundle: './src/bundle.js' }, output: { path: path.resolve(__dirname, 'assets'), filename: ".js" }, module: { rules: }}

Kehitysprosessin tulosteena on kaksi tiedostoa:

  1. assets/bundle.js – puhdas asiakaspuolen sovellus.
  2. assets/client.js – asiakaspuolen kumppani SSR:lle.

Kansiossa src/ on lähdekoodi. Babelin käännetyt tiedostot menevät views/-kansioon. views-hakemisto luodaan automaattisesti, jos sitä ei ole.

Miksi lähdetiedostot pitää kääntää?

Syy on ESM:n & CommonJS:n syntaksiero. Reactia ja Reduxia kirjoittaessamme käytämme kaikissa tiedostoissa voimakkaasti importia ja exportia.

Valitettavasti ne eivät toimi Node. Tässä tulee Babel pelastamaan. Alla oleva skripti käskee Babelia kääntämään kaikki tiedostot src-hakemistossa ja laittamaan tuloksen views.

"babel": "babel src -d views",

Nyt Node voi ajaa niitä.

Kopioi esikoodatut & Staattiset tiedostot

Jos olet jo kloonannut arkiston, kopioi siitä. Muussa tapauksessa lataa ssr-static.zip-tiedosto Dropboxista. Pura se ja pidä nämä kolme kansiota sovellushakemistosi sisällä. Tässä on mitä ne sisältävät.

  1. React App ja komponentit sijaitsevat src/components.
  2. Redux-tiedostot src/redux/.
  3. assets/ & media/: Sisältää staattisia tiedostoja, kuten style.css ja kuvia.

Server Side

Luo kaksi uutta tiedostoa nimeltä server.js ja template.js kansioon src/.

src/server.js

Taidot tapahtuvat tässä. Tämä on koodi, jota olet etsinyt.

import React from 'react';import { renderToString } from 'react-dom/server';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';module.exports = function render(initialState) { // Model the initial state const store = configureStore(initialState); let content = renderToString(<Provider store={store} ><App /></Provider>); const preloadedState = store.getState(); return { content, preloadedState };};

Sovelluksemme renderöinnin sijaan meidän on paketoitava se funktioksi ja vietävä se. Funktio ottaa vastaan sovelluksen alkutilan.

Näin se toimii.

  1. Pass initialState kohtaan configureStore(). configureStore()palauttaa uuden Store-instanssin. Pidä sitä store-muuttujan sisällä.
  2. Kutsu renderToString()-metodia ja anna Appimme syötteenä. Se renderöi sovelluksemme palvelimella ja palauttaa tuotetun HTML:n. Nyt muuttuja content tallentaa HTML:n.
  3. Hae tila pois Redux Storesta kutsumalla getState() store:lle. Säilytä se muuttujassa preloadedState.
  4. Palauta content ja preloadedState. Välitämme nämä malliimme saadaksemme lopullisen HTML-sivun.

2. src/template.js

template.js vie funktion. Se ottaa syötteenä title, state ja content. Se injektoi ne malliin ja palauttaa lopullisen HTML-dokumentin.

Tilan välittämiseksi malli liittää state:n window.__STATE__:een <script>-tagin sisälle.

Nyt voit lukea state:aa asiakaspuolella käyttämällä window.__STATE__:aa.

Sisällytämme myös SSR:n kumppani assets/client.js:n asiakassovelluksen toiseen skriptitagiin.

Jos pyydät pelkkää asiakasversiota, se laittaa vain assets/bundle.js skriptitunnisteen sisälle.

Käyttäjäpuoli

Käyttäjäpuoli on melko suoraviivainen.

src/bundle.js

Näin kirjoitetaan Reactin ja Reduxin Provider wrap. Se on meidän puhdas asiakaspuolen sovelluksemme. Tässä ei ole mitään temppuja.

import React from 'react';import { render } from 'react-dom';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';const store = configureStore();render( <Provider store={store} > <App /> </Provider>, document.querySelector('#app'));

src/client.js

Näyttää tutulta? Joo, siinä ei ole mitään erikoista paitsi window.__STATE__. Meidän tarvitsee vain napata alkutila window.__STATE__:sta ja välittää se configureStore()-funktiollemme alkutilaksi.

Katsotaanpa uutta client-tiedostoamme:

import React from 'react';import { hydrate } from 'react-dom';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';const state = window.__STATE__;delete window.__STATE__;const store = configureStore(state);hydrate( <Provider store={store} > <App /> </Provider>, document.querySelector('#app'));

Katsotaanpa muutoksia:

  1. Korvaa render():n tilalle hydrate(). hydrate() on sama kuin render(), mutta sitä käytetään ReactDOMServer:n renderoimien elementtien hydratointiin. Se varmistaa, että sisältö on sama palvelimella ja asiakkaalla.
  2. Lue tila globaalista ikkunaobjektista window.__STATE__. Tallenna se muuttujaan ja poista window.__STATE__.
  3. Luo uusi store, jonka initialState on state.

Kaikki on tehty tässä.

Kokoaminen yhteen

Index.js

Tämä on sovelluksemme sisäänmenopiste. Se käsittelee pyynnöt ja templating.

Se myös julistaa initialState-muuttujan. Olen mallintanut sen assets/data.json tiedoston tiedoilla. Välitämme sen ssr()-funktiollemme.

Huomautus: Kun viittaat src/:n sisällä olevaan tiedostoon src/:n ulkopuolella olevasta tiedostosta, käytä normaalia require() ja korvaa src/:n views/:llä. Tiedät syyn (Babel compile).

Routing

  1. /: Oletusarvoisesti palvelinrenderöity kotisivu.
  2. /client: Esimerkki puhtaasta asiakaspuolen renderöinnistä.
  3. /exit: Palvelimen pysäytyspainike. Käytettävissä vain kehitystyössä.

Build & Run

On aika rakentaa ja ajaa sovelluksemme. Voimme tehdä tämän yhdellä koodirivillä.

npm run build && npm run start

Nyt sovellus on käynnissä http://localhost:3000.

Valmis React-ammattilaiseksi?

Aloitan ensi maanantaista alkaen uuden sarjan, jonka avulla saat React-taitosi liekkeihin heti.

Tilauslinkki alla ?

Kiitos kun luit tämän.

Jos pidät tästä ja pidät sitä hyödyllisenä, seuraa minua Twitterissä & Webflow.

Vastaa

Sähköpostiosoitettasi ei julkaista.