美文网首页
当面试官问你:怎么处理百万条数据渲染的性能问题?

当面试官问你:怎么处理百万条数据渲染的性能问题?

作者: 杨同学a | 来源:发表于2023-08-27 14:10 被阅读0次

    不要再回答使用分页或者文档碎片了

    回答分页 ,不是很贴切考官的问题,考官也不会想听到这样的答案,
    第二 ,文档碎片 ,这是使用js 操作dom 的时候需要用到,需要动态生成原生dom,在vue的项目里使用比较不方便。能回答到这个勉强可以。

    我推荐的是:window.requestAnimationFrame
    requestAnimationFrame是HTML5中提供的动画API,简称rAF,即请求动画帧。可以让浏览器优化并行的动画动作,更合理的重新排列动作序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果。

    浏览器每次渲染一秒钟渲染60次 1000ms/60s , 即 每毫秒16.6次 。
    当我们页面的数据超级多的时候,一次性就渲染全部的数据,就会造成页面卡顿
    我们来看下一个例子:


    image.png

    右边是渲染的dom 每个div盒子里面包含了n个div块,数量其实并不多。但是等待页面却花了十秒钟的时间
    通过性能调试面板可以看到 浏览器装载只需要1毫秒 执行js 脚本花了 5秒多 ,渲染也花了四秒多,总计 10秒左右。


    image.png

    看看代码如何写的,可以看到就是嵌套了两个循环一个 ,两个循环一百次 ,总的差不多是百万循环了,js一次性就加载,是需要十秒,这个时候浏览器是一直白屏的,需要等待差不多九秒,页面才出来东西

    image.png

    看看使用了 requestAnimationFrame 优化之后 前后对比,速度不是一般的快.

    实际上就是 浏览器分开渲染,n毫秒内渲染前面几个div盒子。一直在渲染,直到渲染完毕。相当是把十秒钟拆分成每一秒渲染前多少个div,以此类推。这样用户一进来就能看到前半段的东西,剩余的浏览器会慢慢加载,并不会影响前面的显示,这样一样来就能解决这种性能的问题,也不会影响用户体验。


    image.png

    完整的代码示例

    <!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>defer</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
    
            .box {
                width: 100vw;
                height: 100vh;
                display: flex;
                flex-wrap: wrap;
            }
    
            .block {
                width: 400px;
                margin: 20px;
                height: 400px;
                border: 1px solid red;
                display: flex;
                flex-wrap: wrap;
            }
    
            .item {
                width: 6px;
                height: 6px;
                background: #000;
                margin: 1px;
            }
        </style>
    </head>
    
    <body>
        <div id="app" class="box">
            <template v-for="(item,index) in 1000">
                 <!-- 默认显示优化后的代码 -->
                <!-- 使用没有用requestAnimationFrame优化之前的渲染代码可以将v-if="defer(index)" 删掉即可 -->
                <div class="block" v-if="defer(index)">
                    <div class="item" v-for="(sub,index) in 1000"></div>
                </div>
            </template>
        </div>
    </body>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.2.6/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    frameCount: 0,
                }
            },
            mounted() {
                const refreshFrameCount = (maxFrameCount) => {
                    requestAnimationFrame(() => {
                        this.frameCount++
                        if (this.frameCount < maxFrameCount) {
                            refreshFrameCount(maxFrameCount)
                        }
                    })
                }
                refreshFrameCount(500)
            },
            methods: {
                defer(showInFrameCount) {
                    return this.frameCount >= showInFrameCount
                }
            }
        })
    </script>
    
    </html>
    

    相关文章

      网友评论

          本文标题:当面试官问你:怎么处理百万条数据渲染的性能问题?

          本文链接:https://www.haomeiwen.com/subject/yelwmdtx.html