zoukankan      html  css  js  c++  java
  • 【H5疑难杂症】脱离文档流时的渲染BUG

    BUG重现

    最近机票团队在一个页面布局复杂的地方发现一个BUG,非常奇怪并且不好定位,这类问题一般最后都会到我这里,这个问题是,改变dom结构,页面却不渲染!!!

    如图所示,我动态的改变了dom结构,结果页面那一坨变得什么都没有,相当奇怪!!!在PC模拟iPhone就可以重现,iPhone、note4等手机上也可重现,由于这种BUG我不是第一次碰到,很快便引起了注意,总结起来可以归结于:

    js代码改变fixed元素的html结构(一般是动画后并且布局相对复杂),页面不会渲染

    问题定位-分离法

    本着发现问题,定位问题,解决问题的步骤,我开始了定位,这里的难点是,这类问题往往非常难以定位,因为他的dom tree相当复杂,首先我做了一个事情,直接将其htmlcss分离出来,摆脱js的原因,直接显示该dom。

    于是问题不在了,这个很令人费解,难道是js对其造成了影响?经过一轮纠缠,定位失败开始二轮定位。

    问题定位-最小化问题

    这种问题确实不好处理的时候,光靠看页面可能不能处理了,这个时候便把机票的代码拿到本地,部署起来,做了几件事情:

    ① 去掉该页多余的业务代码,基本上不完成任何功能

    ② 去掉多余的dom结构(由于我们是单页应用,dom可能相对比较复杂)

    打开对应业务代码一看,洋洋洒洒3000行,立马想吐:

    这个时候一行行去读代码就是2B的行为了,直接找到那个显示日历的代码:

    然后稍作改动,把其它业务逻辑全部搞掉,事件绑定也搞掉,只留下显示日历的事件,直接一来点击显示日历,这个时候形成的dom结构由4000多行变成了1000多行,但是依旧有BUG

    问题定位-CSS重置

    由于机票对日历的样式,做了重置,所以有理由怀疑是他们自己的css导致的问题,于是想去掉他们的css引用试了试,虽然样式难看了点,但是问题依旧存在......

    问题定位-js逻辑

    这个时候便有理由怀疑其日历显示后,本身有一定逻辑功能导致出错,于是看到了日历show后面干的事情,并且为了防止dom结构过大,将月份显示设置为1月。

    都这个样子了,他居然还是渲染不处理,有点伤害自尊!!!

    因为这个日历显示时候有一个从右到左的动画,这个时候将其动画关掉,却发现问题解决了!!!其中的代码为zepto的实现,不是关键

    $el.css({
          '-webkit-transform': prepareCss,
          transform: prepareCss
    })
      .show()
      .animate({
        '-webkit-transform': 'translate(0, 0)',
        transform: 'translate(0, 0)'
      }, 500, 'ease-in-out', function() {
        $el.css({
          '-webkit-transform': '',
          transform: ''
        });
      });

    问题定位成功-脱离文档流的渲染

    最后问题定位成功,至少从表现和处理来说是定位成功的,简单来说:

    动画执行结束后,如果我改变的是fixed元素中的一个子单元的html,不会有反应,但是我们同时改变static元素便会引起一次渲染,尼玛这是神马鬼!!!

    问题探索-渲染的差异

    为了弄懂这个原因,我们得看到渲染的细节,这里做了一个对比:

    不引起static dom变化

    引起static dom变化

    这里注意观察最后一次paint便可以看见渲染出来的东西不一样,导致这种的差异是什么呢,我们一次次的对比几次不同

    这里做一个差异对比,因为这里的static元素与fixed元素还有一些管理,我们这里操作与之完全无关的元素试试。事实证明没有什么影响,所以这类问题的解决方案是:

    移动端过多定位元素布局时,偶尔操作fixed元素html不会渲染,解决方案是同步改变与之相关的static元素,便会引导渲染

    刚刚使用的是设置html,这里完全可以使用这种做法:

    el.html(el.html())

    可以达到相同的功能,但是问题导致原因依旧不可知......不可说不是一种遗憾!!!如果您知道这个问题的答案,请您留言

  • 相关阅读:
    DataAnnotations
    使用BizTalk实现RosettaNet B2B So Easy
    biztalk rosettanet 自定义 pip code
    Debatching(Splitting) XML Message in Orchestration using DefaultPipeline
    Modifying namespace in XML document programmatically
    IIS各个版本中你需要知道的那些事儿
    关于IHttpModule的相关知识总结
    开发设计的一些思想总结
    《ASP.NET SignalR系列》第五课 在MVC中使用SignalR
    《ASP.NET SignalR系列》第四课 SignalR自托管(不用IIS)
  • 原文地址:https://www.cnblogs.com/yexiaochai/p/4359983.html
Copyright © 2011-2022 走看看