在iOS設(shè)備中,如果使用Vue開(kāi)發(fā)的Web應(yīng)用在運(yùn)行時(shí)出現(xiàn)了假死現(xiàn)象,讓用戶(hù)感受非常不好,這種問(wèn)題的出現(xiàn)主要是由于iOS設(shè)備對(duì)于某些Vue特性的兼容性問(wèn)題造成的。
Vue開(kāi)發(fā)框架可以通過(guò)虛擬DOM實(shí)現(xiàn)高效的數(shù)據(jù)渲染,但是虛擬DOM的實(shí)現(xiàn)是通過(guò)操作DOM對(duì)象來(lái)完成的。在iOS設(shè)備中,由于瀏覽器的Webview所依賴(lài)的線(xiàn)程模型不同,它默認(rèn)的JS線(xiàn)程為單線(xiàn)程,因此如果在多個(gè)線(xiàn)程中同時(shí)對(duì)DOM進(jìn)行操作,就會(huì)發(fā)生死鎖現(xiàn)象。
// 以下是一段會(huì)導(dǎo)致iOS假死的代碼 new Promise((resolve) =>{ document.getElementById('app').innerHTML = 'Hello, World!
'; resolve(); }).then(() =>{ document.getElementById('app').innerHTML = 'Hello, World!'; });
上述代碼通過(guò)Promise實(shí)現(xiàn)了DOM的操作,并在最后使用then方法進(jìn)行更新。但是在iOS設(shè)備中,由于JS線(xiàn)程的單線(xiàn)程特性,可能會(huì)導(dǎo)致DOM的操作被多次執(zhí)行,進(jìn)而造成死鎖匿名函數(shù)的執(zhí)行。
針對(duì)上述問(wèn)題,我們可以通過(guò)一些手段來(lái)保證Vue在iOS設(shè)備中的兼容性。比如我們可以使用vue-lazyload來(lái)解決iOS上的懶加載問(wèn)題,因?yàn)樵摬寮旧砭蛯?shí)現(xiàn)了異步加載技術(shù)來(lái)保證組件的渲染不會(huì)被阻塞。另外,我們可以將DOM的元素?cái)?shù)量盡可能的減少,在使用Vue時(shí)避免使用v-html指令,這樣可以避免瀏覽器對(duì)DOM節(jié)點(diǎn)的頻繁操作。
Vue框架本身也提供了許多解決iOS兼容性的方法。Vue 2.3.0之后,默認(rèn)為所有指令綁定MutationObservers,所以在更新DOM的時(shí)候可以避免頻繁操作。通過(guò)取消多余的事件監(jiān)聽(tīng)和防抖函數(shù)的使用,Vue也可以使得頁(yè)面渲染更加流暢。更重要的是,我們需要盡可能的避免在開(kāi)發(fā)過(guò)程中出現(xiàn)死循環(huán)和遞歸等問(wèn)題,這些問(wèn)題在不同的設(shè)備上會(huì)產(chǎn)生無(wú)法預(yù)測(cè)的后果。
總之,在開(kāi)發(fā)Vue應(yīng)用時(shí),兼容性問(wèn)題是一個(gè)不可避免的問(wèn)題,在iOS設(shè)備上使用Vue開(kāi)發(fā)的時(shí)候我們需要仔細(xì)考慮問(wèn)題的本質(zhì)并采取一系列解決方案來(lái)提升用戶(hù)體驗(yàn)。