zoukankan      html  css  js  c++  java
  • 移动端页面滚动性能调优

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

    -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操作变引起了页面的卡顿。找到了源头我们处理一下相关代码问题就解决了。

     
     
     
  • 相关阅读:
    ES6-10笔记(class类)
    ES6-10笔记(let&const -- Array)
    小程序的表单提交
    小程序表单回显
    小程序template模板的使用和模板多数据传递
    微信小程序的初始配置
    babel 版本原因运行报错,解决办法
    webpack 和 webpack-cli 安装和使用中出现的问题
    jQuery中操作属性的方法attr与prop的区别
    javaScript 添加和移除class类名的几种方法
  • 原文地址:https://www.cnblogs.com/guochongbin/p/10612858.html
Copyright © 2011-2022 走看看