女神網站優化之分批返回數據及懶加載

做爲一個手殘的外行前端 coder,今天由於須要,研究了下瀑布延時加載和圖片的懶加載,作個總結,省得之後忘記了!javascript

瀑布流

最近作了一個圖片網站,採用的是瀑布流的佈局效果,大體以下:html

看起來效果還不錯,可是問題卻來了,首頁這裏,每次 loading 都會一次性加載200+圖片,個人天啊。若是遇上網速很差的時候,會致使其餘網頁也沒法打開。這個真實無法忍,因而我準備優化一下。

下拉加載

很容易,我天然而然的就想到了採用下拉的形式,每次加載一部分數據,那麼說幹就幹。前端

改造後臺

最開始,個人後臺代碼是一次性把全部數據都返回給前端,如今把數據分紅4分,首次進入首頁時,只返回第一份java

@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)
複製代碼

而後再寫一個獲取數據的接口,參數就是 pagejquery

@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,這樣前端判斷這個信號就能夠判斷何時中止請求數據了。git

改造前端

先寫一個用戶獲取數據的函數json

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

flask_jsglueapi

這裏不得不提一下 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();
    	});
複製代碼

這樣,就能保證圖片只要當頁面滾動到它的位置時才加載了。

最後再提供下網站地址,供你們參考

nvshen.luobodazahui.top

相關文章
相關標籤/搜索