吐司问卷:性能优化

强化学习智能体学习过程可视化系统设计与实现 强化学习(Reinforcement Learning)作为一种试错驱动的决策建模方法,其核心挑战在于训练动态不可见、收敛机制不透明。理解智能体(Agent)如何从随机试探逐步构建策略,依赖对学习过程(Learning Process)中状态-动作价值、梯度演化与环境反馈的连续观测。本方案通过分层信号采集(环境层/智能体层/学习层)、毫秒级低延迟可视化(如Q值热力图+动态归一化)及内存映射回溯机制,将黑箱训练转化为可监控、可定位、可干预的工程闭环。适用于算法调试、教学演示与跨任务知识迁移分析等典型场景,尤其 阅读详情

吐司问卷:性能优化

Date: March 9, 2025 10:39 PM (GMT+8)


目标

  • 缓存数据,減少计算
  • 代码分析和拆分,优化首页代码体积

**注意事项:**优化要根据实际情况,不要先行优化




React 优化

要点:

  • 缓存数据,减少计算

useState 传入函数

要点:

  • useState 传入普通变量,每次组件更新都会执行
  • useState 传入函数,只在组件渲染时执行一次
  • 适合数据结构复杂、计算成本高的场景,

Case: useState 传入普通变量,每次组件更新都会执行

2025-03-09 23.29.35.gif

import React, { FC, useState } from 'react'

const Demo: FC = () => {
	console.log('Render');
	const [arr, setArr] = useState(['A', 'A', 'A'])
	const handleClick = () => {
		setArr(arr => [...arr, 'd'])
	}
	return (
		<div>
			<div>{arr}</div>
			<button onClick={handleClick}>add</button>
		</div>
	)
}

export default Demo

Case: useState 传入函数,只在组件渲染时执行一次

2025-03-09 23.38.10.gif

import React, { FC, useState } from 'react'

const genArr = () => {
	console.log('genArr...');
	const arr = Array(3).fill('A')
	return arr
}

const Demo: FC = () => {
	console.log('Render');
	const [arr, setArr] = useState(genArr)
	const handleClick = () => {
		setArr(arr => [...arr, 'd'])
	}
	return (
		<div>
			<div>{arr}</div>
			<button onClick={handleClick}>add</button>
		</div>
	)
}

export default Demo

理解:genArr 只在组件渲染时执行一次



useMemo

要点:

  • 函数组件,每次 state 更新都会重新执行函数
  • useMemo 可以缓存数据,不用每次执行函数都重新生成
  • 可用于计算量较大的场景,缓存提高性能

useMemo使用场景:

  • 依赖项不经常变化
  • 缓存的元素创建成本较高

Case: 二维码生成

image.png

比如生成二维码,依赖项为 id 和 isPublished,二维码的创建成本一般较高,就可以采用 useMemo

import React, { FC, useRef, useMemo } from 'react'
import {
  Space,
  Button,
  Typography,
  Input,
  InputRef,
  message,
  Popover,
} from 'antd'
import styles from './StatHeader.module.scss'
import { CopyOutlined, LeftOutlined, QrcodeOutlined } from '@ant-design/icons'
import useGetPageInfo from '../../../hooks/useGetPageInfo'
import { useNavigate, useParams } from 'react-router-dom'
import { QRCodeSVG } from 'qrcode.react'

const { Title } = Typography
const StatHeader: FC = () => {
  const { id } = useParams()
  const { title } = useGetPageInfo()
  const nav = useNavigate()
  const { isPublished } = useGetPageInfo()
  const urlInputRef = useRef<InputRef>(null)
  function copy() {
    const input = urlInputRef.current
    if (!input) return
    input.select()
    document.execCommand('copy')
    message.success('复制成功')
  }
  const LinkAndQRCodeElem = useMemo(() => {
    if (!isPublished) return null
    const url = `http://localhost:3000/questionnaire/${id}`
    const QRCodeElem = (
      <div style={{ textAlign: 'center' }}>
        <QRCodeSVG value={url} size={150} />
      </div>
    )
    return (
      <Space>
        <Input value={url} style={{ width: '300px' }} ref={urlInputRef} />
        <Button icon={<CopyOutlined />} onClick={copy}></Button>
        <Popover content={QRCodeElem}>
          <Button icon={<QrcodeOutlined />}></Button>
        </Popover>
      </Space>
    )
  }, [id, isPublished])

  return (
    <div className={styles['header-wrapper']}>
      <div className={styles.header}>
        <div className={styles.left}>
          <Space align="center">
            <Button type="link" icon={<LeftOutlined />} onClick={() => nav(-1)}>
              返回
            </Button>
            <Title>{title}</Title>
          </Space>
        </div>
        <div className={styles.main}>{LinkAndQRCodeElem}</div>
        <div className={styles.right}>
          <Button
            type="primary"
            onClick={() => {
              nav(`/question/edit/${id}`)
            }}
          >
            编辑问卷
          </Button>
        </div>
      </div>
    </div>
  )
}
export default StatHeader



useCallback

要点:

  • 和 useMemo 作用一样
  • 专门用于缓存函数

Case:

2025-02-14 23.29.16.gif

import React, { useState, memo, useMemo, useCallback } from 'react'

// 1-memo包裹子组件
const Child = memo(({ userInfo, onChange }) => {
  console.log('Child render')
  return (
    <div>
      <p>Name is {userInfo.name}</p>
      <input type="text" onChange={onChange} />
    </div>
  )
})

function App() {
  const [count, setCount] = useState(0)
  const [name, setName] = useState('Nathan')
  // 2-useMemo缓存数据
  const userInfo = useMemo(() => {
    return { name, age: 20 }
  }, [name])
  const handleChange = useCallback(e => {
    console.log('onChange', e.target.value)
  }, [])
  console.log('Parent render')
  return (
    <div>
      <p>Count is {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <Child userInfo={userInfo} onChange={handleChange} />
    </div>
  )
}

export default App

参考:React Hooks



React.memo

  • state 变化,组件会更新
  • 同时,子组件默认会“无脑”更新,无论 props 是否变化
  • 根要控制子组件更新,需使用 React.memo



优化代码体积

代码分析

要点:

  • 通过分析工具,分析各包的大小,并通过 Serve 查看对应包体积

笔记:

Source map explorer,分析 JavaScript 包。这有助于了解代码膨胀的来源。

npm install --save source-map-explorer

然后在 package.json 中,添加以下行到 scripts :

   "scripts": {
+    "analyze": "source-map-explorer 'build/static/js/*.js'",
     "start": "react-scripts start",
     "build": "react-scripts build",
     "test": "react-scripts test",

构建包 & 分析包:

npm run build
npm run analyze

参考文档:

https://create-react-app.dev/docs/analyzing-the-bundle-size


**打包资源图:**根据图分析如何进行拆包处理

image.png

分包前 main 包大小为 1.3MB

serve -s build

image.png



路由懒加载

目标:

  • 首页加载速度提升

分析:

资源图分析:@dnd-kit,recharts 资源体积占比很高,它仅用于统计分析页、编辑器。

而首页用不到这些功能,因此可以将它们拆分出去。

image.png

解决方案:

我们可以通过路由懒加载,拆分 bundle,以此优化首页体积。

index.tsx

// import Edit from '../pages/question/Edit'
// import Stat from '../pages/question/Stat'

const Edit = lazy(
  () => import(/* webpackChunkName: "editPage" */ '../pages/question/Edit')
)
const Stat = lazy(
  () => import(/* webpackChunkName: "statPage" */ '../pages/question/Stat')
)

进行打包与分析:

可以看到 main 包从 1.7 MB 降低到了 1.2 MB

npm run build

image.png

image.png



分包加载

目标:

  • 拆分 antd 和 react-dom

image.png


分析:

在资源图中,antd 和 react-dom 占比很高,我们考虑将其拆分出去。

思考:

  • andt、react-dom 包版本不常更新,可以拆分,并通过浏览器进行缓存

比如浏览器第一次请求服务器资源,会返回 src、antd、react-dom 等包。

浏览器将 antd、react-dom 缓存。之后,浏览器再次请求,服务端就不用发送这些包了。

image.png

  • 在生产环境应用以上规则

分包方式:

将包分成 src、antd、react-dom 以及第三包 这四种包

craco.config

webpack: {
  configure: webpackConfig => {
    // 生产环境:抽离公共代码
    if (webpackConfig.mode === 'production') {
      if (webpackConfig.optimization === null) {
        webpackConfig.optimization = {}
      }
      webpackConfig.optimization.splitChunks = {
        chunks: 'all',
        // 采用缓存,提高打包速度
        cacheGroups: {
          antd: {
            name: 'antdchunk',
            test: /antd/,
            priority: 100,
          },
          reactDom: {
            name: 'reactDom-chunk',
            test: /react-dom/,
            priority: 99,
          },
          // 第三方插件
          vendors: {
            name: 'vendors-chunk',
            test: /node_modules/,
            priority: 98,
          },
        },
      }
    }
    return webpackConfig
  },
},

npm run build 后可见分析(以下是压缩后):

File sizes after gzip:

  343.21 kB (+18.63 kB)  build/static/js/vendors-chunk.7bb93744.js
  138.79 kB (+400 B)     build/static/js/antdchunk.44c16e36.js
  41.45 kB               build/static/js/reactDom-chunk.1439cf47.js
  9.59 kB (+554 B)       build/static/js/main.29ab4e1f.js
  3.88 kB (+10 B)        build/static/js/editPage.b9332f3b.chunk.js
  3.36 kB (+38 B)        build/static/js/766.9f144573.chunk.js
  2.44 kB (-7 B)         build/static/js/statPage.85a628ec.chunk.js
  955 B                  build/static/css/editPage.2fabb9d5.chunk.css
  820 B                  build/static/css/main.d0183c63.css
  633 B (+34 B)          build/static/css/statPage.82d41fdf.chunk.css

分包后可见 main包为 26.3 KB :

image.png

资源图如下所示:

image.png

参考:

  • https://www.webpackjs.com/plugins/split-chunks-plugin/#root


CSS拆分

Craco 会自动根据路由来拆分css,所以以上路由懒加载实现后,Craco 已经拆分出 editPage、statPage 的 css 文件,如下所示:

File sizes after gzip:

  343.21 kB (+18.63 kB)  build/static/js/vendors-chunk.7bb93744.js
  138.79 kB (+400 B)     build/static/js/antdchunk.44c16e36.js
  41.45 kB               build/static/js/reactDom-chunk.1439cf47.js
  9.59 kB (+554 B)       build/static/js/main.29ab4e1f.js
  3.88 kB (+10 B)        build/static/js/editPage.b9332f3b.chunk.js
  3.36 kB (+38 B)        build/static/js/766.9f144573.chunk.js
  2.44 kB (-7 B)         build/static/js/statPage.85a628ec.chunk.js
  955 B                  build/static/css/editPage.2fabb9d5.chunk.css
  820 B                  build/static/css/main.d0183c63.css
  633 B (+34 B)          build/static/css/statPage.82d41fdf.chunk.css
webpack 多应用处理方案 webpack多页面处理方案说明先展示一下打包完毕的内容生产环境开发环境执行命令验证规则方案说明强调:这只是一种处理方式,多多自行研究与分享! 方案说明 前端工程多数是使用webpack来开发,那么问题来了,是一个前端工程就得搭建一个webpack项目吗?我是觉得没这必要,因为很多是固定不变的,如编译… 只是前端工程对应的业务不相同而已! 先展示一下打包完毕的内容 由上图可见,页面工程按模块区分... 阅读详情

相关推荐

Zabbix安装与部署 系统环境:centos7.0

Zabbix安装与部署 系统环境:centos7.0

weixin_42485027的博客 2600

Ant design pro部署到nginx

打包在ant design pro工程目录下,使用一条命令就可以打包:cnpm run build 返回结果> ant-design-pro@1.0.0 build D:\antd_prj > umi build Build completed in 58.478s DONE Compiled successfully in 58489ms ...

899

不止于ACC:用CarSim的‘Multiple Objects’和路径跟踪器玩转复杂交通流场景

本文深入探讨了如何利用CarSim的'Multiple Objects'模块和路径跟踪器模拟复杂交通流场景,超越传统ACC测试的局限。通过批量控制、动态交互和参数化设计,实现多车智能响应和复杂轨迹模拟,适用于连续变道、拥堵博弈、匝道汇流等真实交通场景。

weixin_30954265的博客 497

打包react项目

打包react项目 jim@MacBookPro ⮀ ~/Desktop/my-app ⮀ npm run build > my-app@0.1.0 build /Users/jim/Desktop/my-app > react-scripts build Creating an optimized production build... File sizes after gzi...

m0_37468171的博客 452

避坑指南:Unity新版InputSystem在移动端的5个常见问题及解决方案

本文针对Unity新版InputSystem在移动端开发中的常见问题,提供了5个关键解决方案,包括虚拟摇杆灵敏度调节、多点触控冲突处理、按钮反馈延迟优化、手势识别与陀螺仪数据融合以及Android/iOS平台差异处理。这些实战经验帮助开发者高效解决触控适配难题,提升移动游戏体验。

soda5的博客 405

【数据攻略】字节面试真题(含答案)+100道面试题库

数据攻略

qq_40002713的博客 4104

react-create-app项目解析一 build.js

react-create-app项目解析一 build.js

qq_33715850的博客 1842

西门子 S7-200 SMART 系列六:手把手教你配置S7-200 SMART Modbus RTU

最新发表:https://www.ics-pedia.com/%e8%a5%bf%e9%97%a8%e5%ad%90-s7-200-smart-%e7%b3%bb%e5%88%97%e5%85%ad%ef%bc%9a%e6%89%8b%e6%8a%8a%e6%89%8b%e6%95%99%e4%bd%a0%e9%85%8d%e7%bd%aes7-200-smart-modbus-rtu%e5%ae%9e%e4%be%8b/

John_09040211的博客 3282

webpack plugin 透过现象看本质

这是使用 vue-cli 编译过后的输出显示 是不是看起来不是很对你的胃口,是不是想改改样式看起来好看点,是不是想输出的内容丰富点,比如编译后的文件详情… 1改样式: 那么问题来了,如何找到这是在什么地方输出的,以及如何修改它: ...

qq_37653449的博客 1110

华为HCIP的学习大纲和计划

HCIP(华为认证 ICT 高级工程师)核心围绕华为 ICT 技术体系,不同方向(如路由交换、云计算、安全等)课程目录不同,以下是最热门的。

迷逝 576

pycharm下载continue插件接入DeepSeek的API,向其提问输出乱码,如何解决?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 2222

Tus系统:项目总结

这是一个全栈低代码项目,主要业务是问卷调查与统计,分成B端和C端: B端用于管理、编辑、统计问卷,C端用于用户填写问卷。 项目的技术栈有: 前端:React + Next 后端:Nest + MongoDB 测试:Jest + Storybook

CaptainDrake的博客 1045

Claude Code Auto Memory 的 Storage Location,SAP ABAP 项目里的本地记忆仓库应该怎么理解

本文介绍了 SAP ABAP 项目中 Claude Code 的 auto memory 机制,重点探讨了其存储位置的设计原理。auto memory 不是存储在项目目录中,而是默认位于 ~/.claude/projects/<project>/memory/,其中 <project> 基于 Git 仓库路径推导,确保同一仓库下的所有工作目录和分支共享记忆。记忆目录包含入口文件 MEMORY.md(仅加载前 200 行)和详细主题文件,这种分层设计类似 CDS View 架构思想。文章还分析了按 Git 仓

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 101

UmiJS可插拔的企业级 react 应用框架,配合ant-design-pro使用

入门非常简单 # 安装 $ yarn global add umi # 或者 npm install -g umi # 新建应用 $ mkdir myapp && cd myapp # 新建页面 $ umi generate page index # 本地开发 $ umi dev # 构建上线 $ umi build 介绍 ...

浩秦的博客 716

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

给webpack打包添加打包时间

原因 正常情况下构建的工程,一般都会自带这些信息参数,但是遇到一个老项目,并没时间参数,在做打包优化的过程中,都看不到打包时间,所以需要自己补上 代码 打包代码的核心代码中有个stats参数,里边就有startTime,endTime 属性,我们简单加工一下 新增的打包时间代码 // 打包时间 const times = stats.endTime - stats.startTime; const minute = Math.floor(times / 1000 / 60); con

qq_36990322的博客 4407

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

gzip文件格式解析

在windows下使用UltraEdit打开后缀的.gz的文件显示的数据格式如下: 2 bytes  GZIP标志字节:0x1f, 0x8b (\037 \213)   1 byte   压缩方法: (0..7 reserved, 8 = deflate) 1 byte   标志位:             bit 0 set: 文件可能是ASCII文本文件             bi

Mrknowledge 1万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Gzip格式分析

GZIP文件格式简介 GZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNIX系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet上使用非常普遍的一种数据压缩格式,或者说一种文件格式。HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来让用

stonesharp的专栏 3495

关于reactjs在windows环境中使用npm run build之后,打开网页显示为空白的解决方案

刚开始学react时候,跟着官网的操作:npx create-react-app my-app cd my-app npm start构建完这个初始的项目之后,发现项目是可以正常正常访问的!然后接着就是发布上线npx run build但是发现直接打开index.html界面是一片空白这个时候我们看build的过程中的信息&gt; my-app@0.1.0 build D:\Program Fil...

xzp_forever的博客 1万+

Angular vs React vs Vue vs UISYS 的搭建及发布对比(2020年最新最全)

本文讲解 在不报培训班的情况下,如何快速入门WEB开发。 这篇文章新手不要妄想一次看完,慢慢看,可以收藏起来,一天看一个,然后实战一个。 一、难点 WEB前端开发,新手最蛋痛的莫过于如何部署发布网站,全都是各种服务配置,还得学习windows server、linux等等。 更蛋痛的是学习WEB三大框架的时候还得搭建各种脚手架、编辑器、编辑器插件、破解一些问题。“满脑子都是问号和啥也不...

超级太空人的博客 1664

webpack学习之对比 umi 和 create-react-app的打包流程和优化配置

[toc] 对外配置文件对比 umi .umirc.js // ref: https://umijs.org/config/ export default { treeShaking: true, plugins: [ // ref: https://umijs.org/plugin/umi-plugin-react.html ['umi-plugin-react', { ...

weixin_33801856的博客 4484

react开发项目linux上线,使用nginx部署react项目

一、环境准备1.安装node和yarn开始部署react前需要安装node和yarn,可以参考这里安装node和yarn。2.安装nginx二、部署构建Reat项目1.下载源代码并解压wget https://github.com/mdnice/markdown-nice/archive/master.zipunzip master.zipcd markdown-nice-master/123wg...

weixin_33279929的博客 2220

dva学习笔记一:快速上手

来源:https://dvajs.com/guide/getting-started.html 一、dva简介 dva是一个轻量级的应用框架,基于redux和redux-saga,内置react-router和fetch,是一个数据流方案,可以简化开发。由蚂蚁金服团队开源提供及维护(https://dvajs.com/)。 二、安装工具 通过npm进行安装:npm install dva-...

听樱桃在哭的博客 1768

Chrome 性能优化实战指南:2026 前端页面提速与内存优化全攻略

2026年Chrome已切换为双周更新节奏,页面性能优化规则也随之迭代。本文详解Chrome性能面板高级用法、内存泄漏排查、渲染路径优化与最新API落地技巧,帮助你把页面首屏速度提升50%以上。

Frag0ut的博客 327

闪控窗性能优化与多实例资源治理【鸿蒙心迹】

本文是闪控窗系列第三篇,聚焦**多实例场景下的资源治理**。针对用户高频开关、多任务切换导致闪控窗实例越攒越多、内存与绘制开销失控的问题,给出"实例有上限、绘制会节流、销毁能统一"的完整方案:用全局单例 `FloatMgr` 统筹实例,设硬上限(建议 3 个)并淘汰最旧;用空闲实例池复用避免频繁 create/destroy;用 `Animator` 把静止态刷新压到 1fps 甚至停更;页面销毁与退后台统一 `releaseAll`,并配合 5 分钟超时回收。

wdracky的专栏 303

AI 应用开发工程师技术实践:大模型接入、通用组件封装与性能优化

本文提出AI应用从PoC到生产的核心挑战:模型调用的持续可用、可控与可优化。通过构建统一LLM网关实现多供应商路由与故障转移,封装对话、工具调用与RAG组件以解耦业务逻辑,结合前缀缓存、批处理与流式背压治理等性能优化手段,形成“接通→接稳→接快”的工程路径,最终以工程化能力决定AI应用的生产可用性。

2301_79189962的博客 579
上一篇: 吐司问卷(React低代码):用户登陆模块实现
下一篇: Tus系统:项目总结
CaptainDrake
博客等级 码龄6年 5363粉丝 187原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值