DET beste fra begge verdener: SSR Med isomorphic JavaScript

server-side rendering, ELLER SSR, er et uttrykk som du hører ofte i frontend utvikling samfunnet.

på det mest grunnleggende nivået er server-side gjengivelse akkurat det den beskriver: gjengivelsesprogrammer på serveren. Du navigerer til et nettsted, det gjør en forespørsel til serveren, det gjengir NOE HTML, og du får det fullstendig gjengitte resultatet tilbake i nettleseren din. Ganske grei. Du kan spørre deg selv hvorfor samfunnet selv har et buzzword for dette.

Før fremveksten av rike og dynamiske webapplikasjoner som støttet seg tungt På JavaScript og jQuery, ble i hovedsak alle webapplikasjoner servergjengitt. PHP, WordPress og til og med bare grunnleggende HTML-nettsteder er eksempler på dette.

når du besøker en side på et av disse nettstedene, får du TILBAKE ALLE HTML-dataene og alt. Hvis du klikker på en lenke, vil nettleseren gjøre en annen forespørsel til serveren. Etter svaret vil nettleseren oppdatere og gjengi neste side fra grunnen av. Denne tilnærmingen fungerer bra, og det har i årevis; nettlesere er spektakulært raske til å gjengi statisk HTML. Hva har endret seg?

Siden århundreskiftet Har JavaScript-bruken gått fra et lite dryss her og der for nettsideinteraktivitet til det ubestridte språket av valg på nettet. Vi sender stadig mer logikk Og JavaScript til nettleseren.

Enkeltsiderammer som React og Vue har innledet denne nye epoken med dynamiske, komplekse, datadrevne klient-gjengitte webapplikasjoner. Disse Spaene skiller seg fra server-gjengitte programmer fordi de ikke henter fullstendig gjengitt innhold komplett med data fra serveren før gjengivelse på skjermen.

applikasjoner på Klientsiden gjengir innholdet i nettleseren Ved Hjelp Av JavaScript. I stedet for å hente alt innholdet fra serveren, henter de bare EN barebones HTML-side uten kroppsinnhold og gjengir alt innholdet inni Ved Hjelp Av JavaScript.

fordelen med dette er at du unngår helsides oppdateringer som skjer med fullt server-gjengitte applikasjoner, noe som kan være litt rystende for brukeren. Enkeltsideklient-gjengitte apper vil oppdatere innhold på skjermen, hente data fra Apier og oppdatere rett foran deg uten noen form for sideoppdatering overhodet. Denne egenskapen er det som gjør at moderne webapplikasjoner føles snappy og» native » når du samhandler med dem.

gjengivelsesavvik på Klientsiden

det er ikke bare solskinn og regnbuer i SPA-VERDENEN på klientsiden. Det er noen avveininger som følger med gjengivelse av søknaden din på klientsiden. To primære eksempler ER SEO og innledende lastytelse.

SEO

siden klientgjengitte apper returnerer EN BARE-bones HTML-side med svært lite innhold før JavaScript slår inn og gjengir resten, kan det være vanskelig for søkemotorroboter å forstå HTML-strukturen på siden din, noe som er skadelig for søkerangeringene på nettstedet ditt. Google har gjort mye godt arbeid rundt dette, men det anbefales fortsatt å unngå klientsiden gjengivelse HVIS SEO er spesielt viktig.

innledende lastytelse

med klientgjengitte apper ser du vanligvis følgende ting skje når du åpner siden første gang:

  • appen laster noen grunnleggende HTML, som et appskall eller statisk navbar
  • du ser en lasteindikator av noe slag
  • innholdet ditt blir deretter gjengitt

problemet med dette er at søknaden din ikke vil vise noe før JavaScript laster helt fra nettverket og er ferdig med å gjengi elementer på skjermen.

i et nøtteskall er problemet med klientsidens ytelse generelt at du ikke kan kontrollere hvilken klientenhet noen bruker applikasjonen din på – enten det er deres toppmoderne smarttelefon, kraftig high-end stasjonær maskin eller $ 100 nedre smarttelefon.

vi kontrollerer imidlertid serveren. Vi kan nesten alltid gi vår server MER CPU og minne og justere det for å gjøre det bedre for våre brukere.

det beste fra begge verdener

Vi kan ha det beste fra begge verdener når du bruker server-side gjengivelse med moderne frontend teknologier. Måten dette vanligvis fungerer på, er at serveren gjengir og sender tilbake det fullstendig gjengitte programmet ved første belastning. Det neste trinnet, kjent som hydrering, er Hvor JavaScript-pakken din vil bli lastet ned og utført. Dette fester hendelsesbehandlere og ledninger ting opp som klientsiden ruteren.

med denne tilnærmingen får du alle FORDELENE MED SSR på startbelastningen, og hver interaksjon fra det punktet vil bli håndtert Av Klientsiden JavaScript. DETTE gir en rask, SEO-vennlig startbelastning, etterfulgt av den dynamiske single-page web app-opplevelsen som vi kjenner og elsker.

Programmer som dette er kjent som universelle programmer fordi Det samme JavaScript kjører på klienten og serveren. Du kan også høre mer avansert begrepet «isomorphic» blir brukt, som betyr akkurat det samme.

Opplæring: Implementering AV SSR

SSR er heller ikke uten avveininger. Det legger overhead til din utvikling ved å innføre en mer kompleks konfigurasjon samt å måtte være vert og administrere din egen server. Disse problemene er hvorfor utrolige rammer Som Neste.js Og Razzle er veldig populære: de abstraherer SSR-konfigurasjonsdelen og lar deg fokusere på å skrive UI-kode.

i denne opplæringen skal vi ikke bruke NOEN SSR-rammer. Den beste måten å lære hvordan noe fungerer, er å faktisk bygge det, så vi skal lære å lage det enkleste SSR-oppsettet vi muligens kan som vil gi:

  • Global CDN
  • fullt funksjonell backend API
  • Ingen servere eller infrastruktur for å administrere
  • Single-command deployment

Vi skal distribuere en universell Server-gjengitt React-applikasjon opprettet med create-react-app på Amazon Web Services (AWS). Du trenger ikke å ha ERFARING MED AWS for å følge med.

våre verktøy

for å bygge vår søknad, skal vi gjøre bruk av noen FORSKJELLIGE AWS-tjenester.

  • AWS Forsterker: Et rammeverk på høyt nivå for å administrere AWS-tjenester, hovedsakelig for mobil-og webutvikling
  • AWS Lambda: Kjør kode i skyen uten å administrere servere
  • AWS Cloudfront (CDN): et innholdsleveringsnettverk som er ansvarlig for å levere og caching innhold over hele verden
  • AWS Simple Storage Service (S3): Hvor vi lagrer våre statiske eiendeler (JS, CSS, etc.)

Architecture diagram

Vår Lambda funksjon er ansvarlig for server-rendering Vår React søknad. Vi bruker S3 til å lagre vårt statiske innhold og Cloudfront CDN for å betjene det. DU trenger ikke å ha noen forkunnskaper om disse tjenestene, DA AWS Amplify vil gjøre det super enkelt for oss å lage dem.

 Vårt Arkitekturdiagram

Vår Arkitektur Diagram

Bygg vår søknad

Først av alt må du installere AWS Amplify CLI og opprette EN AWS-konto hvis du ikke allerede har en. Du kan gjøre det ved å følge denne korte veiledningen.

Prosjektoppsett

Nå Som Amplify er konfigurert, kan vi begynne å sette opp Vårt React-prosjekt. Vi kommer til å bruke den fantastiske create-react-app for å hjelpe oss. Forutsatt at Du Har Noden.js og npm installert, kan vi kjøre:

npx create-react-app amplify-ssrcd amplify-ssr yarn add aws-amplify amplify init

Velg standardalternativene i AWS Amplify wizard.

Vårt React-prosjekt er nå bootstrapped Med Amplify og klar for oss å legge til vår «server» FOR SSR. Vi gjør dette ved å kjøre amplify add api og svare på noen spørsmål:

$ amplify add api? Please select from one of the below mentioned services: REST? Provide a friendly name for your resource to be used as a label for this category in the project: amplifyssr? Provide a path (e.g., /items): /ssr? Choose a Lambda source: Create a new Lambda function? Provide a friendly name for your resource to be used as a label for this category in the project: amplifyssr? Provide the AWS Lambda function name: ssr? Choose the function runtime that you want to use: NodeJS? Choose the function template that you want to use: Serverless expressJS function? Do you want to access other resources created in this project from your Lambda function? N? Do you want to edit the local lambda function now? N? Restrict API access: N? Do you want to add another path? N

dette vil skape relevante maler, kataloger og kode som trengs for VÅR AWS-infrastruktur og backend: EN AWS Lambda-funksjon som vil kjøre en liten Express-server som er ansvarlig for å gjengi Vår React-applikasjon.

Før vi distribuerer vår infrastruktur, er det noen endringer vi må gjøre i Vår React-applikasjon for å forberede den til server-side gjengivelse. Åpne opp src/App.js (den viktigste appkomponenten for Din React-applikasjon) og lim inn i følgende:

import React from 'react';function App() { return ( <div className="App"> <header className="App-header"> Server Rendered React App </header> </div> );}export default App;

Deretter må vi lage et skript som vil gjengi Vår React-applikasjon på serversiden. Dette gjøres med renderToString – funksjonen i react-dom/server – pakken. Denne funksjonen er ansvarlig for å ta vår <App /> komponent og gjengi den på serversiden som en streng, klar til å bli returnert som fullstendig gjengitt HTML til klienten.

Opprett en fil på src/render.js med følgende kode:

import React from "react";import { renderToString } from "react-dom/server";import App from "./App";export default () => renderToString(<App />);

Flott – vår klient-Side React app har all koden den trenger å bli gjengitt på serversiden. Dette betyr at vi nå må kode opp server-side endepunkt som vil gjengi Vår React søknad.

vi har et problem, men vi trenger src/render – funksjonen og vår <App /> komponentkode som skal kjøres på serversiden. Serveren vet ikke noe om React eller TIL OG MED ES-moduler som standard. Av denne grunn skal vi transpile koden fra React-programmet ved Hjelp Av Babel til serversiden.

for å gjøre dette, la oss installere Noen Babel-avhengigheter i prosjektet vårt.

yarn add --dev @babel/core @babel/cli @babel/preset-react @babel/preset-env

opprett deretter en .babelrc ved roten av prosjektet. Denne filen brukes til å konfigurere Babel og fortelle hvilke plugins / forhåndsinnstillinger som skal brukes.

{ "presets":}

Til Slutt, la oss oppdatere vår package.json for å transpilere koden vår som en del av byggetrinnet. Dette vil transpile filene inn i katalogen amplify/backend/function/amplifyssr/src/client, som er der vi lagrer all universell JavaScript som må kjøres på klientsiden, samt serveren FOR SSR.

 "scripts": { "start": "react-scripts start", "transpile": "babel src --out-dir amplify/backend/function/amplifyssr/src/client --copy-files", "build": "npm run transpile && react-scripts build && npm run copy", "copy": "cp build/index.html amplify/backend/function/amplifyssr/src/client", "test": "react-scripts test", "eject": "react-scripts eject" },

Gjengivelse av appen I Lambda

byggekonfigurasjonen er fullført! La oss hoppe inn i amplify/backend/function/amplifyssr/src og installere react og react-dom, da de begge vil være påkrevd for Lambda å utføre SSR.

yarn add react react-dom

nå for å konfigurere Vår Express server, som vil kjøre På Lambda. Lambda-funksjonen ble automatisk generert for oss da vi fullførte amplify add api – trinnet tidligere og valgte EN REST OG ExpressJS API.

Amplify har allerede konfigurert Express-serveren for at Vi skal kjøre På Lambda, så alt vi trenger å gjøre nå er å legge til et endepunkt på server-gjengi Vår React-applikasjon når noen treffer API-NETTADRESSEN i nettleseren. Oppdater filen amplify/backend/function/amplifyssr/src/app.js slik at den inneholder følgende kode:

/* Amplify Params - DO NOT EDIT ENV REGIONAmplify Params - DO NOT EDIT */const express = require('express')const bodyParser = require('body-parser')const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware')const fs = require('fs');const render = require('./client/render').default;// declare a new express appconst app = express()app.use(bodyParser.json())app.use(awsServerlessExpressMiddleware.eventContext())// Enable CORS for all methodsapp.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*") res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") next()});app.get('*', function(req, res) { // Read the index.html file from the create-react-app build const html = fs.readFileSync("./client/index.html", "utf-8"); // Server side render the react application const markup = render(); // Replace the empty body of index.html with the fully server rendered react application and send it back to the client res.send(html.replace(`<div></div>`, `<div>${markup}</div>`))});module.exports = app

Vår Express-server er NÅ SSR-klar, og vi kan distribuere Vår React-applikasjon.

Hosting og siste hånd

Når vi mottar server-gjengitt HTML tilbake fra appens første gjengivelse, vil vi da hente Klientsiden JavaScript-pakken for å overta derfra og gi oss et fullt interaktivt SPA.

Vi trenger et sted å være Vert For JavaScript Og statiske filer på klientsiden. I AWS er tjenesten som vanligvis brukes Til Dette S3 (Simple Storage Service), en massivt skalerbar skyobjektbutikk.

Vi skal også sette EN CDN foran den for global caching og ytelse. Med Amplify, kan vi lage begge disse ressursene for vårt prosjekt ved å kjøre noen kommandoer fra vårt prosjekt rotkatalog:

$ amplify add hostingSelect the plugin module to execute Amazon CloudFront and S3? Select the environment setup: PROD (S3 with CloudFront using HTTPS)? hosting bucket name (name your bucket or use the default)

Du kan nå distribuere hele infrastrukturen, inkludert Express server Lambda-funksjonen, S3 bucket og CDN, ved å kjøre kommandoen amplify publish.

konsollutgangen din vil vise alle relevante ressurser fra malene dine som blir opprettet for deg av Amplify. Vær oppmerksom på at å lage En Cloudfront CDN kan ta en stund, så vær tålmodig. Når ressursene dine er opprettet, Vises Cloudfront CDN-NETTADRESSEN din i terminalen.

Publish started for S3AndCloudFront✔ Uploaded files successfully.Your app is published successfully.https://d3gdcgc9a6lz30.cloudfront.net

det siste vi trenger å gjøre er å fortelle React fra hvor du skal hente vår klientside bunt etter at appen er gjengitt av serveren. Dette gjøres i create-react-app ved hjelp av miljøvariabelen PUBLIC_URL. La oss oppdatere Vår React app package.json skript igjen for å se ut som følgende:

 "scripts": { "start": "react-scripts start", "transpile": "babel src --out-dir amplify/backend/function/amplifyssr/src/client --copy-files", "build": "npm run transpile && PUBLIC_URL=<your-cloudfront-url> react-scripts build && npm run copy", "copy": "cp build/index.html amplify/backend/function/amplifyssr/src/client", "test": "react-scripts test", "eject": "react-scripts eject" },

Bygge og distribuere programmet TIL AWS med denne oppdaterte konfigurasjonen.

amplify publish

Vi skal nå ha en fullt server-side-rendret React app som kjører PÅ AWS!

Kjører vår app

DIN SSR API URL finner du på amplify/backend/amplify-meta.json. Se etter RootUrl I json-filen din, og du bør se NETTADRESSEN der du kan besøke din nye server-gjengitte applikasjon. Det skal se ut som følgende:

"output": { "ApiName": "amplifyssr", "RootUrl": "https://g6nfj3bvsg.execute-api.eu-west-1.amazonaws.com/dev", "ApiId": "g6nfj3bvsg"}, 

Besøk API Gateway URL i nettleseren din på <your-api-url>/ssr og du bør se din skinnende nye server-rendret React søknad! Hvis Du dykker inn I Nettverksfanen i nettleseren din og ser forespørslene, vil du legge merke til at forespørselen til /ssr har et fullstendig gjengitt HTML-svar med Vår React-applikasjon gjengitt i <body> av dokumentet.

<div> <div class="App" data-reactroot=""> <header class="App-header">Server Rendered React App</header> </div></div>

du vil også legge merke til at forespørslene blir gjort til Din Cloudfront URL fra nettleseren for å laste klientsiden JavaScript som vil overta gjengivelsen herfra, noe som gir oss det beste av både klientsiden og serversiden gjengivelsesverdener.

hvor å gå herfra

denne opplæringen er ment å få deg i gang med server-side gjengivelse så raskt som mulig uten å bekymre deg for å administrere infrastruktur, Cdn-er og mer. Etter å ha brukt serverløs tilnærming, er det noen fine forbedringer vi kan gjøre i oppsettet vårt.

Klargjort samtidighet

EN måte SOM AWS Lambda er i stand til å forbli ekstremt lave kostnader er At Lambda-funksjoner som ikke har blitt truffet på en stund, vil gå » inaktiv.»Dette betyr i hovedsak at når vi utfører dem igjen, vil det være det som kalles en» kaldstart — – en initialiseringsforsinkelse som må skje før Lambda reagerer.

etter dette blir lambda» varm » igjen i en periode og vil svare på påfølgende forespørsler raskt til neste lange tomgangsperiode. Dette kan føre til litt upålitelige responstider.

Til tross for at Den er «serverløs», bruker Lambda lette beholdere til å behandle eventuelle forespørsler. Hver container kan behandle bare en forespørsel til enhver tid. I tillegg til kaldstart-problemet etter en inaktiv periode, er det samme også sant når mange samtidige forespørsler treffer Samme Lambda-funksjon, noe som fører til at flere samtidige beholdere eller arbeidere blir kaldstart før de svarer.

Tidligere har mange ingeniører løst dette problemet ved å skrive skript for å pinge Lambda regelmessig for å holde det varmt. Det er nå en mye bedre AWS-innfødt måte å løse dette på, og det er kjent som Provisioned Concurrency.

Med Klargjort Samtidighet kan du enkelt be om et gitt antall dedikerte beholdere for å holde varmen for en Bestemt Lambda-funksjon. Dette vil gi deg en mye mer konsekvent SSR responstid i tider med høy og sporadisk belastning.

Lambda versjoner

du kan opprette Flere Lambda versjoner for dine funksjoner og dele trafikk mellom dem. Dette er svært kraftig i VÅR SSR søknad som det tillater oss å gjøre oppdateringer På Lambda side og a / B teste dem med en mindre del av brukerne.

du kan publisere flere versjoner Av Lambda og dele trafikk mellom dem i vekter som du angir. For eksempel kan det være lurt å server-gjengi EN CTA banner for noen brukere å måle engasjement, men ikke gjengi det for andre. Du kan gjøre dette Med Lambda-versjoner.

Full-stack web application

SOM forklart tidligere oppretter AWS Amplify allerede EN REST API og En Express-server for oss, der vi har opprettet et endepunkt til server-gjengi Vår React-applikasjon. Vi kan alltid legge til flere kode og endepunkter til Denne Express-serveren på amplify/backend/function/amplifyssr/src/app.js, slik at vi kan gjøre appen vår til en full-stack webapplikasjon, komplett med database, autentisering og mer.

DU kan benytte deg av DEN fantastiske PAKKEN MED AWS Amplify-verktøy for å lage disse ressursene eller koble til din egen infrastruktur – selv om DEN ikke er vert PÅ AWS. Du kan behandle AWS Lambda backend som alle Andre Express server og bygge på toppen av det.

du har allerede hele distribusjonsrørledningen konfigurert ved å kjøre amplify publish, slik at du kan fokusere på å skrive kode. Utgangspunktet i denne opplæringen gir deg total fleksibilitet til å gjøre hva du vil herfra.

Konklusjon

server-side gjengivelse trenger ikke å være vanskelig. Vi kan bruke fullt administrerte verktøy Som Next eller Razzle, som er fantastiske i seg selv, men for mange lag kan dette være altfor stort et paradigmeskifte gitt deres eksisterende kode eller krav. Ved hjelp av en enkel, lite vedlikehold, tilpasset tilnærming kan gjøre livet enklere, spesielt hvis du allerede bruker AWS eller Amplify for prosjektet.

SSR kan legge massevis av verdi til web-applikasjoner og gi en sårt tiltrengt ytelse ELLER SEO boost. Vi er heldige i webutvikling samfunnet å ha verktøy som kan lage Cdn, serverløse backends, og fullt vert webapplikasjoner med noen få kommandoer eller klikk.

selv om du ikke tror DU trenger SSR, er det et veldig utbredt og vanlig tema i JavaScript-økosystemet. Å ha en forståelse av sine fordeler og avveininger vil komme til nytte for nesten alle som er involvert i webutvikling sfære.

jeg håper du lærte noe i dag-takk for at du leser! Ta gjerne kontakt med Meg eller følg Meg På Twitter, hvor jeg tweet og blogger Om JavaScript, Python, AWS, automatisering og ingen kodeutvikling.

Full oversikt over react-apper

Feilsøking Av React-programmer kan være vanskelig, spesielt når brukere opplever problemer som er vanskelige å reprodusere. Hvis du er interessert i å overvåke Og spore Redux-tilstand, automatisk oppdage JavaScript-feil og spore langsomme nettverksforespørsler og komponentinnlastingstid, kan Du prøve LogRocket. LogRocket Dashboard Gratis Prøveversjon Banner

LogRocket er som EN DVR for web apps, opptak bokstavelig talt alt som skjer På Din React app. I stedet for å gjette hvorfor problemer oppstår, kan du samle og rapportere om hvilken tilstand søknaden din var i da et problem oppstod. LogRocket overvåker også appens ytelse, rapportering med beregninger som klient-CPU-belastning, bruk av klientminne og mer.

LogRocket Redux middleware-pakken legger til et ekstra lag med synlighet i brukerøktene dine. LogRocket logger alle handlinger og tilstand fra Redux butikker.

Moderniser hvordan Du feilsøker React apps-start overvåking gratis.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.