zoukankan      html  css  js  c++  java
  • tab切换引起浏览器卡顿

    tab切换引起浏览器卡顿

    最近写了基于 index 索引关联进行切换的tab组件,谁知道频繁点击后,几个浏览器都卡死,连查看 performance 都看不了。在尝试几次后,没能在 chrome 的 performance下看到原因,因为卡的动不了。反而在 firefox 下看到原因了。

    本地代码业务逻辑大致如下

    <!-- tab header -->
    <div data-type="one"><button>one</button></div>
    <div data-type="two"><button>two</button></div>
    <div data-type="three"><button>three</button></div>
    <!-- tab content -->
    <components :is="type"></components>
    

    通过上面按钮点击,动态更改type,从而更新组件。但是由于点击时,不一定点击的是 div,有可能是 button,因而无论点击哪一个都需要找到div,拿到data-type的参数。于是自己便写了一个查找父元素的function。

      function findTargetByClassNameAndTarget (target = {}, className = '') {
          let el = target
          while (!el.classList.contains(className) && el) {
            el = target.parentNode
          }
          return el
        }
    

    初步点击时,并没有任何问题,都能及时响应,但是快速频繁之后就开始。firefox显示这段js一直在运行。我也是醉了。于是换成了下面这样的才得以解决。

      function closest (ele, selector) {
          const matches = ele.matches 
    			|| ele.webkitMatchesSelector
    			|| ele.mozMatchesSelector
    			|| ele.msMatchesSelector
          if (matches) {
            while (ele) {
              if (matches.call(ele, selector)) {
                return ele
              } else {
                ele = ele.parentNode
              }
            }
          }
          return null
        }
    

    思考

    之前为了解决上诉问题,以为是频繁地更新DOM,导致页面重绘重排,从而性能有了影响。但是 el-tab 却没有。看了下代码没有找到明显的优化之处。然后尝试给 点击事件加延迟,componentkeep-alive。一样没有效果。因而以为是不是使用 v-if 导致的。切换为v-show进行处理依旧没有效果。参考网上做法,开启硬件加速 transform: translateZ(0) 依旧没有任何效果,反而还引发其他问题(弹框的fixed定位不准)

    因为tab切换引起的性能问题,网上有很多,我个人觉得这两个将来值得借鉴一二,原理都是 dom 更新完再进行。

    1. 加一个开发,在dom更新完后再进行下一步

      <div id="first" v-if="flag"></div>
      <div id="last" v-else></div>
      <script>
      	...
      	function handleTab () {
      	 if (this.flag) {
             first.show()
             last.hide()
      	   this.flag = false
           } else {
      	  first.hide()
      	  last.show()
      	   this.flag = true
            }
      	}
      	...
      </script>
      
    2. 使用 vueupdate 来进行处理。因为 updated 也是 dom 更新完再执行

    针对上面的代码,尝试了之前写的另一种方式

       function findElementUpward (el, className) {
          let parent = el
          let name = Array.from(parent.classList || [])
          while (parent && (!name.length || !name.includes(className))) {
            parent = parent.parentNode
            if (parent) name = Array.from(parent.classList || [])
          }
          return parent
        }
    

    依旧是没问题。因而对比两者的差距,只是这次取巧使用了自带的 contains 这个方法而已,却没想到导致这么大的问题。只是目前还无法判断是不是这个 contains 导致的性能问题。需要找个方式进行研究一下方可。

    • matchesclosest 功能类似,都可以通过传参来查找指定父元素
  • 相关阅读:
    leetcode 7:binary-tree-preorder-traversal
    leetcode 49:same-tree
    leetcode 45:maximum-depth-of-binary-tree
    leetcode 15:single number
    leetcode开始刷题!
    MFC按行读写文件,亲测有用!
    把字符串转换成整数
    数组中重复的数字
    CSS盒子模型图
    HTML5入门:HTML5的文档声明和基本代码
  • 原文地址:https://www.cnblogs.com/sinosaurus/p/12982207.html
Copyright © 2011-2022 走看看