• 移动端页面滚动性能调优


    最近在做一个可视化平台的移动端适配,遇到了在移动端页面滚动卡顿的情况,遂进行了一些优化,做一小记:

    -webkit-overflow-scrolling: touch
    -webkit-transform: translateZ(0px)

    上网搜索移动端滑动卡顿,出现次数最多的解决方案便是这两个。他们的原理其实差不多,遇到上述属性时浏览器会创建一个新的layer,layer中的各种操作会使用一个新的线程去处理,所以某些情况下确实可以提高滚动性能。
    当然也不是layer越多越好,因为每次生成一个新的layer,需要额外进行一次composite的操作,也需要耗费时间。
    不过这两个方案对我都没什么用处。

    iscroll

    既然原生滚动折腾半天没有什么起色,那么想到用iscroll来做页面模拟滚动,可能会好点。用了以后确实有所提高,不过ios依然略卡,adr相当卡。并且引申出了其他两个问题:

    1. 处于性能考虑,iscroll默认在touchStart的时候,将event preventDefault了,导致touch之后的click事件将不再触发
    2. overflow:scorll的组件不再触发scroll

    为解决这个问题我也大费周章,通过全局变量控制了下特定情况下才进行preventDefault。然而问题还是没有彻底解决。

    performance分析

    让我们来看看引起页面卡顿的罪魁祸首:

    没错,就是这个react-draggable库中的getControlPosition方法。让我们来看看这个方法都干了什么:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function getControlPosition(e /*: MouseTouchEvent*/, touchIdentifier /*: ?number*/, draggableCore /*: DraggableCore*/) /*: ?ControlPosition*/ {
    var touchObj = typeof touchIdentifier === 'number' ? (0, _domFns.getTouch)(e, touchIdentifier) : null;
    if (typeof touchIdentifier === 'number' && !touchObj) return null; // not the right touch
    var node = _reactDom2.default.findDOMNode(draggableCore);
    // User can provide an offsetParent if desired.

    var offsetParent = draggableCore.props.offsetParent || node.offsetParent || node.ownerDocument.body;

    return (0, _domFns.offsetXYFromParent)(touchObj || e, offsetParent);
    }

    注意第7行,他尝试去获取一个node的offsetParent, 这个操作会直接引起浏览器的reflow。所以大量的reflow操作变引起了页面的卡顿。找到了源头我们处理一下相关代码问题就解决了。

     
     
     
  • 相关阅读:
    【01】国内外git托管平台(总结by魔芋)
    【01】git下载和安装的完整过程
    分享一些正确的放松方式
    【03】图解原型和原型链by魔芋
    求一个正整数的阶乘
    乘法表
    Web Best Practices
    【03】const
    【02】块级作用域
    【01】let和const命令
  • 原文地址:https://www.cnblogs.com/guochongbin/p/10612858.html
Copyright © 2020-2023  润新知