gaogaotiantian / biliscope

Bilibili chrome extension to show uploader's stats
MIT License
575 stars 45 forks source link

Fix unable to refresh recommended video on the homepage #213

Closed Natrium0521 closed 1 month ago

Natrium0521 commented 1 month ago

Bug原因

我们在换一换之后会将原来的feedcard移出DOM,而如果新刷出来的feedcard中有跟上次一样的广告card,vue会复用这个节点,但是这个节点已经被我们移除了,所以在下次换一换的时候会出问题。

解决方案

由于没有想到优雅的方案获得每次刷新需要的广告card,所以决定把所有出现过的广告节点都存在Set里,同时栈中只存非广告节点,每次操作(换一换、前进、后退)后把所有广告节点追加到最后(后面的card其实不显示,而且广告变来变去也就几种,性能影响不大),这样就保证DOM中一定有要复用的节点。

fix #211

gaogaotiantian commented 1 month ago

这个方法有点太hacky了。

如果在前进后退的时候,始终keep所有的真正的换一换的卡(就是最新刷出来的那几个),只不过在不该显示的时候给他们d-none了,这个问题是不是就解决了?因为我们不会主动去remove任何的本来应该出现的卡片,换一换本来的功能会把这些card清理掉。

Natrium0521 commented 1 month ago

由于没有想到优雅的方案获得每次刷新需要的广告card

之前确实想偏了,以为后退之后再刷新会有多个广告不好区分,没注意到栈中已经不存广告card了,所以就算是后退过,刷新之后显示的广告也一定是需要的广告。

现在改过之后能保证DOM里只追加需要的广告了

gaogaotiantian commented 1 month ago

你先往回退一下,我需要理解一下这个问题的本质。我觉得现在这个方案本身侵入性太强了,而且逻辑过于难以follow了。

首先问题的根源是什么?新刷出来的card里有一个广告card,同时这个广告card在之前什么时候出现过?是在点换一换之前的那些card里有,还是在上次换一换之后刷出来的那里面有?为什么我们需要保存所有出现过的广告,哪怕是我们自己存到stack里的?这个问题有没有一个相对稳定的复现方法,以及有没有不去处理DOM就可以解决问题的方法?

isRefreshing这个东西有用么?还是你之前试fix时候残留的东西?

我觉得首先我要搞清楚这个问题具体是如何触发的,然后再去思考fix。现在这个fix我觉得会引入其他的问题,它有点过于复杂了。

Natrium0521 commented 1 month ago

为什么我们需要保存所有出现过的广告

这个其实不需要了,是我之前没有想到更好的解决方案时的临时替代方案

这个问题有没有一个相对稳定的复现方法

我觉得首先我要搞清楚这个问题具体是如何触发的

首先可以把我们的功能关了(可以把 onRollFeedcard 整段注释掉),然后在B站首页每次换一换前删掉广告的 feed-card 的DOM元素,类似这种的:

image

然后再点换一换,几次之后应该就能触发了

isRefreshing 这个东西有用么?还是你之前试fix时候残留的东西?

这个是后面加的,因为发现在狂点换一换和后退的时候(虽然正常用户不应该这么干),可能在新卡片没有加载出来就被后退了,会有问题,加这个相当于上个锁

Natrium0521 commented 1 month ago

然后再点换一换,几次之后应该就能触发了

触发之后可以去网络面板查看触发前最近的两次rcmd请求,发现推荐的广告是相同的,而之前并没有两次相邻的请求中有相同的广告,所以结论是刷出相同广告导致的问题

image

image

gaogaotiantian commented 1 month ago

首先可以把我们的功能关了(可以把 onRollFeedcard 整段注释掉),然后在B站首页每次换一换前删掉广告的 feed-card 的DOM元素,类似这种的:

如果这样的话,我们的功能开着的时候,应该每次点换一换都会删掉所有的DOM,为啥没法复现呢?你依然没有在我们的功能下复现,你只是找到了一种可以出现这个symptom的方式。或者起码有个理论为什么我们的feature会出现这种情况?如果简单的删除DOM,十几次就可以复现出问题,那我们的换一换为啥复现的几率那么低呢?

Natrium0521 commented 1 month ago

我们的换一换如果刷出了一样的广告同样能复现吧

Natrium0521 commented 1 month ago

https://github.com/user-attachments/assets/2cc9d4f2-822b-4006-bdd0-0c83ab508fc9

不同账号推荐的广告应该不一样,所以重复的概率也不一样,有时候可能刷十几次,有时候刷两次就出了

gaogaotiantian commented 1 month ago

不光是广告的问题。只要有任何一个视频是重复的,我们把这个element删掉都会让B站崩掉。我选择了一个更稳妥的修复方式 #214。现在如果你backward了再换一换,会先把所有的element都替换成backward之前的状态,这样就相当于把remove的工作交还给B站了,简单稳妥。当然问题就是这里会出现一个闪回。我的角度看这是一个相对更好的修复方式。在用户正常使用换一换的时候不会出现任何问题,而后退之后再点也只是多闪了一下。问题修复了我就把这个PR关掉了。