vue使用MutationObserver出现的问题

上周在使用vuejs时遇到一个特殊情况,数据的双向绑定失效了!dom无法更新导致页面卡死。

环境是ios版微信,后来经过测试发现其他浏览器也有类似的情况,UC、QQ内置的浏览器,android下倒是不曾出现这种情况。

经过排查后得出结论,凶手就是ios下浏览器的MutationObserver,在复杂的情况下会失效。而vue默认使用MutationObserver作为nextTickHandler的回调。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (typeof MutationObserver !== 'undefined' ) {
var counter = 1
var observer = new MutationObserver(nextTickHandler)
var textNode = document.createTextNode(counter)
observer.observe(textNode, {
characterData: true
})
timerFunc = function () {
counter = (counter + 1) % 2
textNode.data = counter
}
} else {
timerFunc = setTimeout
}

当MutationObserver出问题导致nextTickHandler不回调时,数据的更新是没有问题,但dom的更新却故障了。

貌似在涉及较多数据和dom更新时ios下MutationObserver才会出现问题。

暂时的解决方案是直接把MutationObserver屏蔽掉,Vue会使用setImmediate/setTimeout作为dom更新的回调,虽然会有延迟但总比出问题要好。

1
2
3
4
var userAgent = window.navigator.userAgent;
if (/micromessenger\/(\d+\.\d+\.\d+)/i.test(userAgent)) {
window.MutationObserver = undefined;
}

后来vue也针对这个问题作了处理。commit

参考