Closed kamilmielnik closed 1 year ago
Also:
useMedia
When server side rendering, defaultState should be defined to prevent a hydration mismatches.
react-use
's useMeasure
causes rerenders as the size object reference can change even though the size did not.
The hook could be wrapped and memoized with a custom equality comparison, but I'm a bit tired with react-use
now. It's too big, and I don't use that much of it. I'll remove it.
This is the solution: https://github.com/pmndrs/react-use-measure
npm install @welldone-software/why-did-you-render --save-dev
diff --git a/packages/scrabble-solver/next.config.js b/packages/scrabble-solver/next.config.js
index 08b88d5f..4ae92a27 100644
--- a/packages/scrabble-solver/next.config.js
+++ b/packages/scrabble-solver/next.config.js
@@ -20,35 +20,58 @@ module.exports = {
buildActivity: false,
},
reactStrictMode: true,
- webpack: (config) => ({
- ...config,
- resolve: {
- ...config.resolve,
- alias: {
- ...config.resolve.alias,
- ...tsConfigAliases,
- },
- },
- module: {
- ...config.module,
- rules: [
- ...config.module.rules,
- {
- test: /\.svg$/,
- issuer: /\.tsx?$/,
- use: ['@svgr/webpack'],
+ webpack: (config, { dev, isServer }) => {
+ if (dev && !isServer) {
+ const originalEntry = config.entry;
+ config.entry = async () => {
+ const wdrPath = path.resolve(__dirname, './src/wdyr.ts');
+ const entries = await originalEntry();
+
+ if (entries['main.js'] && !entries['main.js'].includes(wdrPath)) {
+ entries['main.js'].push(wdrPath);
+ }
+ return entries;
+ };
+ }
+
+ return {
+ ...config,
+ resolve: {
+ ...config.resolve,
+ alias: {
+ ...config.resolve.alias,
+ ...tsConfigAliases,
},
- ],
- },
- plugins: [
- ...config.plugins,
- process.env.NODE_ENV === 'production'
- ? new WorkboxPlugin.InjectManifest({
- swSrc: path.join(__dirname, 'src/service-worker/index.ts'),
- swDest: path.join(__dirname, 'public/service-worker.js'),
- exclude: [/\.map$/, /\.next/, /_next/, /manifest/, /\.htaccess$/, /.*\/static\/.*/, /service-worker\.js$/],
- })
- : undefined,
- ].filter(Boolean),
- }),
+ },
+ module: {
+ ...config.module,
+ rules: [
+ ...config.module.rules,
+ {
+ test: /\.svg$/,
+ issuer: /\.tsx?$/,
+ use: ['@svgr/webpack'],
+ },
+ ],
+ },
+ plugins: [
+ ...config.plugins,
+ process.env.NODE_ENV === 'production'
+ ? new WorkboxPlugin.InjectManifest({
+ swSrc: path.join(__dirname, 'src/service-worker/index.ts'),
+ swDest: path.join(__dirname, 'public/service-worker.js'),
+ exclude: [
+ /\.map$/,
+ /\.next/,
+ /_next/,
+ /manifest/,
+ /\.htaccess$/,
+ /.*\/static\/.*/,
+ /service-worker\.js$/,
+ ],
+ })
+ : undefined,
+ ].filter(Boolean),
+ };
+ },
};
diff --git a/packages/scrabble-solver/src/pages/_app.tsx b/packages/scrabble-solver/src/pages/_app.tsx
index 4c77a772..a1218ece 100644
--- a/packages/scrabble-solver/src/pages/_app.tsx
+++ b/packages/scrabble-solver/src/pages/_app.tsx
@@ -3,6 +3,8 @@ import Head from 'next/head';
import { FunctionComponent } from 'react';
import { Provider } from 'react-redux';
+import '../wdyr';
+
import { SeoMessage } from 'components';
import { createAppStore } from 'state';
diff --git a/packages/scrabble-solver/src/pages/index.tsx b/packages/scrabble-solver/src/pages/index.tsx
index a439bb8c..8c8e0615 100644
--- a/packages/scrabble-solver/src/pages/index.tsx
+++ b/packages/scrabble-solver/src/pages/index.tsx
@@ -4,7 +4,8 @@ import path from 'path';
import { FunctionComponent, useEffect, useState } from 'react';
import ReactModal from 'react-modal';
import { useDispatch } from 'react-redux';
-import { useEffectOnce, useMeasure } from 'react-use';
+import { useEffectOnce } from 'react-use';
+import useMeasure from 'react-use-measure';
import { Logo, LogoSplashScreen, NavButtons, Solver, SvgFontFix } from 'components';
import { useAppLayout, useDirection, useLanguage, useLocalStorage } from 'hooks';
@@ -42,12 +43,14 @@ const Index: FunctionComponent<Props> = ({ version }) => {
const [showSettings, setShowSettings] = useState(false);
const [showWords, setShowWords] = useState(false);
const [isInitialized, setIsInitialized] = useState(false);
- const [indexRef, { height: indexHeight, width: indexWidth }] = useMeasure<HTMLDivElement>();
- const [navRef, { height: navHeight }] = useMeasure<HTMLElement>();
+ const [indexRef, { height: indexHeight, width: indexWidth }] = useMeasure();
+ const [navRef, { height: navHeight }] = useMeasure();
const solverHeight = indexHeight - navHeight;
const solverWidth = indexWidth;
const [isClient, setIsClient] = useState(false);
+ console.log('render Index');
+
const handleClear = () => {
dispatch(reset());
};
@@ -151,3 +154,5 @@ const readVersion = async (): Promise<string> => {
};
export default Index;
+
+Index.whyDidYouRender = true;
diff --git a/packages/scrabble-solver/tsconfig.json b/packages/scrabble-solver/tsconfig.json
index 0455aaf2..087a514b 100644
--- a/packages/scrabble-solver/tsconfig.json
+++ b/packages/scrabble-solver/tsconfig.json
@@ -28,7 +28,8 @@
"rootDir": "./src",
"skipLibCheck": true,
"typeRoots": ["./node_modules/@types", "./src/@types"],
- "incremental": true
+ "incremental": true,
+ "jsxImportSource": "@welldone-software/why-did-you-render"
},
"exclude": ["node_modules"],
"files": ["./src/@types/scss.d.ts", "./src/@types/svg.d.ts"],
TODO:
BORDER_WIDTH
)2 renders are left. The second one is because of isClient
- it's needed as there is no viewport size information on the server, so SSR is pointless as it's never going to match anyway.
This is what currently affects the lighthouse score the most. Ideally the splash screen is not required anymore.