Le temps de requête pour des dizaines de milliers de données sur le backend (ce bug est de 20 000 données) est trop lent, le plan d'optimisation du front-end et les problèmes qui surviennent lors du processus de solution

Table des matières

Chapitre 1 Préface Description

Chapitre 2 Processus de résolution de problèmes

2.1 Analyser la cause du problème

2.2 Compréhension de $.when()

2.3 Processus de résolution

2.3.1 Traiter les symptômes mais pas la cause racine (pour le cas d'un stockage insuffisant lorsque les données sessionStore sont trop nombreuses : 12s+)

2.3.2 Mettez les statistiques de la deuxième page dans le traitement de page nécessaire, puis stockez-les dans le stockage (12s +)

2.3.3 Le démarrage du traitement prend beaucoup de temps (interface de pagination de requête synchrone 12s+ -> environ 8s)

2.3.4 Le temps de traitement est plus court (données de requête asynchrones, traitement pendant la requête : 3s-6s)

2.3.5 Interludes au milieu (pagination et websocket push)


Chapitre 1 Préface Description

  • Description : dans le processus de travail, j'ai rencontré une telle situation. Il y a une quantité particulièrement importante de données sous un compte, avec près de 20 000 éléments de données. Le résultat de la requête est placé dans le stockage de session temporaire (sessionStore), puis le les données sont extraites du stockage temporaire lorsque les données sont nécessaires
  • Les méthodes qui regardent uniquement le code source et utilisent les données de la requête sont : window.HJWL_API --> requête pour chaque API, $.when().done(function(){}).then(function(){}) --> À utiliser lors du traitement de plusieurs demandes en même temps

Chapitre 2 Processus de résolution de problèmes

2.1 Analyser la cause du problème

  • Avec l'augmentation de la partie A à l'avenir, les données correspondantes continueront également d'augmenter, entraînant des dizaines de milliers de données sous un administrateur à l'étape ultérieure, et le temps de traitement de la demande deviendra plus long lors de l'obtention des données de l'appareil.
  • En raison de l'utilisation du stockage temporaire, il existe un autre problème selon lequel lorsque les données demandées sont trop volumineuses, elles dépasseront la mémoire, ce qui entraînera une erreur

2.2 Compréhension de $.when()

Pour les requêtes window.HJWL_API, il y a un point où l'interface a été traitée après chaque requête de données et les données ont été obtenues, mais toutes les données obtenues seront toujours obtenues après la mise en œuvre de la logique de code complète, ce qui entraînera la logique de code à Les données ne peuvent pas être obtenues pendant le processus (il n'est pas correct de le comprendre comme une tâche macro, donc je suis confus)

$.when() a résolu beaucoup de problèmes pour moi : la méthode peut être comprise de cette manière : seules différentes méthodes de demande de données sont exécutées sous $.when(), puis les données peuvent être obtenues sous .done et le correspondant la méthode est exécutée

2.3 Processus de résolution

2.3.1 Traiter les symptômes mais pas la cause racine (pour le cas d'un stockage insuffisant lorsque les données sessionStore sont trop nombreuses : 12s+)

A cette époque, parce qu'il était pressé, il n'y avait pas de recherche approfondie particulière, mais simplement ajouté l'interface utilisée pour obtenir le nombre total dans les deux pages, résolvant ainsi le problème de cache insuffisant

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

La raison pour laquelle il est traité en passant des paramètres est que les données demandées par cette méthode sont les dernières

Après avoir utilisé cette solution, la page de carte et une page de statistiques doivent demander des données à chaque fois, ce qui entraîne une longue attente pour chaque chargement, et l'effet n'est pas bon

2.3.2 Mettez les statistiques de la deuxième page dans le traitement de page nécessaire, puis stockez-les dans le stockage (12s +)

Bien que cette solution ait grandement optimisé la deuxième page, elle a un défaut qu'elle doit passer par la première page, de sorte que lorsque certaines personnes n'empruntent pas le chemin habituel, il n'y aura pas de rendu de données, ce qui est aussi une solution opportuniste.

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

2.3.3 Le démarrage du traitement prend beaucoup de temps (interface de pagination de requête synchrone 12s+ -> environ 8s)

  •  Négocier avec le backend pour fournir une interface de pagination
  • Annoté de nombreux endroits dans le code qui utilisent des minuteries. Bien que ces méthodes de délai forcé soient utilisées pour obtenir des données, il n'y a plus besoin d'une interface de pagination maintenant (lorsque j'ai fini de les traiter, le temps de demande passe des 12 secondes d'origine à 8 secondes ) -- c'est le traitement du code actuel, mais 8 secondes n'est pas stable , car toutes les données sont toujours récupérées
  • Utilisez $.when pour obtenir des données de l'interface de pagination (pour le moment, la demande est toujours envoyée de manière synchrone)
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
})                 

Après avoir utilisé cette méthode, il s'est essentiellement stabilisé à 8 secondes

2.3.4 Le temps de traitement est plus court (données de requête asynchrones, traitement pendant la requête : 3s-6s)

  • Cette fois, nous n'avons pas envoyé de requête de pagination, traité la méthode correspondante une fois, obtenu les données correspondantes, puis continué à traiter la méthode correspondante lors de l'envoi de la deuxième requête, de sorte qu'il y a un effet de rendu dynamique des données sur la carte, et enfin le temps raccourci à 3-6 secondes, et a également un effet dynamique
  • La raison pour laquelle la méthode est exécutée sous la requête ici est que la logique de traitement des données ne sera obtenue que lorsque la méthode de requête correspondra, ce qui est normalement affiché à la fin, ce qui entraînera la non-obtention des données
 // 异步分组查询
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 Interludes au milieu (pagination et websocket push)

  •  Lorsque les données font moins d'une page, une erreur est signalée, ce qui n'est pas réfléchi
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
})      
  • Étant donné que la surveillance de la carte implique le push webSocket, chaque fois que de nouvelles données changent, toutes les données acquises seront modifiées. Cependant, cette poussée webSocket enverra également une demande lorsque les données sont demandées, et elle sera ajoutée s'il n'y a pas de données dans le tableau, ce qui entraînera des données incohérentes obtenues à chaque fois.

Solution : exécutez la méthode webSocker une fois la demande de données terminée.

 // 异步分组查询
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(); //监听的方法
})

Je suppose que tu aimes

Origine blog.csdn.net/qq_45796592/article/details/131030569
conseillé
Classement