/online-account

一个在线记账网站

Primary LanguageTypeScript

在线记账系统

项目结构:

│  App.css
│  App.tsx
│  constans.ts
│  index.tsx
│  react-app-env.d.ts
│  setupTests.ts
│
├─components
│  ├─animateNumber
│  │      AnimateNumber.tsx
│  │
│  ├─icon
│  │      Icon.css
│  │      Icon.tsx
│  │
│  ├─localDatePicker
│  │      LoaclDatePicker.css
│  │      LocalDatePicker.tsx
│  │
│  ├─logo
│  │      Logo.css
│  │      Logo.tsx
│  │
│  ├─mainLayout
│  │      MainLayout.css
│  │      MainLayout.tsx
│  │
│  └─provider
│      │  Provider.tsx
│      │
│      └─reducer
│              action.ts
│              asyncActions.ts
│              reducer.ts
│              useCustomizedReducer.ts
│
├─pages
│  ├─chart
│  │  │  ChartPage.css
│  │  │  ChartPage.tsx
│  │  │
│  │  └─components
│  │      ├─linechart
│  │      │      lineChartInMonth.tsx
│  │      │
│  │      └─piechart
│  │              pieChartInMonth.tsx
│  │
│  └─detail
│      │  DetailPage.css
│      │  DetailPage.tsx
│      │
│      └─components
│          ├─dailyRecord
│          │      DailyRecords.css
│          │      DailyRecords.tsx
│          │
│          ├─record
│          │      Record.css
│          │      Record.tsx
│          │
│          └─recordModal
│                  RecordModal.css
│                  RecordModal.tsx
│
└─services
    │  client.ts
    │  dateHelper.ts
    │  recordHelpler.ts
    │  router.tsx
    │
    └─iconSelector
            iconSelector.ts

优化之路

  1. 输入框数据类型

  在新建账单的输入框把金额减到零,发现控制台warningThe specified value “NaN” cannot be parsed, or is out of range。发现是输入框解析undefined异常的问题,遂把记录价格的price属性改成string类型,解决了问题。

  1. First Contentful Paint

    使用Lighthouse生成性能报告,发现FCP很高

优化前

  遂采取其提供的建议"If you are not server-side rendering, split your JavaScript bundles with React.lazy(). Otherwise, code-split using a third-party library such as loadable-components.",依据官方文档对antd进行了按需加载优化,并使用React.lazy()让图表分页懒加载,达到了一定的优化效果:

优化后

  1. Layout Shift

  每次刷新页面,都能感到有什么东西闪了一下,遂用perfomance录制页面加载过程并分析,发现页面存在一个虽然只有33.4ms,但是看起来很明显的Layout Shift:

Layout Shift

相关元素:summary

  起初以为是content的高度问题,经查找发现并不是,后通过改变各种CSS属性并观察效果,确信应该是渲染过程中Sider的宽度被Content无视了,因为项目布局是采用了antd的Layout组件,于是我仔细查看antd的Layout文档,这才发现有个提示:

遂给Layout加了个属性hasSider = {true},问题就这么解决了。这个问题不像应该官方文档说的这样,只有服务端渲染才会出现。

  1. 还是Layout Shift

当统计金额增加时,金额会瞬间变为目标值,进位(长度增加)时更是会导致同在一个flex box的title移位,这个问题在首屏加载时很明显:

打开Layout Shift Regions可以看到被标记的蓝色区域:

  经过对CSS的检查,我发现了问题所在,我之前的思路是把月份选择器用flex-basis固定宽度,把右边俩Statistic组件都设置为flex-grow: 1来平分剩下的宽度。然而,随着数字长度的增加,宽度的分配会有所改变,从而造成移位,故把样式改为三个组件宽度均为flex-basis: 34%,达到固定位置的目的。

  顺便引入useAnimateNumber,给统计数字加了个滚动递增的效果。

优化后:

Layout Shift直接归零,看起来流畅多了。