feat: 增加性能埋点统计

pull/13/head
moonrailgun 4 years ago
parent 11c5c42e15
commit 312d96fb7a

@ -32,6 +32,7 @@
"k3fe97dcc": "System settings",
"k41064134": "DM",
"k419da0ef": "Message explanation",
"k4231ab36": "Performance statistics",
"k424be044": "This invite expired in <2>{{date}}</2>",
"k42a44318": "Joined",
"k42a98418": "File Service",

@ -32,6 +32,7 @@
"k3fe97dcc": "系统设置",
"k41064134": "私信",
"k419da0ef": "消息解释",
"k4231ab36": "性能统计",
"k424be044": "该邀请将于 <2>{{date}}</2> 过期",
"k42a44318": "已加入",
"k42a98418": "文件服务",

@ -6,6 +6,7 @@ import { Loadable } from './components/Loadable';
import { ConfigProvider as AntdProvider } from 'antd';
import { parseColorScheme } from './utils/color-scheme-helper';
import { Helmet } from 'react-helmet';
import { useRecordMeasure } from './utils/measure-helper';
const MainRoute = Loadable(() =>
import('./routes/Main').then((module) => module.MainRoute)
@ -44,7 +45,7 @@ const AppProvider: React.FC = React.memo((props) => {
});
AppProvider.displayName = 'AppProvider';
export const AppContainer: React.FC = React.memo((props) => {
const AppContainer: React.FC = React.memo((props) => {
const { colorScheme } = useColorScheme();
const { isDarkMode, extraSchemeName } = parseColorScheme(colorScheme);
@ -77,6 +78,8 @@ const AppHeader: React.FC = React.memo(() => {
AppHeader.displayName = 'AppHeader';
export const App: React.FC = React.memo(() => {
useRecordMeasure('AppRenderStart');
return (
<AppProvider>
<AppHeader />

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

@ -4,6 +4,7 @@ import React, { useCallback, useMemo } from 'react';
import { t } from 'tailchat-shared';
import { SettingsAbout } from './About';
import { SettingsAccount } from './Account';
import { SettingsPerformance } from './Performance';
import { SettingsStatus } from './Status';
import { SettingsSystem } from './System';
@ -41,6 +42,11 @@ export const SettingsView: React.FC<SettingsViewProps> = React.memo((props) => {
title: t('服务状态'),
content: <SettingsStatus />,
},
{
type: 'item',
title: t('性能统计'),
content: <SettingsPerformance />,
},
{
type: 'item',
title: t('关于'),

@ -1,8 +1,10 @@
import { isDevelopment, request, version } from 'tailchat-shared';
import { measure } from './utils/measure-helper';
if (isDevelopment === true) {
(window as any).DEBUG = {
request,
version,
measure,
};
}

@ -6,8 +6,11 @@ import clsx from 'clsx';
import styles from './index.module.less';
import loginPatternUrl from '@assets/images/login-pattern.svg';
import { RegisterView } from './RegisterView';
import { useRecordMeasure } from '@/utils/measure-helper';
export const EntryRoute = React.memo(() => {
useRecordMeasure('AppEntryRenderStart');
return (
<div className="h-full flex flex-row">
<div

@ -5,12 +5,14 @@ import { InviteInfo } from './InviteInfo';
import bgImage from '@assets/images/bg.jpg';
import { JoinBtn } from './JoinBtn';
import { PortalHost } from '@/components/Portal';
import { useRecordMeasure } from '@/utils/measure-helper';
/**
*
*/
export const InviteRoute: React.FC = React.memo(() => {
const { inviteCode } = useParams<{ inviteCode: string }>();
useRecordMeasure('AppInviteRenderStart');
return (
<PortalHost>

@ -1,9 +1,12 @@
import { useRecordMeasure } from '@/utils/measure-helper';
import React from 'react';
import { MainContent } from './Content';
import { Navbar } from './Navbar';
import { MainProvider } from './Provider';
export const MainRoute: React.FC = React.memo(() => {
useRecordMeasure('AppMainRenderStart');
return (
<div className="flex h-full">
<MainProvider>

@ -0,0 +1,60 @@
import { useLayoutEffect } from 'react';
const records: Record<string, number> = {};
/**
*
* @param name
*/
export function recordMeasure(name: string) {
if (!records[name]) {
records[name] = performance.now();
}
}
/**
* (hook)
* @param name
*/
export function useRecordMeasure(name: string) {
useLayoutEffect(() => {
recordMeasure(name);
}, []);
}
export const measure = {
getRecord: () => ({ ...records }),
getTimeUsage() {
let t = performance.timing;
const usage = {
// DNS查询耗时
dnsUsage: t.domainLookupEnd - t.domainLookupStart,
// TCP链接耗时
tcpUsage: t.connectEnd - t.connectStart,
// request请求耗时
requestUsage: t.responseEnd - t.responseStart,
// 解析dom树耗时
parseDOMUsage: t.domComplete - t.domInteractive,
// 白屏时间
firstPaintTime: t.responseStart - t.navigationStart,
// domready时间
domReadyTime: t.domContentLoadedEventEnd - t.navigationStart,
// onload 时间
onloadTime: t.loadEventEnd - t.navigationStart,
};
if ((t = performance.memory)) {
// js内存使用占比
usage['jsHeapRatio'] = t.usedJSHeapSize / t.totalJSHeapSize;
}
return usage;
},
};
Loading…
Cancel
Save