为了账号安全,请及时绑定邮箱和手机立即绑定

女神网站优化之分批返回数据及懒加载

作为一个手残的外行前端 coder,今天因为需要,研究了下瀑布延时加载和图片的懒加载,做个总结,免得以后忘记了!

瀑布流

最近做了一个图片网站,采用的是瀑布流的布局效果,大致如下:
图片描述
看起来效果还不错,但是问题却来了,首页这里,每次 loading 都会一次性加载200+图片,我的天啊。如果赶上网速不好的时候,会导致其他网页也无法打开。这个真实没法忍,于是我准备优化一下。

下拉加载

很容易,我自然而然的就想到了采用下拉的形式,每次加载一部分数据,那么说干就干。

改造后台

最开始,我的后台代码是一次性把所有数据都返回给前端,现在把数据分成4分,首次进入首页时,只返回第一份

@app.route('/', methods=['GET', 'POST'])
def index():
    db = get_db()
    cur = db.execute('select name, nvshen_id from nvshen order by id desc')
    nvshen = [dict(name=row[0], nvshen_id=row[1]) for row in cur.fetchall()]
    seg = int(len(nvshen)/4)
    data = []
    socre = 1
    for n in nvshen[:seg]:
        tmp_data = []
        pic = db.execute('select pic_url from picture where nvshen_id = (?)', [n['nvshen_id']])
        pic_list = [row[0] for row in pic.fetchall()]
        pic_url = random.choice(pic_list)
        tmp_data.append(n['name'])
        tmp_data.append(pic_url)
        tmp_data.append(n['nvshen_id'])
        data.append(tmp_data)
    return render_template('index.html', data=data, score=socre)

然后再写一个获取数据的接口,参数就是 page

@app.route('/api/getdata/<int:page>', methods=['POST'])
def get_data(page):
    db = get_db()
    cur = db.execute('select name, nvshen_id from nvshen order by id desc')
    nvshen = [dict(name=row[0], nvshen_id=row[1]) for row in cur.fetchall()]
    seg = 0
    seg_page = int(len(nvshen)/4)
    end = False
    if page == 2:
        seg = seg_page
        seg_page = seg*2
    elif page == 3:
        seg = seg_page*2
        seg_page = seg*3
    elif page == 4:
        seg = seg_page*3
        seg_page = int(len(nvshen)) + 1
        end = True
    elif page == 1:
        pass
    else:
        return jsonify({"msg": "error page id", "code": 422}), 422
    data = []
    socre = 1
    for n in nvshen[seg:seg_page]:
        tmp_data = []
        pic = db.execute('select pic_url from picture where nvshen_id = (?)', [n['nvshen_id']])
        pic_list = [row[0] for row in pic.fetchall()]
        pic_url = random.choice(pic_list)
        tmp_data.append(n['name'])
        tmp_data.append(pic_url)
        tmp_data.append(n['nvshen_id'])
        data.append(tmp_data)
    print("getdata: ", data)
    return jsonify({"msg": data, "code": 200, "end": end}), 200

因为当前只是把数据分成4分,所以当 page 为4的时候,就把停止信号 end 设置为 True,这样前端判断这个信号就可以判断什么时候停止请求数据了。

改造前端

先写一个用户获取数据的函数

function getData(page) {
			var xhr = new XMLHttpRequest();
			xhr.responseType = "json";
			xhr.open('POST', '/api/getdata/' + page, true);
			xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			xhr.onload = function (ev) {
				if(this.status === 200) {
					//console.log(this.response);
					if(this.response['end'] === true) {
						//console.log("end is true");
						flag = false;
					};
						var mydata = this.response['msg'];
						for(var i=0, len=mydata.length; i<len; i++){
							var myurl = mydata[i][1];
							var myid = mydata[i][2];
							var myname = mydata[i][0];
							var htmlText = '<article class="white-panel">' +
								'<img data-src=' + myurl +' class="thumb">' +
								'<h1>' +
								'<a href=URL title="去投票" target="_blank">'.replace("URL", Flask.url_for("nvshen", {id: myid})) +
								 myname + '</a>' +
								'</h1>' +
								'<p>' +
								'<div id="starBg" class="stars-bg">' +
								'{% if score == 1 %}' +
								'<a href="#" class="star-active" style="width: 20%"></a>' +
								'{% elif score == 2 %}' +
								'<a href="#" class="star-active" style="width: 40%"></a>' +
								'{% elif score == 3 %}' +
								'<a href="#" class="star-active" style="width: 60%"></a>' +
								'{% elif score == 4 %}' +
								'<a href="#" class="star-active" style="width: 80%"></a>' +
								'{% elif score == 5 %}' +
								'<a href="#" class="star-active" style="width: 100%"></a>' +
								'{% else %}' +
								'<a href="#" class="star-active" style="width: 0%"></a>' +
								'{% endif %}' +
								'</div>' +
								'</p>' +
								'</article>';
							var script = '<script>' +
									'$(function(){' +
									'$("img.thumb").lazyload();' +
									'})' +
									'<\/script>';
							$('#gallery-wrapper').append(htmlText);
							$('body').append(script);
						}
					//console.log("add new html finish");
				}
			};
			xhr.send();
		}

主要还是拼接字符串,然后把获取到的数据塞进字符串中。

flask_jsglue
这里不得不提一下 flask 的一个插件 --flask_jsglue
对于在 JavaScript 中使用 url_for 函数真的是太好用了,感兴趣的同学可以自行去看看,非常的简单好用。

然后就是下拉的逻辑了

        var totalHeight = $(document).height(); //整个文档高度
		var scrollTop = $(window).scrollTop();//浏览器可视窗口顶端距离网页顶端的高度(垂直偏移)
		var p = 2;
		var flag = true;
		$(window).scroll(function () {
			scrollTop = $(window).scrollTop();
			console.log("totalHeight-scrollTop-$(this).height()", totalHeight-scrollTop-$(this).height());
			totalHeight = $(document).height();
			if(flag){
				if(totalHeight-scrollTop-$(this).height()<0.5){
					//console.log("add new html");
					getData(p);
					p ++;
				}
			}
		});

因为我们再进入首页的时候,已经返回了数据的第一部分,所以这里的 page 就从2开始取值;然后当整个文档的高度减去垂直偏移量,再减去浏览器可是窗口的高度小于0.5时,则调用拉取数据的函数,并且 p 自加1.

图片懒加载

对于图片懒加载,就比较简单了,有现成的组件库可以使用。
首先引入类库

<script src="https://rawgit.com/tuupola/jquery_lazyload/2.x/lazyload.js" type="text/javascript"></script>

然后修改 img 元素的图片地址属性

<img class="thumb" data-src="{{ p[1] }}">

我们一般会把图片地址赋值给 src,现在我们赋值给 data-src。

最后,在页面全局写一个函数

		$(function(){
        	$("img.thumb").lazyload();
    	});

这样,就能保证图片只要当页面滚动到它的位置时才加载了。

最后再提供下网站地址,供大家参考
https://nvshen.luobodazahui.top

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消