六月份开始搭建的自己的第一个网站:书虫小说。
在经历前端页面重写后,网站首屏加载速度有了一定提升,之后发现小说目录详情页白屏时间竟然高达1-2s,拖了一段时间,打算解决这个问题,我用Chrome调试抓包发现json数据包大小竟然有200多KB,测试了一下加载时间大概在700ms-1500ms,由于章节列表的生成依赖于这个数据,所以自然会产生很长一段时间的白屏,我打算先解决这个问题。
server传数据是支持gzip压缩的,例如nginx发送html文档给客户端,会自动开启gzip压缩。至于一些其他格式的数据比如json需要手动开启,修改api网站nginx配置文件如下:
1 | gzip on; |
经过这个设置后,json数据从200+KB降到了30+KB,加载时间从原来的700+ms
降到了200+ms, 白屏时间至少减少了1s,可是依然存在。
这时我想到我要加载的是一个长列表,很多小说的章节数高达1000+,有一部《校花的贴身高手》更是高达8000+章,要一次渲染一个这么长的列表是相当耗费性能的,所以决定采用懒加载方案。
方案详情:
1. 数据还是一次性请求,因为数据延迟时间已经可以接受了,分多次请求的反而还增加了服务器压力(重新请求又要建立TCP连接,又要进行三次握手,blablabla...)。
2. 初次载入时只加载部分章节,直到用户滑到网页文档底部时开始插入数据,由于是加载已经缓存在内存中的数据,所以几乎不会有延迟,只是会因重新插入节点页面回流。
如何判断一个元素是否滚动到底?
1 | var element = document.documentElement //这里拿document来判断 |
几个属性及其含义:
- scrollHeight
表示的是元素的内容高度,包括了视区不可见的内容
- scrollTop
一个元素的 scrollTop 值是这个元素的顶部到视口可见内容(的顶部)的距离的度量。当一个元素的内容没有产生垂直方向的滚动条,那么它的 scrollTop 值为0。
如图:
- clientHeight
元素在出现在视区内的高度
有了这些概念,所以当一个滚动元素滑倒底部时,那么element.scrollHeight - element.scrollTop 应该等于 element.clientHeight
我的做法是给documentElement添加了scroll事件处理器,监听滚动事件,由于频繁获取以上这几个属性又挺消耗性能,我给回调函数设置了节流
1 | scrollWatcher() { // method |