在ios的safari上bfcache失效
wen911119 opened this issue · 5 comments
Version
2.5.16
Reproduction link
https://github.com/wen911119/vue-bfcache-bug-report
Steps to reproduce
1.git clone
2.npm install
3.npm start
4.用iphone的safari浏览器打开页面
5.滑动一下列表
6.点击跳转到下一页按钮
7.在下一页滑屏返回
What is expected?
在滑屏返回后从bfcache读取页面。页面生命周期不会再次触发,列表也保持在原来位置。
What is actually happening?
onpageshow事件的event.persisted属性为false,说明没有从缓存读取。页面的mounted被重新触发了,列表回到了顶部。
一直用的vue,这个bug我原以为是safari设计的不好。直到今天试了下react,发现react没有这个问题。才意识到这个是vue的问题,作为对比,我也用react创建了个一样的测试例子。https://github.com/wen911119/react-bfcache-test
This is quite an interesting problem. Didn't notice that before.
Translation of this bug report:
When Vue is included in a webpage, back-forward cache no longer works on iOS Safari. That means, when navigating back from any other url, onpageshow
event's persisted
prop always equals false
, and the scroll position does not get preserved.
After some investigation, I found it caused by this line:
vue/src/core/util/next-tick.js
Line 46 in acd92cf
It's the MessageChannel
instance created during Vue's initialization process that prevents Safari from caching this page.
If I understand correctly, as of 2.6.x, Vue.nextTick
uses microtask by default, and MessageChannel
is only used for deferring DOM event callbacks. Maybe we can consider requestAnimationFrame
as an alternative now?
requestAnimationFrame
has too long a delay and is quite indeterministic. We will likely revert to always using microTasks. Using MessageChannel
fixed a few edge cases but caused more problems in the end...