Halo,
Kami telah melihat masalah di mana jika Anda masuk ke konsol Pencarian Google, dan mengambil sebagai Google, situs web ditampilkan sebagai halaman kosong.
Saya telah melakukan beberapa penelitian, dan beberapa di antaranya membawa saya ke artikel ini:
https://medium.com/@gajus/react -application-seen-as-a-blank-page-via-fetch-as-google-afb11dff8562
Sangat mungkin mesin pencari, dan mengambil karena google sendiri tidak berperilaku dengan cara yang sama, atau kita akan kehilangan peringkat sekarang, namun saya ingin menyelesaikan masalah ini, karena akan membuat pemilik situs web tetap terjaga.
Saya telah mengunduh phantomjs, dengan asumsi itu sama dengan mengambil seperti Google, dan mencoba merendernya mengembalikan sejumlah kesalahan:
Masalah ini mungkin mudah diselesaikan seperti mengubah browser target yang sedang dikompilasi, namun menginstal babel/polyfil dan mengimpor saja tidak akan berhasil.
Adakah yang bisa mengarahkan saya ke arah yang benar di sini?
Jika halaman Anda kosong maka Anda telah merusak skema SSR atau hidrasi Anda. Razzle tidak mengalami apa yang telah Anda jelaskan di luar kotak, pada kenyataannya, ini digunakan di situs yang berfokus pada SEO seperti BBC.com. dapatkah Anda menempelkan file server.js Anda? Apakah Anda mengambil data Anda di server?
Hai Jared,
Terima kasih atas balasan yang cepat, ya kami mengambil data dari server.
Ini server saya.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;
Saya dapat mengonfirmasi bahwa di luar kotak Razzle tidak menderita karenanya, hanya memuat instalasi yang bersih dan menggunakan phantomjs tidak ada peringatan yang muncul, yang berarti itu mungkin sesuatu yang kami instal di perpustakaan.
Apakah Anda melihat sesuatu yang jelas di atas?
Rasanya seperti mengejar angsa liar saat ini! :-)
Jadi saran saya (dan mungkin kita memerlukan panduan pemecahan masalah dalam dokumen tentang ini) adalah berkomentar sebanyak mungkin dari server.js
, client.js
, App.js
, dan berpotensi aspek penggantian webpack Anda (jika ada) untuk mengembalikan aplikasi Razzle Anda ke status seperti "hello world". Saya juga menyarankan untuk menyalin kembali template HTML Razzle ke file server.js
hanya untuk memastikan bahwa semua skrip dimuat dengan benar di luar kotak. Setelah dijalankan, buka alat pengembang Chrome dan buka tab "Kinerja", centang kotak "Tampilan Layar", lalu tekan ikon Segarkan. Lihat GIF di bawah ini.
Tujuannya adalah untuk memastikan tidak ada bingkai putih kosong di area timeline. Setelah Anda mendapatkan render yang tepat tanpa berkedip, Anda harus menambahkan kembali lebih banyak dan lebih banyak kode lama Anda. Ambil langkah kecil. Ini cukup mudah untuk mengacaukan jika Anda tidak hati-hati.
Adapun kasus spesifik Anda, saya akan mulai dengan menghapus semua hal pengelola tag google, semua CSS Anda, serta pemecahan kode apa pun yang Anda lakukan. Cukup buat untuk dirender dan bekerja mundur. Selanjutnya, buat Redux berfungsi. Kemudian tambahkan kembali react-helm, dan kemudian, setelah Anda merasa sudah melakukannya dengan benar, periksa kembali dengan melakukan tes Lighthouse juga (tab Audit). Komit status ini ke cabang baru sehingga Anda dapat kembali ke sana di masa mendatang. Selanjutnya, tambahkan kembali skrip analitik Anda dan periksa rendering lagi. Terakhir, coba tambahkan kembali pemecahan kode.
Catatan: Jika Anda menyimpan css dan melakukan analisis di atas dengan Razzle dalam mode pengembangan, Anda mungkin mendapatkan FOUC karena Razzle tidak memproses gaya
.css
di server selama pengembangan (hanya pada klien). Jadi, untuk sepenuhnya menguji apakah Anda melakukan SSR yang tepat dengan hidrasi gaya jika Anda menggunakan file.css
, Anda harus membuat Razzle untuk produksi dan menjalankan server produksi secara lokal. Namun, jika Anda hanya memeriksa keberadaan HTML Anda dari server, Anda dapat menjalankannya dalam mode pengembangan.
Oke, terima kasih atas kerja luar biasa dengan Razzle, dan sekarang untuk ini. Saya akan mengauditnya dengan baik dan melaporkan kembali.
Tentu saja, hal pertama yang harus diperiksa pada halaman seo yang "kosong" (bukan kosong, itu adalah kesalahan), adalah: apakah halaman Anda bergantung pada componentDidMount
untuk memuat data yang akan ditampilkan. Anda dapat menggunakan curl
untuk memeriksa dengan cepat. Jika ya, Anda memerlukan sesuatu seperti After.js untuk dimuat sebelumnya.
bisakah Anda memberi saran cara men-debug menggunakan tab Performance, jika ada halaman kosong di sekitar tanda 1000ms? Saya tahu masalah saya adalah seputar pustaka font ikon yang tidak dimuat di server dan dengan demikian ini menunjukkan kotak kosong kosong ini pada pemuatan awal ...
Ah, semua font kustom saya tidak dimuat sampai lama kemudian. Saya memuat font saya melalui @font-face {} CSS.
@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 Saya juga memiliki masalah yang sama. Font dan aset tidak dimuat di halaman klien saya.
Saya belum menambahkan file webpack.config dalam pengaturan aplikasi saya, yang saya kloning dari repo Anda. Saya baru saja mengambil salinan dari repo Anda dan menginstal modul npm, kemudian saya mulai menggunakan aplikasi dengan menjalankan perintah npm start.
adakah yang saya lewatkan untuk mengonfigurasi atau harus menggunakan file webpack baru saya untuk menyelesaikan masalah ini?
Tolong bantu saya untuk menyelesaikan masalah ini.
File App.css saya terlihat seperti ini..
@font-wajah {
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-wajah {
font-family: 'Roboto-reguler';
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"); }
terima kasih inadvane :)
Komentar yang paling membantu
Jadi saran saya (dan mungkin kita memerlukan panduan pemecahan masalah dalam dokumen tentang ini) adalah berkomentar sebanyak mungkin dari
server.js
,client.js
,App.js
, dan berpotensi aspek penggantian webpack Anda (jika ada) untuk mengembalikan aplikasi Razzle Anda ke status seperti "hello world". Saya juga menyarankan untuk menyalin kembali template HTML Razzle ke fileserver.js
hanya untuk memastikan bahwa semua skrip dimuat dengan benar di luar kotak. Setelah dijalankan, buka alat pengembang Chrome dan buka tab "Kinerja", centang kotak "Tampilan Layar", lalu tekan ikon Segarkan. Lihat GIF di bawah ini.Tujuannya adalah untuk memastikan tidak ada bingkai putih kosong di area timeline. Setelah Anda mendapatkan render yang tepat tanpa berkedip, Anda harus menambahkan kembali lebih banyak dan lebih banyak kode lama Anda. Ambil langkah kecil. Ini cukup mudah untuk mengacaukan jika Anda tidak hati-hati.
Adapun kasus spesifik Anda, saya akan mulai dengan menghapus semua hal pengelola tag google, semua CSS Anda, serta pemecahan kode apa pun yang Anda lakukan. Cukup buat untuk dirender dan bekerja mundur. Selanjutnya, buat Redux berfungsi. Kemudian tambahkan kembali react-helm, dan kemudian, setelah Anda merasa sudah melakukannya dengan benar, periksa kembali dengan melakukan tes Lighthouse juga (tab Audit). Komit status ini ke cabang baru sehingga Anda dapat kembali ke sana di masa mendatang. Selanjutnya, tambahkan kembali skrip analitik Anda dan periksa rendering lagi. Terakhir, coba tambahkan kembali pemecahan kode.