当前位置:首页 > 生活 > 正文

为什么我的render渲染速度这么慢?这里有提速秘诀

为什么我的render渲染速度这么慢?这里有提速秘诀

为什么我的render渲染速度这么慢?这里有提速秘诀 最近一直在搞前端渲染这块,脑袋都要炸了。以前觉得这玩意儿,浏览器都给你搞定了,我们写代码的操心结果项目跑起来一看,...

为什么我的render渲染速度这么慢?这里有提速秘诀

最近一直在搞前端渲染这块,脑袋都要炸了。以前觉得这玩意儿,浏览器都给你搞定了,我们写代码的操心结果项目跑起来一看,卡得不行,用户体验贼差。我赶紧扎进去研究了一圈,发现渲染慢真不是浏览器的问题,主要是我们自己搞事情。

我先从最简单的排查开始。我把页面拆开来看,最开始怀疑是DOM结构太复杂了。你想,一层套一层,几百个元素堆在一起,浏览器光是计算这些元素的布局就得转半天圈。

  • 我拿开发者工具打开了Performance面板,开始录制页面加载和交互过程。
  • 放大去看Layout和Recalculate Style阶段,发现时间占比特别高。
  • 找到那些深度嵌套特别厉害的组件,立马动手简化结构。该用Flexbox和Grid的就用,不搞那些过时的浮动布局了。

结构优化了一波后,感觉好像快了那么一点点,但核心问题还在。接着我就盯上了样式(Style)。样式写得烂,浏览器计算起来就得费劲。

为什么我的render渲染速度这么慢?这里有提速秘诀

样式计算大户

我发现很多样式都是全局的,特别是那种用了ID选择器或者通配符()的。这些东西一旦触发,浏览器就要回溯查好几条街,性能肯定要跪。

  • 我开始清理全局CSS,把那些污染全局的样式都收回到组件内部。
  • 把一些复杂的伪类选择器替换成更直接的类选择器。
  • 更狠的是,我发现某个模块有个动画效果,居然是整个DOM树在重排(Reflow)。我赶紧定位那个动画,把触发重排的属性换成了触发重绘(Repaint)的属性,比如把改变`width`换成改变`transform`。这一下,FPS稳多了。

这还没完。代码跑起来,数据一多,又是卡顿。我意识到,数据更新触发的重新渲染才是大头。

组件更新的玄机

我用的是React(虽然原理都差不多),发现一个组件的State一变,它下面的所有子组件,不管需不需要,都会跟着重新渲染一遍。这就是典型的“大树抖一抖,所有叶子都跟着动”。

  • 我赶紧在那些不常变的子组件上加了`*`(或者Class组件的`shouldComponentUpdate`)。
  • 测了一下,果然,那些静态展示的模块,在父组件State变动时,渲染时间蹭蹭地往下掉。
  • 对于那些列表数据,我用了虚拟列表(Virtual List),只渲染视口内的那几十个元素,几千条数据瞬间流畅得像丝般顺滑。

我回头看了一下那些初始加载的脚本和资源。代码打包体积太大,浏览器下载、解析和执行都要花老鼻子时间。

为什么我的render渲染速度这么慢?这里有提速秘诀
  • 我设置了代码分割(Code Splitting),把不常用的模块拆出来按需加载。
  • 用上Tree Shaking,把那些没用的库函数统统干掉。
  • 图片资源全部懒加载,首屏看不到的图,等用户滚到底部再说。

折腾了这么一圈,从DOM结构到样式计算,再到组件更新策略,到资源加载,里里外外优化了个遍。再回头跑一遍Performance测试,渲染时间果然大幅度缩短了。这感觉,就像把一辆老旧的拖拉机,硬生生给它调校成了跑车,看着那时间条缩短,心里别提多舒坦了。

最新文章