Razzle: サヌバヌレンダリングのトラブルシュヌティングを行うにはどうすればよいですか

䜜成日 2019幎02月05日  Â·  9コメント  Â·  ゜ヌス: jaredpalmer/razzle

こんにちは、

Googleの怜玢コン゜ヌルにログむンしおGoogleずしお取埗するず、りェブサむトが空癜のペヌゞずしお衚瀺されるずいう問題に気づきたした。

私はいく぀かの調査を行いたした、そしおそれのいく぀かは私をこの蚘事に導きたす

https://medium.com/@gajus/react -application-seen-as-a-blank-page-via-fetch-as-google-afb11dff8562

それは怜玢゚ンゞンである可胜性が非垞に高く、グヌグル自䜓が同じように動䜜しないのでフェッチしたす。そうしないず、今たでにランキングを倱っおいたでしょうが、それでも、りェブサむトの所有者を目芚めさせおしたうので、この問題を解決したいず思いたす。

phantomjsをダりンロヌドしたしたが、これはGoogleず同じフェッチであるず想定しおおり、レンダリングしようずするず、いく぀かの゚ラヌが返されたす。

image

この問題は、コンパむルするタヌゲットブラりザを倉曎するのず同じくらい簡単に解決できる堎合がありたすが、babel / polyfilをむンストヌルしおむンポヌトするだけでは機胜したせん。

誰かが私をここで正しい方向に向けるこずができるでしょうか

最も参考になるコメント

したがっお、私の提案そしおおそらくこれに関するドキュメントのトラブルシュヌティングガむドが必芁ですは、 server.js 、 client.js 、 App.js 、そしお朜圚的にはできるだけ倚くコメントアりトするこずですWebpackのアスペクト存圚する堎合をオヌバヌラむドしお、Razzleアプリケヌションを「HelloWorld」のような状態に戻したす。 たた、すべおのスクリプトが箱から出しお正しくロヌドされおいるこずを確認するために、RazzleのHTMLテンプレヌトをserver.jsファむルにコピヌしお戻すこずをお勧めしたす。 実行したら、Chrome開発ツヌルを開き、[パフォヌマンス]タブに移動し、[スクリヌンショット]チェックボックスをオンにしお、[曎新]アむコンを抌したす。 以䞋のGIFを参照しおください。

kapture 2019-02-05 at 8 33 42

目暙は、タむムラむン領域に空癜の癜いフレヌムがないこずを確認するこずです。 フラッシュなしで適切なレンダリングを取埗したら、叀いコヌドをさらに远加する必芁がありたす。 赀ちゃんの䞀歩を螏み出したす。 泚意しないず、これは非垞に簡単に混乱したす。

あなたの特定のケヌスに関しおは、私はあなたがしおいるすべおのグヌグルタグマネヌゞャヌのもの、あなたのCSS、そしおどんなコヌド分割も削陀するこずから始めたす。 レンダリングしお逆方向に動䜜させるだけです。 次に、Reduxを動䜜させたす。 次に、react-helmetを远加し盎し、問題がないず思ったら、Lighthouseテストも実行しお再確認したす[監査]タブ。 この状態を新しいブランチにコミットしお、将来その状態に戻るこずができるようにしたす。 次に、分析スクリプトを远加し盎しお、レンダリングを再床確認したす。 最埌に、コヌド分割を远加し盎しおみおください。

泚cssを保持し、Razzleを開発モヌドで䞊蚘の分析を行うず、Razzleは開発䞭にサヌバヌクラむアントのみで.cssスタむルを凊理しないため、FOUCが発生する可胜性がありたす。 したがっお、 .cssファむルを䜿甚しおいる堎合にスタむルハむドレヌションを䜿甚しお適切なSSRを実行しおいるこずを完党にテストするには、本番甚にRazzleをビルドし、本番サヌバヌをロヌカルで実行する必芁がありたす。 ただし、サヌバヌからHTMLの存圚を確認するだけの堎合は、これを開発モヌドで実行できたす。

党おのコメント9件

ペヌゞが空癜を取埗しおいる堎合は、SSRたたはハむドレヌションスキヌムが壊れおいたす。 Razzleは、箱から出しお説明した内容に悩たされるこずはありたせん。実際、BBC.comのようなSEOに焊点を圓おたサむトで䜿甚されおいたす。 server.jsファむルを貌り付けるこずができたすか サヌバヌでデヌタを取埗しおいたすか

こんにちはゞャレド、

迅速な返信をありがずう、はい、サヌバヌからデヌタをフェッチしたす。

これが私のserver.jsです

import App from './App';
import React from 'react';
import Helmet from 'react-helmet';
import { StaticRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import express from 'express';
import compression from 'compression';
import { renderToString } from 'react-dom/server';

import configureStore from './store/configureStore';
import { remoteLoader } from './api/remoteLoader';
import serialize from 'serialize-javascript';

import { Capture } from 'react-loadable';
import { getBundles } from 'react-loadable/webpack';
import stats from '../build/react-loadable.json';

import { IS_PRODUCTION } from './components/shared/constants';

const assets = require(process.env.RAZZLE_ASSETS_MANIFEST);

const server = express();
server.use(compression());

if (!IS_PRODUCTION) {
    server.set('cache', false);
}

server
    .disable('x-powered-by')
    .use(express.static(process.env.RAZZLE_PUBLIC_DIR, { Expires: '30d' }))
    .get('/*', (req, res) => {
        //Ensures clients with old css paths are served the current file
        if (req.path.indexOf('/static/css') > -1 && assets.client.css) {
            const currentCssFile = `${process.env.RAZZLE_PUBLIC_DIR}${assets.client.css}`;
            return res.sendFile(currentCssFile);
        }

        remoteLoader(apiResult => {
            const responseCode = typeof apiResult.status === 'undefined' ? 404 : apiResult.status;

            if (responseCode === 301) {
                return res.redirect(responseCode, apiResult.headers.location);
            }

            // Compile an initial state
            const initialState = {
                remote: {
                    cms: {
                        result: apiResult ? apiResult.data : false,
                        loading: false
                    },
                    myDrewberry: {
                        searchResults: null,
                        loading: false,
                        failed: false
                    }
                }
            };
            // Create a new Redux store instance
            const store = configureStore(initialState);

            const context = {};
            const modules = [];
            const markup = renderToString(
                <Capture report={moduleName => modules.push(moduleName)}>
                    <StaticRouter context={context} location={req.url}>
                        <Provider store={store}>
                            <App />
                        </Provider>
                    </StaticRouter>
                </Capture>
            );
            const helmet = Helmet.renderStatic();

            if (context.url) {
                res.redirect(context.url);
            } else {
                const bundles = getBundles(stats, modules);
                const chunks = bundles.filter(bundle => bundle.file.endsWith('.js'));

                res.status(responseCode).send(
                    `<!doctype html>
                    <html ${helmet.htmlAttributes.toString()}>
                    <head>

                        ${assets.client.css ? `<link rel="stylesheet" href="${assets.client.css}">` : ''}
                        ${helmet.title.toString()}
                        ${helmet.meta.toString()}
                        ${helmet.link.toString()}
                        <link rel="icon" type="image/png" href="/favicon16.png" sizes="16x16"/>
                        <link rel="icon" type="image/png" href="/favicon32.png" sizes="32x32"/>
                        <link rel="icon" type="image/png" href="/favicon96.png" sizes="96x96"/>
                        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/> <!--320-->
                        <meta http-equiv="expires" content="0">
                    </head>
                    <body class="drewberry-preload">

                        <!-- Google Tag Manager -->
                            <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
                            new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
                            j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
                            'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
                            })(window,document,'script','dataLayer','GTM-TKPXWB');</script>
                        <!-- End Google Tag Manager -->

                        <div id="root">${markup}</div>
                        <script>
                            window.__PRELOADED_STATE__ = ${serialize(initialState)}
                        </script>
                        ${
                            IS_PRODUCTION
                                ? `<script src="${assets.client.js}"></script>`
                                : `<script src="${assets.client.js}" crossorigin></script>`
                        }
                          ${chunks
                              .map(chunk =>
                                  IS_PRODUCTION
                                      ? `<script src="/${chunk.file}"></script>`
                                      : `<script src="http://${process.env.HOST}:${parseInt(process.env.PORT, 10) + 1}/${
                                            chunk.file
                                        }"></script>`
                              )
                              .join('\n')}
                          <script>window.main();</script>
                    </body>
                </html>`
                );
            }
        }, req.path);
    });

export default server;

箱から出しおRazzleに問題がないこずを確認できたす。クリヌンむンストヌルをロヌドし、phantomjsを䜿甚するず、譊告は衚瀺されたせんでした。これは、おそらくラむブラリがむンストヌルしたものであるこずを意味したす。

䞊蚘で明らかなこずはありたすか

今はガチョりの远跡のようです :-)

したがっお、私の提案そしおおそらくこれに関するドキュメントのトラブルシュヌティングガむドが必芁ですは、 server.js 、 client.js 、 App.js 、そしお朜圚的にはできるだけ倚くコメントアりトするこずですWebpackのアスペクト存圚する堎合をオヌバヌラむドしお、Razzleアプリケヌションを「HelloWorld」のような状態に戻したす。 たた、すべおのスクリプトが箱から出しお正しくロヌドされおいるこずを確認するために、RazzleのHTMLテンプレヌトをserver.jsファむルにコピヌしお戻すこずをお勧めしたす。 実行したら、Chrome開発ツヌルを開き、[パフォヌマンス]タブに移動し、[スクリヌンショット]チェックボックスをオンにしお、[曎新]アむコンを抌したす。 以䞋のGIFを参照しおください。

kapture 2019-02-05 at 8 33 42

目暙は、タむムラむン領域に空癜の癜いフレヌムがないこずを確認するこずです。 フラッシュなしで適切なレンダリングを取埗したら、叀いコヌドをさらに远加する必芁がありたす。 赀ちゃんの䞀歩を螏み出したす。 泚意しないず、これは非垞に簡単に混乱したす。

あなたの特定のケヌスに関しおは、私はあなたがしおいるすべおのグヌグルタグマネヌゞャヌのもの、あなたのCSS、そしおどんなコヌド分割も削陀するこずから始めたす。 レンダリングしお逆方向に動䜜させるだけです。 次に、Reduxを動䜜させたす。 次に、react-helmetを远加し盎し、問題がないず思ったら、Lighthouseテストも実行しお再確認したす[監査]タブ。 この状態を新しいブランチにコミットしお、将来その状態に戻るこずができるようにしたす。 次に、分析スクリプトを远加し盎しお、レンダリングを再床確認したす。 最埌に、コヌド分割を远加し盎しおみおください。

泚cssを保持し、Razzleを開発モヌドで䞊蚘の分析を行うず、Razzleは開発䞭にサヌバヌクラむアントのみで.cssスタむルを凊理しないため、FOUCが発生する可胜性がありたす。 したがっお、 .cssファむルを䜿甚しおいる堎合にスタむルハむドレヌションを䜿甚しお適切なSSRを実行しおいるこずを完党にテストするには、本番甚にRazzleをビルドし、本番サヌバヌをロヌカルで実行する必芁がありたす。 ただし、サヌバヌからHTMLの存圚を確認するだけの堎合は、これを開発モヌドで実行できたす。

さお、Razzleずの玠晎らしい仕事に感謝したす、そしお今これに感謝したす。 私はそれをうたく監査し、報告する぀もりです。

もちろん、「空の」空癜ではない、゚ラヌですseoペヌゞを最初にチェックするのは、衚瀺するデヌタをロヌドするためにペヌゞがcomponentDidMountに䟝存しおいるかどうかです。 curlを䜿甚しおすばやく確認できたす。 はいの堎合、プリロヌドするにはAfter.jsのようなものが必芁です。

1000msマヌクの呚りに空癜のペヌゞがある堎合、[パフォヌマンス]タブを䜿甚しおデバッグする方法をアドバむスできたすか 私の問題は、アむコンフォントラむブラリがサヌバヌにロヌドされないこずであり、したがっお、初期ロヌド時にこれらの空癜の空の正方圢が衚瀺されるこずを知っおいたす...

screen shot 2019-02-11 at 9 57 30 am

ああ、私のカスタムフォントはすべお、ずっず埌になるたで読み蟌たれたせん。 CSSの@ font-face {}を介しおフォントをロヌドしおいたす。

@font-face {
  font-family: 'SFProText';
  font-display: auto;
  src: url('fonts/SFPro/SF-Pro-Display-Regular.otf') format('truetype');
  font-weight: normal;
  font-style: normal;
}

@jaredpalmer私も同じ問題を抱えおいたす。 フォントずアセットがクラむアントペヌゞに読み蟌たれたせん。

アプリケヌションのセットアップにwebpack.configファむルを远加しおいたせん。これは、リポゞトリから耇補したものです。 リポゞトリからコピヌを取埗しおnpmモゞュヌルをむンストヌルした埌、npmstartコマンドを実行しおアプリケヌションの䜿甚を開始したした。
蚭定に倱敗したもの、たたはこの問題を解決するために新しいwebpackファむルを䜿甚する必芁があるものはありたすか

この問題の解決にご協力ください。

私のApp.cssファむルは次のようになりたす。
@ font-face {
font-family 'Roboto-medium';
srcurl "./ static / fonts / Roboto-Medium-webfont.eot";
srcurl "./ static / fonts / Roboto-Medium-webfont.eot#iefix"format "embedded-opentype"、url "./ static / fonts / Roboto-Medium-webfont.woff" format "woff"、url "./ static / fonts / Roboto-Medium-webfont.ttf"format "truetype"; }

@ font-face {
font-family 'Roboto-regular';
srcurl "./ static / fonts / roboto-regular-webfont.eot";
srcurl "./ static / fonts / roboto-regular-webfont.eot#iefix"format "embedded-opentype"、url "./ static / fonts / roboto-regular-webfont.woff" format "woff"、url "./ static / fonts / roboto-regular-webfont.ttf"format "truetype"; }

ありがずうinadvane :)

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡

関連する問題

mhuggins picture mhuggins  Â·  3コメント

krazyjakee picture krazyjakee  Â·  3コメント

gabimor picture gabimor  Â·  3コメント

MaxGoh picture MaxGoh  Â·  4コメント

alexjoyner picture alexjoyner  Â·  3コメント