精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

如果后端API一次返回10萬條數據,前端應該如何處理?

開發 后端
?最近,我的一位朋友在面試時被問到這個問題。這個問題其實是考察面試者對性能優化的理解,涉及的話題很多。下面我就和大家一起來分析一下這個問題。

?最近,我的一位朋友在面試時被問到這個問題。這個問題其實是考察面試者對性能優化的理解,涉及的話題很多。下面我就和大家一起來分析一下這個問題。

創建服務器

為了方便后續測試,我們可以使用node創建一個簡單的服務器。

服務器端代碼:

const http = require('http')
const port = 8000;

let list = []
let num = 0

// create 100,000 records
for (let i = 0; i < 100_000; i++) {
num++
list.push({
src: 'https://miro.medium.com/fit/c/64/64/1*XYGoKrb1w5zdWZLOIEevZg.png',
text: `hello world ${num}`,
tid: num
})
}

http.createServer(function (req, res) {
// for Cross-Origin Resource Sharing (CORS)
res.writeHead(200, {
'Access-Control-Allow-Origin': '*',
"Access-Control-Allow-Methods": "DELETE,PUT,POST,GET,OPTIONS",
'Access-Control-Allow-Headers': 'Content-Type'
})

res.end(JSON.stringify(list));
}).listen(port, function () {
console.log('server is listening on port ' + port);
})
const http = require('http')
const port = 8000;

let list = []
let num = 0

// create 100,000 records
for (let i = 0; i < 100_000; i++) {
num++
list.push({
src: 'https://miro.medium.com/fit/c/64/64/1*XYGoKrb1w5zdWZLOIEevZg.png',
text: `hello world ${num}`,
tid: num
})
}

http.createServer(function (req, res) {
// for Cross-Origin Resource Sharing (CORS)
res.writeHead(200, {
'Access-Control-Allow-Origin': '*',
"Access-Control-Allow-Methods": "DELETE,PUT,POST,GET,OPTIONS",
'Access-Control-Allow-Headers': 'Content-Type'
})

res.end(JSON.stringify(list));
}).listen(port, function () {
console.log('server is listening on port ' + port);
})

我們可以使用 node 或 nodemon 啟動服務器:

$ node server.js
# or
$ nodemon server.js

創建前端模板頁面

然后我們的前端由一個 HTML 文件和一個 JS 文件組成。

Index.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}

#container {
height: 100vh;
overflow: auto;
}

.sunshine {
display: flex;
padding: 10px;
}

img {
width: 150px;
height: 150px;
}
</style>
</head>
<body>
<div id="container">
</div>
<script src="./index.js"></script>
</body>
</html>

Index.js:

// fetch data from the server
const getList = () => {
return new Promise((resolve, reject) => {

var ajax = new XMLHttpRequest();
ajax.open('get', 'http://127.0.0.1:8000');
ajax.send();
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
resolve(JSON.parse(ajax.responseText))
}
}
})
}

// get `container` element
const container = document.getElementById('container')


// The rendering logic should be written here.

好的,這就是我們的前端頁面模板代碼,我們開始渲染數據。

直接渲染

最直接的方法是一次將所有數據渲染到頁面。代碼如下:

const renderList = async () => {
const list = await getList()

list.forEach(item => {
const div = document.createElement('div')
div.className = 'sunshine'
div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`
container.appendChild(div)
})
}
renderList()

一次渲染 100,000 條記錄大約需要 12 秒,這顯然是不可取的。

通過 setTimeout 進行分頁渲染

一個簡單的優化方法是對數據進行分頁。假設每個頁面都有limit記錄,那么數據可以分為Math.ceil(total/limit)個頁面。之后,我們可以使用 setTimeout 順序渲染頁面,一次只渲染一個頁面。

const renderList = async () => {

const list = await getList()

const total = list.length
const page = 0
const limit = 200
const totalPage = Math.ceil(total / limit)

const render = (page) => {
if (page >= totalPage) return
setTimeout(() => {
for (let i = page * limit; i < page * limit + limit; i++) {
const item = list[i]
const div = document.createElement('div')
div.className = 'sunshine'
div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`
container.appendChild(div)
}
render(page + 1)
}, 0)
}
render(page)
}

分頁后,數據可以快速渲染到屏幕上,減少頁面的空白時間。

requestAnimationFrame

在渲染頁面的時候,我們可以使用requestAnimationFrame來代替setTimeout,這樣可以減少reflow次數,提高性能。

const renderList = async () => {
const list = await getList()

const total = list.length
const page = 0
const limit = 200
const totalPage = Math.ceil(total / limit)

const render = (page) => {
if (page >= totalPage) return

requestAnimationFrame(() => {
for (let i = page * limit; i < page * limit + limit; i++) {
const item = list[i]
const div = document.createElement('div')
div.className = 'sunshine'
div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`
container.appendChild(div)
}
render(page + 1)
})
}
render(page)
}

window.requestAnimationFrame() 方法告訴瀏覽器您希望執行動畫,并請求瀏覽器調用指定函數在下一次重繪之前更新動畫。該方法將回調作為要在重繪之前調用的參數。

文檔片段

以前,每次創建 div 元素時,都會通過 appendChild 將元素直接插入到頁面中。但是 appendChild 是一項昂貴的操作。

實際上,我們可以先創建一個文檔片段,在創建了 div 元素之后,再將元素插入到文檔片段中。創建完所有 div 元素后,將片段插入頁面。這樣做還可以提高頁面性能。

const renderList = async () => {
console.time('time')
const list = await getList()
console.log(list)
const total = list.length
const page = 0
const limit = 200
const totalPage = Math.ceil(total / limit)

const render = (page) => {
if (page >= totalPage) return
requestAnimationFrame(() => {

const fragment = document.createDocumentFragment()
for (let i = page * limit; i < page * limit + limit; i++) {
const item = list[i]
const div = document.createElement('div')
div.className = 'sunshine'
div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`

fragment.appendChild(div)
}
container.appendChild(fragment)
render(page + 1)
})
}
render(page)
console.timeEnd('time')
}

延遲加載

雖然后端一次返回這么多數據,但用戶的屏幕只能同時顯示有限的數據。所以我們可以采用延遲加載的策略,根據用戶的滾動位置動態渲染數據。

要獲取用戶的滾動位置,我們可以在列表末尾添加一個空節點空白。每當視口出現空白時,就意味著用戶已經滾動到網頁底部,這意味著我們需要繼續渲染數據。

同時,我們可以使用getBoundingClientRect來判斷空白是否在頁面底部。

圖片

使用 Vue 的示例代碼:

<script setup lang="ts">
import { onMounted, ref, computed } from 'vue'
const getList = () => {
// code as before
}
const container = ref<HTMLElement>() // container element
const blank = ref<HTMLElement>() // blank element
const list = ref<any>([])
const page = ref(1)
const limit = 200
const maxPage = computed(() => Math.ceil(list.value.length / limit))
// List of real presentations
const showList = computed(() => list.value.slice(0, page.value * limit))
const handleScroll = () => {
if (page.value > maxPage.value) return
const clientHeight = container.value?.clientHeight
const blankTop = blank.value?.getBoundingClientRect().top
if (clientHeight === blankTop) {
// When the blank node appears in the viewport, the current page number is incremented by 1
page.value++
}
}
onMounted(async () => {
const res = await getList()
list.value = res
})
</script>

<template>
<div id="container" @scroll="handleScroll" ref="container">
<div class="sunshine" v-for="(item) in showList" :key="item.tid">
<img :src="item.src" />
<span>{{ item.text }}</span>
</div>
<div ref="blank"></div>
</div>
</template>

最后

我們從一個面試問題開始,討論了幾種不同的性能優化技術。

如果你在面試中被問到這個問題,你可以用今天的內容回答這個問題,如果你在工作中遇到這個問題,你應該先揍那個寫 API 的人。?

責任編輯:未麗燕 來源: springmeng
相關推薦

2022-10-27 21:32:28

數據互聯網數據中心

2022-07-27 10:30:49

后端前端

2021-11-02 14:46:50

數據

2019-11-28 18:54:50

數據庫黑客軟件

2025-09-01 01:45:00

數據虛擬列表

2019-07-16 08:51:03

熱搜新浪微博數據

2024-03-07 08:08:51

SQL優化數據

2023-10-19 15:13:25

2011-03-31 11:24:14

數據搜索本文字段

2017-07-22 22:11:36

數據丟失操作

2024-09-22 14:17:54

2018-08-27 07:01:33

數據分析數據可視化租房

2020-10-27 10:35:38

優化代碼項目

2024-07-10 10:08:36

項目多表關聯哈希

2018-10-11 09:33:51

Kafka消息處理

2025-09-10 07:05:00

2018-03-02 10:42:44

服務器數據備份

2024-08-28 17:50:22

2022-04-28 20:12:44

二分法搜索算法

2019-10-18 15:36:24

網易歌單熱評
點贊
收藏

51CTO技術棧公眾號

久草手机视频在线观看| 日本在线xxx| 国产精品一区二区av白丝下载 | 国产丝袜在线播放| bt欧美亚洲午夜电影天堂| 欧美中文字幕视频在线观看| 国产综合精品久久久久成人av| 四虎国产精品免费久久| 亚洲福利电影网| 婷婷五月色综合| 亚洲AV无码精品自拍| 亚洲欧美成人| 欧美裸体xxxx极品少妇| 日韩乱码人妻无码中文字幕久久| 亚洲青青久久| 狠狠色狠狠色综合日日小说| japanese在线视频| 激情小说 在线视频| 国产精品一区二区久激情瑜伽| 国产91精品久久久久久| 国产午夜手机精彩视频| 国产一区日韩| 亚洲第一精品电影| 亚洲综合20p| 欧美天堂视频| 亚洲大型综合色站| 好吊色这里只有精品| 麻豆app在线观看| 成人免费黄色大片| 成人久久久久久| 波多野结衣二区三区| 亚洲精品女人| 欧美成年人在线观看| 国产欧美小视频| 久草成人资源| 日韩电影在线观看永久视频免费网站| 中文字幕第10页| 欧美亚洲福利| 欧美视频一区二区在线观看| 日av中文字幕| 国模冰冰炮一区二区| 亚洲成av人在线观看| 成人午夜视频免费观看| 精品国产白色丝袜高跟鞋| 免费在线视频一级不卡| 欧美激情在线精品一区二区三区| 日韩欧美中文字幕一区| 精品亚洲视频在线| 国产极品一区| 欧美色视频一区| 一区二区三区国产免费| 亚洲精品.com| 91福利视频网站| 日本精品一区二区三区四区| 色综合桃花网| 欧美视频在线观看免费| 精品99在线视频| 午夜小视频福利在线观看| 国产亚洲福利社区一区| 欧美精品尤物在线| 极品白浆推特女神在线观看| 国产三级精品在线| 亚洲国产一区二区三区在线播| 超碰免费在线| 国产精品久99| 丰满女人性猛交| 超碰caoporn久久| 亚洲精品成a人| 97碰在线视频| 在线天堂中文资源最新版| 精品久久久久久久久久久久久久| av片中文字幕| 国产成+人+综合+亚洲欧美| 欧美日韩国产bt| 宇都宫紫苑在线播放| 中文字幕亚洲在线观看 | 人妻精品一区一区三区蜜桃91| 丁香桃色午夜亚洲一区二区三区| 国产日本一区二区三区| 免费黄网站在线观看| 中文字幕免费不卡| 强伦女教师2:伦理在线观看| 久久一卡二卡| 色综合欧美在线视频区| 中文字幕 日韩 欧美| 日韩欧美另类中文字幕| 日韩成人在线网站| 91麻豆制片厂| 亚洲国产一区二区三区a毛片| 欧美一级高清免费| 亚洲天堂avav| 成人精品视频一区二区三区| 日本视频精品一区| 成人直播在线| 一本色道a无线码一区v| 亚洲欧美日本一区二区| 久久成人福利| 精品久久国产精品| 99热国产在线观看| 久久精品国产77777蜜臀| 国产欧美亚洲日本| 欧美一区二区三区在线观看免费| 亚洲国产美国国产综合一区二区| 91香蕉视频污版| 日本精品国产| 一区二区三区国产视频| 国产精品99精品| 久久er精品视频| 欧美另类一区| 岛国毛片av在线| 欧美精品三级日韩久久| 粉嫩av蜜桃av蜜臀av| 欧美不卡高清| 国产精品视频成人| 青青青免费视频在线2| 亚洲精品免费一二三区| www.欧美日本| 日韩欧美在线精品| 欧美成人自拍视频| 这里只有精品9| 国产亚洲一本大道中文在线| 男女猛烈激情xx00免费视频| 国产精品777777在线播放| 亚洲人午夜色婷婷| 日韩三级av在线| 国产精品资源站在线| 亚洲精品久久久久久一区二区| 黄毛片在线观看| 精品成a人在线观看| 欧美日韩中文字幕在线观看| 久久精品国产亚洲高清剧情介绍 | 午夜不卡av在线| 国模大尺度视频| 99国产精品免费视频观看| 日韩av毛片网| 日本高清中文字幕二区在线| 亚洲成人在线免费| 久久久久无码国产精品一区李宗瑞| 偷拍欧美精品| 国产主播喷水一区二区| 在线日本视频| 欧美日韩在线综合| 久久91亚洲精品中文字幕| aaaaa一级片| 99国产精品久久久久久久| av日韩免费电影| 中日韩高清电影网| 日韩一区二区精品| avove在线播放| 国产精品888| 男人草女人视频| 日韩欧美激情电影| 欧美黑人巨大精品一区二区| 国产99久久九九精品无码免费| 中文字幕一区二区三| 岛国av免费在线| 一区二区三区四区电影| 亚洲最大的免费| 污污影院在线观看| 日韩精品中文字幕一区| 国产精品a成v人在线播放| 成人午夜私人影院| 欧美s码亚洲码精品m码| 亚洲免费福利一区| 国产精品福利网站| 黄色网址在线免费播放| 日韩一级免费观看| 日韩av片在线播放| www国产精品av| 亚洲天堂av线| 欧美福利专区| 久久久7777| 视频精品导航| 欧美福利视频在线| 五月天婷婷视频| 欧美亚洲禁片免费| 五月综合色婷婷| eeuss影院一区二区三区| av免费播放网址| 欧美亚洲国产激情| 3d动漫精品啪啪一区二区三区免费 | 亚洲欧美中文在线视频| 国产又大又黄又爽| 香蕉成人啪国产精品视频综合网| 亚洲天堂视频一区| 黄色小说综合网站| 99久久国产综合精品五月天喷水| 欧美人与牛zoz0性行为| 91免费在线视频网站| 理论不卡电影大全神| 中文字幕日韩精品在线| 精品毛片一区二区三区| 色综合天天综合狠狠| 亚洲不卡在线播放| 久久综合九色综合97_久久久| www.99r| 国产日韩欧美在线播放不卡| 亚洲欧洲在线一区| 久久久久久毛片免费看 | 嗯用力啊快一点好舒服小柔久久| 国产成人高清激情视频在线观看| 最近中文字幕免费mv2018在线| 亚洲精品一区二区在线| 国产三级第一页| 色噜噜夜夜夜综合网| 麻豆视频在线观看| 中文字幕高清一区| 久久久国产精品无码| 久久99国产精品久久99| 国产肥臀一区二区福利视频| 欧美成人tv| 亚洲免费久久| 婷婷成人影院| 国产精品久久久久久久久久久久冷 | 国产欧美一区二区| 中文字幕资源网在线观看免费 | 日韩特黄一级片| 亚洲色图视频网站| jizz中文字幕| 久久网站热最新地址| 日本一区二区免费视频| 高清不卡av| 亚洲日韩欧美一区二区在线| 波多野结衣av在线免费观看| 国v精品久久久网| 亚洲精品视频三区| 免费观看在线色综合| 精品一卡二卡三卡| 99精品国产福利在线观看免费| 天天爱天天做天天操| 日韩不卡一区| 四虎影院一区二区三区| 亚洲综合福利| 久久综合伊人77777麻豆| 高清日韩中文字幕| 国产91一区二区三区| 日本免费一区二区三区视频| 91精品视频一区| 日韩免费在线电影| 国产在线播放91| 国产69精品久久久久按摩| 国产精品久久久久久av福利软件| 国偷自产一区二区免费视频| 97成人精品区在线播放| 神马久久午夜| 欧美综合在线第二页| a欧美人片人妖| 国产91色在线| 日韩毛片在线| 国产精品久久在线观看| 成人欧美magnet| 国产成+人+综合+亚洲欧洲| 欧美黑人粗大| 国产精品高清免费在线观看| 电影一区二区| 91性高湖久久久久久久久_久久99| 羞羞视频在线观看一区二区| 91久久久久久久久久久久久| 国产精品久久久久久久久久辛辛| 91在线|亚洲| 亚洲一区网址| 久久精品第九区免费观看| 性人久久久久| 亚洲一区二区不卡视频| 婷婷久久综合| 成人av在线播放观看| 99视频精品| 蜜臀视频一区二区三区| 另类小说视频一区二区| 在线观看欧美一区二区| 成人avav影音| 先锋影音av在线| 综合色中文字幕| 日韩成人一区二区三区| 日韩欧美在线看| 又骚又黄的视频| 日韩精品一区二区三区视频| 亚欧在线观看视频| 中文字幕一区二区三区电影| 国产在线69| 欧美诱惑福利视频| 成人看片毛片免费播放器| 91久久偷偷做嫩草影院| 欧美日韩一本| 婷婷久久五月天| 激情欧美日韩| www.日本xxxx| 成人一区二区三区在线观看| 国产av自拍一区| 一二三四区精品视频| 无码人妻av免费一区二区三区 | 国产精品三级网站| 日韩精品久久久久久久软件91| 免费日韩av电影| 在线精品国产| 日韩精品一区二区三区不卡| 国产乱子轮精品视频| 麻豆精品免费视频| 亚洲激情网站免费观看| 91丨九色丨海角社区| 精品sm在线观看| 免费的黄网站在线观看| 欧美伊久线香蕉线新在线| 欧美成人一级| 婷婷久久青草热一区二区| aa国产精品| 污视频在线观看免费网站| 日本一区二区在线不卡| 日本中文字幕网| 在线综合+亚洲+欧美中文字幕| 欧美扣逼视频| 97在线视频精品| 日韩中文字幕在线一区| 午夜精品区一区二区三| 亚洲视频1区| 美国黄色一级视频| 亚洲欧洲成人精品av97| 中文字幕免费观看| 亚洲国产黄色片| 污视频免费在线观看| 91精品久久久久久久久久| 精品高清在线| 97在线免费公开视频| av成人动漫在线观看| 中文字幕av免费在线观看| 欧美日韩精品一区二区三区蜜桃 | 不卡影院一区二区| youjizz久久| 国产精品50页| 精品国产乱码久久久久久图片 | 精品无人区麻豆乱码久久久| 免费无码国产v片在线观看| 国产1区2区3区精品美女| 在线看的片片片免费| 欧美欧美午夜aⅴ在线观看| 国家队第一季免费高清在线观看| 97视频在线观看播放| 丁香五月缴情综合网| 97中文字幕在线| 高清不卡一区二区| 久草国产在线观看| 日韩精品中午字幕| jizz一区二区三区| 国产一区二区高清不卡| 999在线观看精品免费不卡网站| 日本中文字幕精品| 一区二区三区**美女毛片| 99热这里只有精品在线观看| 欧美理论电影在线播放| 亚洲2区在线| 亚洲理论电影在线观看| 成人精品视频一区| 色婷婷av国产精品| 亚洲美腿欧美激情另类| 欧美xx视频| 性欧美精品一区二区三区在线播放| 免费高清视频精品| 美女视频久久久| 欧美好骚综合网| 亚洲资源在线网| 极品美女销魂一区二区三区免费| 天天鲁一鲁摸一摸爽一爽| 日韩午夜在线影院| 丁香高清在线观看完整电影视频| 国产日韩欧美一区二区| 久久亚洲影院| 黄色av片三级三级三级免费看| 91精品午夜视频| 黄色大片在线| 欧美日韩在线不卡一区| 久久国产三级精品| 久草视频免费在线播放| 亚洲精品久久久久久下一站 | 成人免费高清完整版在线观看| 亚洲欧洲中文字幕| 国产精品扒开腿做爽爽爽a片唱戏| 欧美天堂在线观看| 日韩黄色影院| 国产一区二区高清视频| 美女免费视频一区| 久久久久久av无码免费网站| 亚洲人午夜精品免费| 疯狂欧洲av久久成人av电影| 成人一区二区免费视频| 国产片一区二区| 国产欧美综合视频| 欧美做受高潮1| 欧美在线三区| 成人免费网站黄| 日韩欧美国产一区在线观看| 二区三区不卡| 91传媒免费视频| 日本一区二区视频在线观看| 成人av一区二区三区在线观看| 日韩女在线观看| 黑人一区二区三区四区五区| 国产精品18在线| 日韩精品极品在线观看播放免费视频 | 午夜a成v人精品| 日本三级视频在线播放|