perf: 增加更多的性能埋点与报告

pull/64/head
moonrailgun 2 years ago
parent 66d2b91654
commit ed06245a64

@ -64,6 +64,7 @@
"tailchat-shared": "*", "tailchat-shared": "*",
"tailwindcss": "^2.2.4", "tailwindcss": "^2.2.4",
"url": "^0.11.0", "url": "^0.11.0",
"web-vitals": "^3.1.0",
"yup": "^0.32.9", "yup": "^0.32.9",
"zustand": "^4.1.2" "zustand": "^4.1.2"
}, },

@ -77,7 +77,7 @@ const AppHeader: React.FC = React.memo(() => {
AppHeader.displayName = 'AppHeader'; AppHeader.displayName = 'AppHeader';
export const App: React.FC = React.memo(() => { export const App: React.FC = React.memo(() => {
useRecordMeasure('AppRenderStart'); useRecordMeasure('appRenderStart');
return ( return (
<AppProvider> <AppProvider>

@ -2,8 +2,9 @@ import { measure } from '@/utils/measure-helper';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
export const SettingsPerformance: React.FC = React.memo(() => { export const SettingsPerformance: React.FC = React.memo(() => {
const { record, timeUsage } = useMemo( const { vitals, record, timeUsage } = useMemo(
() => ({ () => ({
vitals: measure.getVitals(),
record: measure.getRecord(), record: measure.getRecord(),
timeUsage: measure.getTimeUsage(), timeUsage: measure.getTimeUsage(),
}), }),
@ -12,22 +13,34 @@ export const SettingsPerformance: React.FC = React.memo(() => {
return ( return (
<div> <div>
<div className="mb-4">
<div>Vitals:</div>
<div className="rounded bg-black bg-opacity-10 p-2">
{Object.entries(vitals).map(([n, t]) => (
<div key={n}>
{n}: {t}ms
</div>
))}
</div>
</div>
<div className="mb-4"> <div className="mb-4">
<div>Record:</div> <div>Record:</div>
<div className="rounded bg-black bg-opacity-10 p-2"> <div className="rounded bg-black bg-opacity-10 p-2">
{Object.entries(record).map(([n, t]) => ( {Object.entries(record).map(([n, t]) => (
<div key={n}> <div key={n}>
{n}: {t} {n}: {t}ms
</div> </div>
))} ))}
</div> </div>
</div> </div>
<div> <div>
<div>TimeUsage:</div> <div>TimeUsage:</div>
<div className="rounded bg-black bg-opacity-10 p-2"> <div className="rounded bg-black bg-opacity-10 p-2">
{Object.entries(timeUsage).map(([n, t]) => ( {Object.entries(timeUsage).map(([n, t]) => (
<div key={n}> <div key={n}>
{n}: {t} {n}: {t}ms
</div> </div>
))} ))}
</div> </div>

@ -6,13 +6,16 @@ import { App } from './App';
import { initPlugins } from './plugin/loader'; import { initPlugins } from './plugin/loader';
import { installServiceWorker } from './utils/sw-helper'; import { installServiceWorker } from './utils/sw-helper';
import { showErrorToasts, t } from 'tailchat-shared'; import { showErrorToasts, t } from 'tailchat-shared';
import { recordMeasure } from './utils/measure-helper';
import './styles'; import './styles';
installServiceWorker(); installServiceWorker();
// 先加载插件再开启应用 // 先加载插件再开启应用
recordMeasure('initPluginsStart');
initPlugins() initPlugins()
.then(() => { .then(() => {
recordMeasure('initPluginsEnd');
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const root = createRoot(document.querySelector('#app')!); const root = createRoot(document.querySelector('#app')!);
root.render( root.render(

@ -18,6 +18,9 @@ import {
import { getPopupContainer } from './utils/dom-helper'; import { getPopupContainer } from './utils/dom-helper';
import { getUserJWT } from './utils/jwt-helper'; import { getUserJWT } from './utils/jwt-helper';
import _get from 'lodash/get'; import _get from 'lodash/get';
import { recordMeasure } from './utils/measure-helper';
recordMeasure('init');
if (isDevelopment) { if (isDevelopment) {
import('source-ref-runtime').then(({ start }) => start()); import('source-ref-runtime').then(({ start }) => start());

@ -10,7 +10,7 @@ import { GuestView } from './GuestView';
import { ForgetPasswordView } from './ForgetPasswordView'; import { ForgetPasswordView } from './ForgetPasswordView';
const EntryRoute = React.memo(() => { const EntryRoute = React.memo(() => {
useRecordMeasure('AppEntryRenderStart'); useRecordMeasure('appEntryRenderStart');
return ( return (
<div className="h-full flex flex-row"> <div className="h-full flex flex-row">

@ -9,7 +9,7 @@ import { useRecordMeasure } from '@/utils/measure-helper';
*/ */
const InviteRoute: React.FC = React.memo(() => { const InviteRoute: React.FC = React.memo(() => {
const { inviteCode = '' } = useParams<{ inviteCode: string }>(); const { inviteCode = '' } = useParams<{ inviteCode: string }>();
useRecordMeasure('AppInviteRenderStart'); useRecordMeasure('appInviteRenderStart');
return ( return (
<PortalHost> <PortalHost>

@ -7,7 +7,7 @@ import { MainProvider } from './Provider';
import { useShortcuts } from './useShortcuts'; import { useShortcuts } from './useShortcuts';
const MainRoute: React.FC = React.memo(() => { const MainRoute: React.FC = React.memo(() => {
useRecordMeasure('AppMainRenderStart'); useRecordMeasure('appMainRenderStart');
useShortcuts(); useShortcuts();
return ( return (

@ -21,7 +21,7 @@ const GroupDetailRoute = React.memo(() => {
GroupDetailRoute.displayName = 'GroupDetailRoute'; GroupDetailRoute.displayName = 'GroupDetailRoute';
const PanelRoute: React.FC = React.memo(() => { const PanelRoute: React.FC = React.memo(() => {
useRecordMeasure('AppRouteRenderStart'); useRecordMeasure('appRouteRenderStart');
return ( return (
<div className="flex h-full bg-content-light dark:bg-content-dark"> <div className="flex h-full bg-content-light dark:bg-content-dark">

@ -1,7 +1,22 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable @typescript-eslint/ban-ts-comment */
import { useLayoutEffect } from 'react'; import { useEffect, useLayoutEffect } from 'react';
import { Metric, onCLS, onFCP, onFID, onINP, onLCP, onTTFB } from 'web-vitals';
const records: Record<string, number> = {}; const records: Record<string, number> = {};
const vitals: Record<string, number> = {};
const handleVitalsCb = (metric: Metric) => {
if (!vitals[metric.name]) {
vitals[metric.name] = metric.value;
}
};
onCLS(handleVitalsCb);
onFCP(handleVitalsCb);
onFID(handleVitalsCb);
onINP(handleVitalsCb);
onLCP(handleVitalsCb);
onTTFB(handleVitalsCb);
/** /**
* *
@ -9,6 +24,8 @@ const records: Record<string, number> = {};
*/ */
export function recordMeasure(name: string) { export function recordMeasure(name: string) {
if (!records[name]) { if (!records[name]) {
// 首次进入
performance.mark(`tailchat:${name}`);
records[name] = performance.now(); records[name] = performance.now();
} }
} }
@ -21,9 +38,14 @@ export function useRecordMeasure(name: string) {
useLayoutEffect(() => { useLayoutEffect(() => {
recordMeasure(name); recordMeasure(name);
}, []); }, []);
useEffect(() => {
recordMeasure(name + 'Mounted');
}, []);
} }
export const measure = { export const measure = {
getVitals: () => ({ ...vitals }),
getRecord: () => ({ ...records }), getRecord: () => ({ ...records }),
getTimeUsage() { getTimeUsage() {
let t = performance.timing; let t = performance.timing;

@ -421,6 +421,7 @@ importers:
typescript: ^4.5.2 typescript: ^4.5.2
url: ^0.11.0 url: ^0.11.0
url-loader: ^4.1.1 url-loader: ^4.1.1
web-vitals: ^3.1.0
webpack: 5.73.0 webpack: 5.73.0
webpack-bundle-analyzer: ^4.5.0 webpack-bundle-analyzer: ^4.5.0
webpack-cli: ^4.9.1 webpack-cli: ^4.9.1
@ -471,6 +472,7 @@ importers:
tailchat-shared: link:../shared tailchat-shared: link:../shared
tailwindcss: 2.2.19_ywsstkkounrjlah5ti55snp2aq tailwindcss: 2.2.19_ywsstkkounrjlah5ti55snp2aq
url: 0.11.0 url: 0.11.0
web-vitals: 3.1.0
yup: 0.32.11 yup: 0.32.11
zustand: 4.1.2_react@18.2.0 zustand: 4.1.2_react@18.2.0
devDependencies: devDependencies:
@ -11760,7 +11762,7 @@ packages:
babel-plugin-syntax-jsx: 6.18.0 babel-plugin-syntax-jsx: 6.18.0
lodash: 4.17.21 lodash: 4.17.21
picomatch: 2.3.1 picomatch: 2.3.1
styled-components: 5.3.6_react@18.2.0 styled-components: 5.3.6_7i5myeigehqah43i5u7wbekgba
/babel-plugin-syntax-jsx/6.18.0: /babel-plugin-syntax-jsx/6.18.0:
resolution: {integrity: sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==} resolution: {integrity: sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==}
@ -19626,7 +19628,7 @@ packages:
pretty-format: 27.5.1 pretty-format: 27.5.1
slash: 3.0.0 slash: 3.0.0
strip-json-comments: 3.1.1 strip-json-comments: 3.1.1
ts-node: 10.9.1_k2dsl7zculo2nmh5s33pladmoa ts-node: 10.9.1_bqee57coj3oib6dw4m24wknwqe
transitivePeerDependencies: transitivePeerDependencies:
- bufferutil - bufferutil
- canvas - canvas
@ -29104,7 +29106,6 @@ packages:
react-is: 18.2.0 react-is: 18.2.0
shallowequal: 1.1.0 shallowequal: 1.1.0
supports-color: 5.5.0 supports-color: 5.5.0
dev: false
/styled-components/5.3.6_mdz3marskokvq6744hhidi3r5a: /styled-components/5.3.6_mdz3marskokvq6744hhidi3r5a:
resolution: {integrity: sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg==} resolution: {integrity: sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg==}
@ -29150,6 +29151,7 @@ packages:
react: 18.2.0 react: 18.2.0
shallowequal: 1.1.0 shallowequal: 1.1.0
supports-color: 5.5.0 supports-color: 5.5.0
dev: true
/styled-system/5.1.5: /styled-system/5.1.5:
resolution: {integrity: sha512-7VoD0o2R3RKzOzPK0jYrVnS8iJdfkKsQJNiLRDjikOpQVqQHns/DXWaPZOH4tIKkhAT7I6wIsy9FWTWh2X3q+A==} resolution: {integrity: sha512-7VoD0o2R3RKzOzPK0jYrVnS8iJdfkKsQJNiLRDjikOpQVqQHns/DXWaPZOH4tIKkhAT7I6wIsy9FWTWh2X3q+A==}
@ -31540,6 +31542,10 @@ packages:
/web-namespaces/1.1.4: /web-namespaces/1.1.4:
resolution: {integrity: sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==} resolution: {integrity: sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==}
/web-vitals/3.1.0:
resolution: {integrity: sha512-zCeQ+bOjWjJbXv5ZL0r8Py3XP2doCQMZXNKlBGfUjPAVZWokApdeF/kFlK1peuKlCt8sL9TFkKzyXE9/cmNJQA==}
dev: false
/webidl-conversions/3.0.1: /webidl-conversions/3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}

Loading…
Cancel
Save