ReactJS sunucu tarafı işleme ve istemci tarafı işleme


120

ReactJS'i incelemeye yeni başladım ve bunun size sayfaları oluşturmanın 2 yolunu sunduğunu gördüm: sunucu tarafı ve istemci tarafı. Ama onu birlikte nasıl kullanacağımı anlayamıyorum. Uygulamayı oluşturmanın 2 ayrı yolu mu yoksa birlikte kullanılabilir mi?

Birlikte kullanabilirsek, nasıl yapılır - sunucu tarafında ve istemci tarafında aynı öğeleri kopyalamamız gerekir mi? Ya da uygulamamızın statik kısımlarını sunucuda ve dinamik kısımlarını istemci tarafında, önceden oluşturulmuş sunucu tarafına herhangi bir bağlantı olmadan oluşturabilir miyiz?


1
Kısa yanıt, HAYIR - ayırabilir, statik html gönderebilir ve istemci oluşturmada tamamen değiştirebilirsiniz. Cevabıma detaylar ekledim.
Kira

Yanıtlar:


108

Belirli bir web sitesi / web uygulaması için, istemci tarafı , sunucu tarafı veya her ikisini birden kullanabilirsiniz .

İstemci Tarafı

Burada, tarayıcıda tamamen ReactJS çalıştırıyorsunuz. Bu en basit kurulumdur ve çoğu örneği içerir (http: //reactjs.org'dakiler dahil ). Sunucu tarafından oluşturulan ilk HTML bir yer tutucudur ve tüm komut dosyalarınız yüklendikten sonra kullanıcı arayüzünün tamamı tarayıcıda oluşturulur.

Sunucu Tarafı

ReactJS'i burada sunucu tarafı şablonlama motoru olarak düşünün (yeşim, gidon, vb. Gibi). Sunucu tarafından oluşturulan HTML, olması gerektiği gibi kullanıcı arayüzünü içerir ve herhangi bir komut dosyasının yüklenmesini beklemeyin. Sayfanız bir arama motoru tarafından dizine eklenebilir (herhangi bir javascript çalıştırmıyorsa).

Kullanıcı arabirimi sunucuda oluşturulduğundan, olay işleyicilerinizden hiçbiri çalışmaz ve etkileşim yoktur (statik bir sayfanız vardır).

Her ikisi de

Burada, ilk render sunucu üzerindedir. Bu nedenle, tarayıcı tarafından alınan HTML, olması gerektiği gibi UI'ye sahiptir. Komut dosyaları yüklendikten sonra, bileşenlerinizin olay işleyicilerini kurmak için sanal DOM bir kez daha yeniden oluşturulur.

Burada, aynı sanal DOM'u (kök ReactJS bileşeni) sunucuda oluşturduğunuzla aynı şekilde yeniden oluşturduğunuzdan emin olmanız gerekir props. Aksi takdirde ReactJS, sunucu tarafındaki ve istemci tarafındaki sanal DOM'ların eşleşmediğinden şikayet edecektir.

ReactJS, sanal DOM'ları yeniden oluşturmalar arasında farklılaştırdığından, gerçek DOM mutasyona uğramaz. Yalnızca olay işleyicileri gerçek DOM öğelerine bağlıdır.


1
Yani "her ikisi" durumunda aynı kodu iki kez yazmam gerekiyor, biri sunucu oluşturma için ve diğeri bu DOM'u istemcide yeniden oluşturmak için mi?
Simcha

10
Aynı kodu iki kez çalıştırmanız gerekir . Bir kez sunucuda ve bir kez istemcide. Ancak, bunu hesaba katmak için bileşenlerinizi yazmanız gerekir - örneğin componentWillMount(), hem istemciyi hem de sunucuyu çalıştıracağı için eşzamansız veri getirme yapmamalısınız . Aynı çıktıyı aldığınızdan emin olmak için, verileri sunucuda önden getirmek ve istemcide ilk render için kullanılabilir hale getirmek için bir stratejiye de ihtiyacınız olacak.
Jonny Buchanan

3
Ayrıca, çalıştırılan kodun sunucu tarafında mı yoksa istemci tarafında mı olduğunu kontrol edebilir typeof window == "undefined"ve ardından verilerinizi buna göre getirebilirsiniz.
Gautham Badhrinathan

Uygulamanıza uyan bir örneğe bağlantınız var mı?
Sawtaytoes

1
@IanW Tipik olarak bu durumda, sunucu tarafından döndürülen HTML çok "çıplak kemikler" dir, sadece JavaScript'inizi ve stilleri içe aktarır ve React'in yazacağı bir dosyayı içerir <div>.
Matt Holland

48

Resim kaynağı: Walmart Labs Engineering Blog

SSR

CSR

NB: SSR (Sunucu Tarafı Oluşturma), CSR (İstemci Tarafı Oluşturma).

Temel fark, SSR ile sunucuların istemcinin tarayıcısına yanıt vermesi, işlenecek sayfanın HTML'sini içermesidir. SSR ile sayfanın daha hızlı görüntülendiğine de dikkat etmek önemlidir. JS dosyaları indirilene ve tarayıcı React'i çalıştırana kadar sayfa kullanıcı etkileşimi için hazır olmayacaktır.

Bir dezavantajı, SSR TTFB'nin (İlk Bayt Süresi) biraz daha uzun olabilmesidir. Anlaşılır bir şekilde, çünkü sunucu HTML belgesini oluşturmak için biraz zaman alıyor ve bu da sunucuların yanıt boyutunu artırıyor.


4

Aslında aynı araştırmayı epeyce merak ediyordum ve aradığınız cevap yorumlarda verilmiş olsa da daha belirgin olması gerektiğini düşünüyorum bu yüzden bu yazıyı yazıyorum (bir kez bulabilirsem güncelleyeceğim çözümü mimari olarak en azından sorgulanabilir bulduğum için daha iyi bir yol).

Bileşenlerinizi her iki yolu da göz önünde bulundurarak yazmanız gerekir, böylece temelde ifistemcide mi yoksa sunucuda mı olduğunuzu belirlemek için anahtarları her yere koyun ve ardından DB sorgusu (veya sunucuda uygun olanı) veya bir REST çağrısı ( istemci). Ardından, verilerinizi oluşturan ve müşteriye açıklayan uç noktalar yazmanız gerekir ve işte oraya gidersiniz.

Daha temiz bir çözümü öğrenmekten yine mutluyum.


2

Uygulamayı oluşturmanın 2 ayrı yolu mu yoksa birlikte kullanılabilir mi?

Birlikte kullanılabilirler.

Birlikte kullanabilirsek, nasıl yapılır - sunucu tarafında ve istemci tarafında aynı öğeleri kopyalamamız gerekir mi? Ya da uygulamamızın statik kısımlarını sunucuda ve dinamik kısımlarını istemci tarafında, önceden oluşturulmuş sunucu tarafına herhangi bir bağlantı olmadan oluşturabilir miyiz?

Yeniden akıtma ve yeniden boyama işlemlerinden kaçınmak için aynı mizanpajın oluşturulması daha iyidir, daha az titreme / yanıp sönme, sayfanız daha düzgün olacaktır. Ancak bu bir sınırlama değildir. SSR html'sini ( Electrode'un yanıt süresini kısaltmak için yaptığı bir şey) çok iyi bir şekilde önbelleğe alabilir / CSR tarafından üzerine yazılan (istemci tarafı oluşturma) statik bir html gönderebilirsiniz.

SSR ile yeni başlıyorsanız, basit bir şekilde başlamanızı tavsiye ederim, SSR çok hızlı bir şekilde çok karmaşık hale gelebilir. Sunucuda html oluşturmak, pencere, belge (istemcide bunlar var) gibi nesnelere erişimi kaybetmek, eşzamansız işlemleri birleştirme yeteneğini kaybetmek (kutudan çıkar) ve genellikle kodunuzu SSR uyumlu hale getirmek için çok sayıda kod düzenlemesi yapmak anlamına gelir ( çünkü bundle.js dosyanızı paketlemek için web paketini kullanmanız gerekecek). CSS içe aktarma gibi şeyler, vs içe aktarmayı gerektirir, aniden sizi ısırmaya başlar (web paketi olmayan varsayılan React uygulamasında durum böyle değildir).

SSR'nin genel düzeni şuna benzer. İsteklere hizmet veren bir Express sunucusu:

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));
}

SSR ile başlayanlara önerim, statik html sunmaktır. Statik html'yi CSR SPA uygulamasını çalıştırarak alabilirsiniz:

document.getElementById('root').innerHTML

Unutmayın, SSR'yi kullanmanın tek nedeni şunlar olmalıdır:

  1. SEO
  2. Daha hızlı yükler (bunu düşürürdüm)

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.