发现问题
今天有客户向我们反馈了一个BUG:一个页面在IE、FireFox、Chrome52中能正常运行,但是在最新版的Chrome53中显示不了???
习惯性的,我们需要客户提供页面在浏览器中的HTML源代码,客户居然告诉我们说:右键打不开!!!
这就怪了,莫非写的代码导致死循环了,然后浏览器崩溃了........
首先和客户确认运行环境:
- 使用了最新版的FineUIPro v3.2.0.4
- 使用了最新版的Chrome 53.0.2785 稳定版
一切看似都是最新的,然后我们让客户在IE浏览器下取到页面的HTML源代码,开始调试
分析问题
拿到页面的HTML源代码,我们在相同的Chrome53中测试,的确浏览器卡死了。
我们的第一反应就是代码中存在死循环,但是奇怪的是为啥Chrome52没有问题呢?不管他,先调试再说
最后,代码跟踪到这里地方:
其实这就是jQuery的一个DOM节点的插入操作,但是执行完这条语句后,浏览器就卡死,没反应了。
这个代码的简化示例代码如下:
$('<div></div>').appendTo('body');
其实就是对 jQuery 的 appendTo 方法的调用,这让我们的焦点转向了 jQuery,莫非是 jQuery 对 Chrome 53 不兼容?
如果存在这么严重的问题,网络上应该早就有人遇到了。但实际上没有一个人提出类似的问题,并且我们使用的 jQuery 也是最新版:v1.12.4
为了避免 FineUIPro 的客户端 JavaScript 的影响,我们把 me._fjs_el DOM 节点的内容单独拿出来,在页面上执行:
$('<div id="Panel7" class="f-panel f-panel-viewport f-cmp ui-widget" style="margin: 5px; display: block;">'+ '<div id="Panel7_Toolbar1" class="f-toolbar f-toolbar-align-left f-panel-toolbar-top ui-widget-content f-cmp ui-widget" style="display: block;"></div>'+ '<div class="f-panel-body" style="padding: 0px; overflow: auto;">'+ '<div id="fineui_0" class="f-panel ui-widget-content f-panel-border f-cmp ui-widget f-layout-vbox-item" style="margin: 5px; display: block;"></div>'+ '</div>'+ '</div>').appendTo('body')
结果是,执行完这段代码后,浏览器直接卡死:
此时,我们来到 CPU 的占用居高不下:
莫非,是 DOM 节点有问题,比如少了闭合标签之类的,导致Chrome53解析出的问题??
仔细检查后,我们确认了 DOM 节点一切正常!!
好吧,那就来折半分析问题,先删除一部分代码,发现如下两段删除了一个 DIV 节点的代码都能正常运行:
$('<div id="Panel7" class="f-panel f-panel-viewport f-cmp ui-widget" style="margin: 5px; display: block;">'+ '<div id="Panel7_Toolbar1" class="f-toolbar f-toolbar-align-left f-panel-toolbar-top ui-widget-content f-cmp ui-widget" style="display: block;"></div>'+ '<div class="f-panel-body" style="padding: 0px; overflow: auto;">'+ '</div>'+ '</div>').appendTo('body')
$('<div id="Panel7" class="f-panel f-panel-viewport f-cmp ui-widget" style="margin: 5px; display: block;">'+ '<div class="f-panel-body" style="padding: 0px; overflow: auto;">'+ '<div id="fineui_0" class="f-panel ui-widget-content f-panel-border f-cmp ui-widget f-layout-vbox-item" style="margin: 5px; display: block;"></div>'+ '</div>'+ '</div>').appendTo('body')
无厘头,本身删除的 DIV 节点都没有任何问题。更无厘头的事情时,经过好多次尝试,我们发现把原始HTML代码中 class 属性改个字符就能正常运行了:
$('<div id="Panel7" class="f-panel f-panel-viewport f-cmp ui-widget" style="margin: 5px; display: block;">'+ '<div id="Panel7_Toolbar1" class="f-toolbar f-toolbar-align-left f-panel-toolbar-top ui-widget-content f-cmp ui-widget" style="display: block;"></div>'+ '<div class="f-panel-body" style="padding: 0px; overflow: auto;">'+ '<div id="fineui_0" class="f-panel ui-widget-content f-panel-border f-cmp ui-widget f-layout-vbox-iter" style="margin: 5px; display: block;"></div>'+ '</div>'+ '</div>').appendTo('body')
好吧!这还有啥好说的,这是Chrome53本身的BUG无疑!
小结:上面的代码可复现,如果你不信,可以自己试下。
首先随便找到一个引用了 jQuery 的页面,如果不好找,可以用我们产品的示例页面:http://fineui.com/demo_pro/
打开 Chrome53, F12 打开调试窗口,执行如下代码:
$('<div id="Panel7" class="f-panel f-panel-viewport f-cmp ui-widget" style="margin: 5px; display: block;">'+ '<div id="Panel7_Toolbar1" class="f-toolbar f-toolbar-align-left f-panel-toolbar-top ui-widget-content f-cmp ui-widget" style="display: block;"></div>'+ '<div class="f-panel-body" style="padding: 0px; overflow: auto;">'+ '<div id="fineui_0" class="f-panel ui-widget-content f-panel-border f-cmp ui-widget f-layout-vbox-item" style="margin: 5px; display: block;"></div>'+ '</div>'+ '</div>').appendTo('body')
浏览器卡死!!!
然后,重新启动 Chrome53,执行如下代码:
$('<div id="Panel7" class="f-panel f-panel-viewport f-cmp ui-widget" style="margin: 5px; display: block;">'+ '<div id="Panel7_Toolbar1" class="f-toolbar f-toolbar-align-left f-panel-toolbar-top ui-widget-content f-cmp ui-widget" style="display: block;"></div>'+ '<div class="f-panel-body" style="padding: 0px; overflow: auto;">'+ '<div id="fineui_0" class="f-panel ui-widget-content f-panel-border f-cmp ui-widget f-layout-vbox-iten" style="margin: 5px; display: block;"></div>'+ '</div>'+ '</div>').appendTo('body')
浏览器正常运行!!
解决问题
既然是 Chrome53 的BUG,就等 Chrome官方出更新版本吧....
刚下载的最新版:53.0.2785.116 仍然可重现这个问题,有兴趣的同学可以自己试下(由于google官网无法访问,可以方便的通过baidu下载)。