Я провел аудит моего приложения React с помощью инструмента Chrome Lighthouse, и он обнаружил, что в моем приложении есть некоторые блокирующие CSS файлы рендеринга.Я провел дальнейшее исследование, запустив покрытие, и заметил, что мое приложение содержит около 50% неиспользуемого кода (CSS & JS).
Я пробовал различные плагины, такие как: Критический, Пентхаус, критический для веб-пакетов, Веб-пакет-плагин-critical, html-критический-webpack-plugin response-snap, чтобы удалить критические CSS из приложения, но ни один из них не работал в основном потому, что все плагины, которые должны помочь, ожидают, что приложение использует HTMLExtractPlugin.Однако это не относится ко мне, потому что все мое приложение отображается на сервере и обслуживается клиенту.
Вот функция рендеринга на моем сервере:
const serverRenderer = () => (req, res) => {
const content = renderToString(
<Provider store={req.store}>
<App />
</Provider>
);
const state = JSON.stringify(req.store.getState());
return res.send(
`<!doctype html>
${renderToString(
<Html
css={[res.locals.assetPath('bundle.css'), res.locals.assetPath('vendor.css')]}
scripts={[res.locals.assetPath('bundle.js'), res.locals.assetPath('vendor.js')]}
state={state}
>
{content}
</Html>
)}`
);
};
export default serverRenderer;
КОМПОНЕНТ HTML
// @flow
/* eslint-disable react/no-danger */
import React from 'react';
import Helmet from 'react-helmet';
export default class HTML extends React.Component {
static defaultProps = {
css: [],
scripts: [],
state: '{}',
};
render() {
const head = Helmet.renderStatic();
const { children, scripts, css, state } = this.props;
return (
<html lang="">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
{head.base.toComponent()}
{head.title.toComponent()}
{head.meta.toComponent()}
{head.link.toComponent()}
{head.script.toComponent()}
{css.map((href) => {
return <link key={href} href={href} rel="stylesheet" as="style" />;
})}
<script
dangerouslySetInnerHTML={{
__html: `window.__PRELOADED_STATE__ = ${state}`,
}}
/>
</head>
<body>
<div id="app" dangerouslySetInnerHTML={{ __html: children }} />
{scripts.map((src) => {
return <script key={src} src={src} async />;
})}
</body>
</html>
);
}
}
Конфигурация веб-пакета
const webpack = require('webpack');
const ManifestPlugin = require('webpack-manifest-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const Critters = require('critters-webpack-plugin');
// const HtmlWebpackPlugin = require('html-webpack-plugin');
/* const LoadablePlugin = require('@loadable/webpack-plugin');
const ChunkExtractor = require('@loadable/server');
const statsFile = path.resolve('../../rafikibuild/client/statics/loadable-stats.json'); */
const env = require('../env')();
const shared = [];
const client = [
// TODO: add client side only mode
// new HtmlWebpackPlugin({
// inject: true,
// template: paths.appHtml,
// }),
new CaseSensitivePathsPlugin(),
new webpack.DefinePlugin(env.stringified),
new webpack.DefinePlugin({
__SERVER__: 'false',
__BROWSER__: 'true',
}),
new MiniCssExtractPlugin({
filename:
process.env.NODE_ENV === 'development' ? '[name].css' : '[name].[contenthash].css',
chunkFilename:
process.env.NODE_ENV === 'development' ? '[id].css' : '[id].[contenthash].css',
}),
new Critters({
preload: 'swap',
preloadFonts: true,
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new ManifestPlugin({ fileName: 'manifest.json' }),
new CompressionPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8,
}),
];
const server = [
new webpack.DefinePlugin({
__SERVER__: 'true',
__BROWSER__: 'false',
}),
];
module.exports = {
shared,
client,
server,
};
Существует ли способ удаления стилей блокировки рендеринга на стороне рендеринга приложения React на стороне сервера?
Спасибо.