How to partition tasks using Iframe in vUE projects!

I. Problem description

Background: two days ago, my colleagues and I have a question, is probably like this, a page in a project using the websocket to obtain the background of real-time data, real-time data every second to get a, a data about 12 groups (may be more), the front-end need group to dynamic mapping it to 12 echarts diagram; The graph is based on this legend, which means that the browser needs to draw more than a dozen of these legends every second. The project is not designed to be paginated or otherwise paginated; So you have to force yourself to draw on one page at a time;

Problem: The problem is that the requirement is to see all data from the beginning to the end of the service, so the socket data is always cached in the front end; And every second needs to be drawn, so with the accumulation of time, the front-end data will be a relatively large increment, and with the accumulation of time to draw the consumption will be more and more large, when we draw to the second minute, there will be the problem of menu stuck;

Analysis: Caton problem is mainly because in the process of drawing every second icon, is essentially a js in the operation process of canvas and perform computations, so it is the task of js thread is too big, the cause of the blocked browser rendering thread, lead to browser within 16 ms have surplus to perform rendering, made the operation of menu click or other look caton, Not smooth;

Solution: there are several solutions, the first can be paging processing, so that the front-end cache data, not so much, and less drawing magnitude, such as real-time drawing a few legend is good, to put it bluntly is task sharing; The second reason is that the business scene is a single-page application, so the whole project has only one HTML, so we can use iframe to nested an IFrame in vUE, so that the drawing task can be executed in this IFrame. No matter how many tasks there are in this IFrame, it will not affect the rendering of the main application, because they are two independent domains. As long as the communication problem is solved, our needs can be better realized;

Second, concrete implementation

1. Document preparation

Before the implementation, I made a small Demo, a preliminary experiment;

Create an ifame. HTML file in the public folder of your project, and then write the main drawing task.

node_modules
|
public
|  |
|  iframe.html
|  |
|  index.html
Copy the code

Then create the following vue file;

<template>
  <div>
    <h1>iframe</h1>
    <button @click="move">mobile</button>
    <div class="div" :style="{transform:`translateX(${distence}px)`}"></div>
    <iframe :src="src" frameborder="0"></iframe>
  </div>
</template>

<script>
export default {
  name:"Iframe".data(){
    return {
      src:"http://localhost:8081/iframe.html".distence:10}},methods: {move(){
      this.distence +=100; }}}</script>

<style>
.div{
  width:100px;height:100px;background-color:red;
  position:relative;
  transition:all 0.5 s linear;
}
</style>
Copy the code

2. Explanation of the problem

I want to explain why the SRC here to use the url and not use relative path or absolute path, because of the iframe SRC attribute must meet a point is the SRC point must be an independent domain, because the iframe tag is ultimately will pack the compiled, no matter in the development environment or production environment, so after packing, In the development environment, even if it points to a new HTML that you have defined, but when compiled, it all points to the current index. HTML, so the content of iframe is the content of index. HTML.

So we need to point SRC to a URL that accesses the contents of iframe.html directly in public to make this work;

In this way, running the project should be ready to use; You can see that the location of iframe is the contents of iframe.html;

3. Iframe task

<! DOCTYPEhtml>
<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>
    <script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.2.2/echarts.common.js"></script>
    <style>
        #echart {
            width: 300px;
            height: 300px;
            border: 1px solid #ccc;
        }
        
        .move {
            width: 100px;
            height: 100px;
            background: red;
        }
    </style>
</head>

<body>
    <div id="echart"></div>
    <script>
        let bar = echarts.init(document.getElementById("echart"));
        let option = {
            xAxis: {
                type: 'category'.data: ['Mon'.'Tue'.'Wed'.'Thu'.'Fri'.'Sat'.'Sun']},yAxis: {
                type: 'value'
            },
            series: [{
                data: [150.230.224.218.135.147.260].type: 'line'}}; bar.setOption(option);let genData = () = > {
            let arr = [];
            for (let i = 0; i < 10000; i++) {
                arr.push(Math.ceil(Math.random() * 100))}return arr
        }
        setInterval(() = > {
            bar.setOption({
                series: {
                    data: genData()
                }
            })
        }, 1000)
    </script>
</body>

</html>
Copy the code

4. Iframe task

Import the ECahrts CDN in iframe and draw it. As you can see, I set it to draw 10000 data per second. It can be said that the cost of drawing is somewhat challenging, but performing an animation in a Vue file, moving blocks; You can see that they are not blocked, because they are completely in different domains

Third, summary

There are other schemes above, here will not be detailed one by one, if there is unreasonable understanding of the place please readers to correct, very grateful!