记一次活动页面优化


公司业务需求,需要做一个活动页面,页面中会展示大约1万多个商品.
这就对页面的加载性能很有要求和技巧了.
页面中大概有小分类100个.
页面示意图
页面示意图
页面刚做完时,加载时间在5~7秒的样子.

初始版本

代码如下:

constructor (props) {
	this.state = {
		type2: [],
        type3: [],
        type4: [],
        type5: [],
        ...
        type108: []
	}
}
componentDidMount () {
	this.getGoodList()
}
getGoodList () {
	this.setState({ 
		type2: goodList.type2,
		type3: goodList.type3,
		...
		type108: goodList.type108,
	})
}

这里面的getGoodList()方法耗时巨大,所以接下来需要对其进行改造

优化版本

改造思路:
页面直接加载全部数据–>页面展示具体某个分类时,加载该分类的商品数据
代码如下:
增加判断dom元素是否在浏览器可视范围的函数

checkVisibleInDocument = (node) => {
    if (!(node.offsetHeight || node.offsetWidth
        || node.getClientRects().length)) {
        return false
    }
    // 获取元素的高度和元素顶部相对视口的距离
    const { height, top } = node.getBoundingClientRect()
    const windowHeight = window.innerHeight || document.documentElement.clientHeight
    // 只需要确定元素顶部相对视口左上角的垂直距离小于视口的高度且元素底部相对视口左上角的垂直距离
    // 大于0
    return (top < windowHeight) && (top + height > 0)
}

在加载商品列表的方法中加入函数判定

getGoodList () {
	for (let i = 2; i <= 108; i++) {
		if (this.checkVisibleInDocument(document.getElementById('' + i))) {
			switch (i) {
                    case 2:if(this.state.type2.length == 0) {this.setState({ type2: goodList.type2 })}break;
                    case 3:if(this.state.type3.length == 0) {this.setState({ type3: goodList.type3 })}break;
                    ...
                    default:
                        break
		}
	}
}

增加滑屏事件监听

componentDidMount () {
	window.addEventListener('scroll', this.handleScroll)
}
handleScroll = (e) => {
    let ctx=this;
    let clientHeight = document.documentElement.clientHeight; //可视区域高度
    let scrollHeight =document.documentElement.scrollHeight
    if(clientHeight != scrollHeight) {
        ctx.getGoodList()
    }
}

这样一来,用户刚进入页面时,只会加载第一个分类的数据,而在滑动时再一一加载其他分类的数据
此时页面响应速度已经来到了1秒以内.

解决锚点跳转时的滑屏问题

但由于页面中存在带有锚点的导航条,在点击跳转时,会同时触发滑屏事件,这回导致在快速定位到指定位置时,会加载若干个分类的数据,这和我们的期望不符
侧边导航
解决方式如下:
在锚点组件中增加onCLick事件

<Anchor affix={false} onClick={this.getSolimg}>
	...
</Anchor>

在事件中先移除滑屏事件监听,在0.5秒后再还原

getSolimg = () => {
    window.removeEventListener('scroll', this.handleScroll)
    setTimeout(()=>{
         this.handleScroll();
         window.addEventListener('scroll', this.handleScroll);
    }, 500);
}

PS: 在这个页面中,一开始还使用了Zmage组件,但由于数据量过大,会出现数据未加载完毕时,图片都显示组件加载中的状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值