El tiempo de solicitud de decenas de miles de datos en el backend (este error son 20 000 datos) es demasiado lento, el plan de optimización del front-end y los problemas que surgen durante el proceso de solución

Tabla de contenido

Capítulo 1 Prefacio Descripción

Capítulo 2 Proceso de resolución de problemas

2.1 Analizar la causa del problema

2.2 Comprensión de $.when()

2.3 Proceso de resolución

2.3.1 Tratar los síntomas pero no la causa raíz (para el caso de almacenamiento insuficiente cuando los datos de sessionStore son demasiados: 12s+)

2.3.2 Coloque las estadísticas de la segunda página en el procesamiento de página necesario y luego guárdelas en el almacenamiento (12s+)

2.3.3 Lleva mucho tiempo comenzar a procesar (interfaz de paginación de solicitud síncrona 12s+ -> alrededor de 8s)

2.3.4 El tiempo de procesamiento es más corto (datos de solicitud asíncrona, procesamiento durante la solicitud: 3s-6s)

2.3.5 Interludios en el medio (paginación y empuje websocket)


Capítulo 1 Prefacio Descripción

  • Descripción: En el proceso de trabajo, me encontré con una situación así. Hay una cantidad particularmente grande de datos en una cuenta, con casi 20,000 piezas de datos. El resultado de la solicitud se coloca en el almacenamiento de sesión temporal (sessionStore), y luego el los datos se toman del almacenamiento temporal cuando se necesitan los datos
  • Los métodos que solo miran el código fuente y usan los datos de la solicitud son: window.HJWL_API --> solicitud para cada API, $.when().done(function(){}).then(function(){}) --> Usar cuando se procesan varias solicitudes al mismo tiempo

Capítulo 2 Proceso de resolución de problemas

2.1 Analizar la causa del problema

  • Con el aumento de la Parte A en el futuro, los datos correspondientes también seguirán aumentando, lo que dará como resultado decenas de miles de datos bajo un administrador en el período posterior, y el tiempo de procesamiento de solicitudes será más largo cuando se obtengan datos del dispositivo.
  • Debido al uso de almacenamiento temporal, existe otro problema que cuando los datos solicitados son demasiado grandes, excederán la memoria, lo que generará un error.

2.2 Comprensión de $.when()

Para las solicitudes de window.HJWL_API , hay un punto en el que la interfaz se procesó después de cada solicitud de datos y se obtuvieron los datos, pero todos los datos obtenidos siempre se obtendrán después de implementar toda la lógica del código, lo que hace que la lógica del código Los datos no se pueden obtener durante el proceso (no es correcto entenderlo como una macro tarea, por lo que estoy confundido)

$.when() me ha resuelto muchos problemas: el método se puede entender de esta manera: solo se ejecutan diferentes métodos de solicitud de datos en $.when(), y luego los datos se pueden obtener en .done y el correspondiente se ejecuta el método

2.3 Proceso de resolución

2.3.1 Tratar los síntomas pero no la causa raíz (para el caso de almacenamiento insuficiente cuando los datos de sessionStore son demasiados: 12s+)

En ese momento, debido a que tenía prisa, no se realizó una investigación especial en profundidad, sino que simplemente se agregó la interfaz utilizada para obtener el número total en las dos páginas, resolviendo así el problema de caché insuficiente.

 HJWL_API.getAllDevice().done(function(res) {  //请求获取所有数据的方法
    self.getAllData(res.list);    //将获取到的数据通过传参进行处理
    loading.close()
})

La razón por la que se procesa pasando parámetros es porque los datos solicitados por este método son los últimos

Después de usar esta solución, la página del mapa y la página de estadísticas necesitan solicitar datos cada vez, lo que genera una larga espera para cada carga y el efecto no es bueno.

2.3.2 Coloque las estadísticas de la segunda página en el procesamiento de página necesario y luego guárdelas en el almacenamiento (12s+)

Si bien esta solución ha optimizado mucho la segunda página, tiene la falla de que debe pasar por la primera página, por lo que cuando algunas personas no toman el camino habitual, no habrá procesamiento de datos, que también es una solución oportunista.

 reloadOption1Data: function (data) {
        ……
       //统计数据的过程……
       sessionStorage.stateTemp = JSON.stringify(stateTemp) //最后将统计结果放到临时存储中
},

2.3.3 Lleva mucho tiempo comenzar a procesar (interfaz de paginación de solicitud síncrona 12s+ -> alrededor de 8s)

  •  Negociar con el backend para proporcionar una interfaz de paginación
  • Anote muchos lugares en el código que usan temporizadores. Aunque estos métodos de retraso forzado se usan para obtener datos, ahora no hay necesidad de una interfaz de paginación (cuando termino de procesarlos, el tiempo de solicitud cambia de los 12 segundos originales a 8 segundos ) -- este es el procesamiento del código actual, pero 8 segundos no es estable , porque todavía se recuperan todos los datos
  • Use $.when para obtener datos de la interfaz de paginación (en este momento, la solicitud todavía se envía de forma síncrona)
const pageSize = 2500; //一次请求的数据大小
const countPage = Math.ceil(self.devicesTotal/pageSize); //一共有多少页
var deviceList = [];  // 存放数据
var apiList = []   //存放请求
for(let pageNumber = 1; pageNumber<= countPage; pageNumber++) {  //将所有的请求都获取出来
    apiList.push(HJWL_API.getAllDevice('',pageNumber,pageSize))
}
$.when(  //处理所有的分页获取数据的请求
    ...apiList
).done((...res) => {
    res.forEach((devicePage)=>{ //将每个分页得到的结果合并起来
       deviceList.push(...devicePage[0].page.list)
    })
    self.initCharts();      //执行后续的方法
    self.initMap(res.list);
    self.initMap(deviceList);
    loading.close()
})
    this.firstInit = false
})                 

Después de usar este método, básicamente se estabilizó en 8 segundos.

2.3.4 El tiempo de procesamiento es más corto (datos de solicitud asíncrona, procesamiento durante la solicitud: 3s-6s)

  • Esta vez, no enviamos una solicitud de paginación, procesamos el método correspondiente una vez, obtuvimos los datos correspondientes y luego continuamos procesando el método correspondiente al enviar la segunda solicitud, de modo que hay un efecto de representación dinámica de datos en el mapa, y finalmente el tiempo Acortado a 3-6 segundos, y también tiene un efecto dinámico
  • La razón por la que el método se ejecuta bajo la solicitud aquí es que la lógica de procesamiento de datos se obtendrá solo cuando el método de solicitud corresponda, que normalmente se muestra al final, lo que hará que no se obtengan los datos.
 // 异步分组查询
const pageSize = 2500; //分页大小
const countPage = Math.ceil(self.devicesTotal/pageSize); //总页数
for(let pageNumber = 1; pageNumber<= countPage; pageNumber++) { // 通过循环发送请求,同时每请求成功一次数据处理一些事件
    HJWL_API.getAllDevice('',pageNumber,pageSize).then((res)=>{ //发送请求
        self.devices.push(...res.page.list)
        loading.close()
        ……
        //当存储设备数等于总设备数时,代表获取到了所有设备数据
        if(self.devices.length == self.devicesTotal) {
        this.firstInit = false
        let alamState=0;
        // 将地图中心转到一个告警设备并展示设备信息
        for(let k in self.devices) {
             if(self.devices[k].alarmState>alamState){
                  alamState=self.devices[k].alarmState;
                  if(alamState==1){
                        self.play_mp3();
                        self.showInfoWindow(self.devices[k].id);
                              self.map.setZoomAndCenter(18,
[parseFloat(self.devices[k].longitude),parseFloat(self.devices[k].latitude)]);
                              break;
                         }
                  }
             }
         }
})

2.3.5 Interludios en el medio (paginación y empuje websocket)

  •  Cuando los datos son menos de una página, se informa un error, que no es considerado
const pageSize = 2500; //一次请求的数据大小
const countPage = Math.ceil(self.devicesTotal/pageSize); //一共有多少页
var deviceList = [];  // 存放数据
var apiList = []   //存放请求
for(let pageNumber = 1; pageNumber<= countPage; pageNumber++) {  //将所有的请求都获取出来
    apiList.push(HJWL_API.getAllDevice('',pageNumber,pageSize))
}
$.when(  //处理所有的分页获取数据的请求
    ...apiList
).done((...res) => {
    if(countPage===1){  //添加判断,对不足一页的数据重新赋值
        deviceList.push(...res[0].page.list)
    }else{
        res.forEach((devicePage)=>{
             deviceList.push(...devicePage[0].page.list)
        })
    }
    self.initCharts();      //执行后续的方法
    self.initMap(res.list);
    self.initMap(deviceList);
    loading.close()
})
    this.firstInit = false
})      
  • Dado que el monitoreo del mapa implica la inserción de webSocket, cada vez que cambien nuevos datos, se modificarán todos los datos adquiridos. Sin embargo, esta inserción de webSocket también enviará una solicitud cuando se soliciten los datos, y se agregará si no hay datos en la matriz, lo que dará como resultado que se obtengan datos inconsistentes cada vez.

Solución: ejecute el método webSocker después de completar la solicitud de datos.

 // 异步分组查询
const pageSize = 2500; //分页大小
const countPage = Math.ceil(self.devicesTotal/pageSize); //总页数
for(let pageNumber = 1; pageNumber<= countPage; pageNumber++) { // 通过循环发送请求,同时每请求成功一次数据处理一些事件
    HJWL_API.getAllDevice('',pageNumber,pageSize).then((res)=>{ //发送请求
        self.devices.push(...res.page.list)
        loading.close()
        …… //执行的逻辑
        }
     // 初始化websocket用于监听服务器单个设备状态变化推送
     self.init_socket(); //监听的方法
})

Supongo que te gusta

Origin blog.csdn.net/qq_45796592/article/details/131030569
Recomendado
Clasificación