前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >女神网站优化之分批返回数据及懒加载

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

作者头像
周萝卜
发布2019-08-13 14:54:45
6240
发布2019-08-13 14:54:45
举报
文章被收录于专栏:萝卜大杂烩

微信公众号:萝卜大杂烩 关注可了解更多的原创内容。问题或建议,请公众号留言或加本人微信; 如果你觉得文章对你有帮助,欢迎加微信交流

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

瀑布流

最近做了一个图片网站,采用的是瀑布流的布局效果,大致如下:

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

下拉加载

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

改造后台

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

代码语言:javascript
复制
@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

代码语言:javascript
复制
@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,这样前端判断这个信号就可以判断什么时候停止请求数据了。

改造前端

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

代码语言:javascript
复制
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 函数真的是太好用了,感兴趣的同学可以自行去看看,非常的简单好用。

然后就是下拉的逻辑了

代码语言:javascript
复制
        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.

图片懒加载

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

代码语言:javascript
复制
<script src="https://rawgit.com/tuupola/jquery_lazyload/2.x/lazyload.js" type="text/javascript"></script>

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

代码语言:javascript
复制
<img class="thumb" data-src="{{ p[1] }}">

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

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

代码语言:javascript
复制
        $(function(){
            $("img.thumb").lazyload();
        });

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-08-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 萝卜大杂烩 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 瀑布流
  • 下拉加载
  • 改造后台
  • 改造前端
    • 图片懒加载
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档