Blog
Blog copied to clipboard
记录一次有意义的页面和代码优化
为何写这个文章
很少有时间对于写过的代码重构 这次发现重构是真的很有意思的事情 所以就记录下来了
modal的fifo应用
集卡属于互动类型的游戏,此页面有9个弹窗,其中有同时出现的5个弹窗的情况,且如果同时出现必须按照指定顺序弹出。
遇到复杂的交互逻辑,数据结构可以帮助理清思路,抽象逻辑,完成稳定可靠的代码。在这次交互中,弹框要一个个按照顺序弹出,可以虑有序队列。但是弹框的弹出和关闭属于事件。在上一个弹框弹出关闭后,触发下一个弹框弹出。可以考虑事件的发布订阅。
队列图解
队列 是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(end)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队首。
弹窗和队列结合
队列的弹窗展示有三个状态
- 同一时间段只有一个弹窗触发
- 同一时间段有两个或多个弹窗出发
- 一个弹窗在展示过程中,另一个弹窗要触发
整体逻辑分析如下图
用法
import { push } from "./utils"
push(MODAL_TYPE.GIVE_CARD)
push(MODAL_TYPE.ASSIST_CARD)
push(MODAL_TYPE.BUY_CARD)
push(MODAL_TYPE.TASK_CARD)
setTimeOut(()=>{
push(MODAL_TYPE.RECEIVE_CARD)
},1000)
setTimeOut(()=>{
push(MODAL_TYPE.ASSIST_CARD)
},4000)
结果
创建enum管理状态
游戏状态多意味着常量多,好的代码最好是不写注释也一目了然。如果可以把注释通过代码表示出来那就太棒了,限制维护者强制书写注释那就更好了。
代码抽离和模块划分
优化后的代码index.js减少了500行左右的代码
我的处理是
- 先进行模块划分,把this.renderXXX里的代码放入components里让整体逻辑分离更清晰,把只和子组建相关的逻辑全部移除到子组建中
- 首页的ajax多个请求合并,把index.js和store内都会用到的请求都组合再一起,对整体页面init的逻辑整合
- 此时再整理首页里面的各种 状态控制锁。将状态控制锁放入constant里。只需要根据不同状态进入不同的组建即可,进行整体的逻辑整合。因为原来的逻辑是 user的状态有4中,活动的状态有4中。这样的排列组合就有16中。需要把这么多排列组合分别在首页逻辑中判断是很复杂的。这里可以考虑根据展示结果判断。同样的展示结果对应哪几种user和activity状态判断组合在一起。后期增加游戏状态时候,只需要再加一个状态和对应的组建即可,也无惧user和活动状态的多变性
- 分离出ui组建和容器组建
- UI组件:只负责页面的渲染
- 容器组件:只负责业务逻辑和数据的处理,要保证组建功能的完整性,与父组建的交互只需给出回调的callback。与父组建无关的逻辑就封闭起来。
- 对觉得已经不满足后期维护需求,承载负荷过重的代码进行重构。此时代码已经解耦,重构起来会是一件快乐和容易的事情
- 对css,动画等进行优化
- 删除重复和多余的代码
- 分析页面性能,进行具体调整
单测
写单测是和留下组建快照 是代码的一次快照缩影,以后维护中可以验证是否修改最后的html结构。用代码描述出最基本的功能,并进行验证。这样保证代码的设计合理性和容易理解的实用性。
加载优化
骨架屏
修改css
使用stylelint检测css一些不和规则的书写
因为css里有一些属性会触发重绘 所以 按照一定的书写顺序可以减少重绘提高css加载速度
而使用简写等可以减少css的打包体积
1. 安装
npm install stylelint --save-dev
npm install stylelint-config-standard --save-dev
npm install stylelint-order --save-dev
2. 在根目录下创建.stylelintrc配置文件
3. 使用
npx stylelint "**/*.css" --fix // fix 是自动修改
4. stylelint的检测提示
下图 是stylelint检测的要修改的点 加入--fix就会自动修改了
对比 虽然很小 但是 量变产生质变 文件多了自然就减少的多了
bundle区分 使用react lazy
const RedBagRain = React.lazy(() =>
import(
/* webpackPrefetch: true, webpackChunkName: 'RedBagRain.lazy'*/ "./components/red_bag_rain"
)
)
<React.Suspense fallback={null}>
<RedBagRain
dis_cold_start_selectors={[".mask", ".slidemodal"]}
visible={!showFinishPage}
/>
</React.Suspense>
RedBagRain有155 kb ,组建单独打包,分包加载,最后显示分出来 我把modal,actionsheet等 需要点击才能显示出的组建分包加载。这样就达到了首要的包优先加载,其他的包懒加载。如果不需要立即加载的,延迟1000s加载的写法是
const RedBagRain = React.lazy(() => {
return new Promise(resolve => setTimeout(resolve, 10 * 100)).then(() =>
import(/*webpackChunkName: 'RedBagRain.lazy'*/ "./components/red_bag_rain")
)
})
图片压缩
点击进入tiny-图片压缩网站 webpack-bundle-analyzer 分析那些图片太大,如果不是主要图片就进行再次压缩
结果对比
打包结果对比:
优化前
加载结果对比
reference
学习了