网页端 B 站卡顿,有什么解决办法吗?

很多方法都试过了,包括切换编码方式、硬件加速,禁用插件,还有各种实验性开关的flag,都没有解决。

主要的现象就是一到卡的时候,弹幕、视频,都卡住,鼠标、键盘、滚轮都没反应,甚至鼠标箭头都会消失。

我主要用Chrome, mac 和 windows都卡,Safari 不常用,测试的时候好像不怎么卡。

但是Safari 在切换视频速度的时候总会卡一下,这个也不知道为什么。我写了个js脚本,绑定了一件倍速,还挺常切换倍速的,Safari每次切换都卡半秒钟,这个有点受不了。Chrome切换速度虽然比较丝滑,但是经常整个页面卡住,一卡就是几秒甚至十几秒。

我录制了一下Performance,发现每次卡都是卡在同一个函数时间很长,但是这个函数看起来也没有什么问题,很轻量的操作。

有没有大佬分析一下什么原因?实在是受不了了。

有办法修改或者调试这部分代码吗?

28 个赞

帮顶,马克思在回复!

5 个赞

不如痛骂鼠鼠,写的这狗屎一样的前端性能

相比之下YouTube画质高而且流畅

5 个赞

这个是真的,我本来以为是我电脑性能的问题,结果B站码率也低,而且我调的 1080p, youtube 4k 都不卡

2 个赞

之前也有卡 B 站的情况,主要是全屏播放有弹幕的时候,隔一段时间就卡爆炸,直播有弹幕的时候卡得更快。

那时尝试过调解码方式、开关硬件加速、系统添加高性能等等,甚至显卡选项也调来调去。但就是完全解决不了,无论是 Edge 还是 Chrome 都不行,后来不了了之了。

之后因为 Edge 一直偷偷加料,然后原本就是 Chrome 转 Edge 来着,所以最终选择了转 FireFox。然后突然一下发现阿 B 看视频、直播放弹幕居然都不卡了!!!离谱…

不好说是硬件、Chromium 还是阿 B 的问题,但反正现在是一点问题没有。

1 个赞

我记得Edge 有画质增强的功能

1 个赞

我的也卡,应该是我用的插件太多了,好几个B站插件,弄得每次都很卡

那会能开关的功能都试了一遍的,Edge 和 Chrome 来回测试,卸载重装或禁用插件,亦或安全 DNS、Clash 那种影响网络的都统统试过开关卸载等测试,但还是完全解决不了全屏播放卡顿的问题。

只能说要么硬件和 Chromium 八字不合,要么阿 B 有问题,在我这真无解。

1 个赞

那我先试试 firefox 吧,Chrome 暂时还是离不开,先用 Firefox 看视频

b站的问题,无论什么浏览器都有概率卡顿

我从核显换成显卡就不卡了,就一张二手的1070Ti,后面换成一张p106也不卡(捡垃圾 :slightly_smiling_face:
另外检查一下网络,wifi会卡,千兆wifi和网卡也卡,然后我换成网线直连就不卡 :confused:

原来不是我一个人卡

编码选没有,选av1或者avc

可以下载电脑客户端版,缺点是B站相关的浏览器扩展不能用了

三种编码都一样。 我刚试了一下firefox,竟然一点都不卡。之前chrome的时候不播放视频,连B站主页都卡。

这个确实不卡

选过啦,真的全都试过,我也很好奇到底为什么会卡,但在我这,这个问题真的解决不了,无论怎么调它们都没用。:melting_face: :melting_face:

其实客户端我这边也试用过,一开始确实不会卡,但用久了,照旧还是会卡爆炸的,甚至卡得更彻底,需要任务管理器强制退出才行,哎,在我这真的完全无解。:melting_face: :melting_face:

更新下显卡驱动

1、换浏览器chrome、360

2、切换编码(播放策略),如AVC(最清晰)或AV1

3、禁用webrtc

4、禁用/替换pcdn

添加过滤规则(adguard浏览器插件或者adguard home)

||*pcdn*.biliapi.net^
||mcdn.bilivideo.cn^
||szbdyd.com^
||cn-*.bilivideo.com^
||cn-*.bilivideo.cn^

(建议别直接在规则里禁用 data.bilibili.com 上报,不然控制台一直报错,疯狂重试请求,甚至直接在规则里添加 @@||data.bilibili.com^$important 给它放行比较好,在其他地方其他办法禁上报)

5、油猴优化脚本:

(摘自 Make BiliBili Great Again 的一部分,因为个人只需要这一部分,加上一些其余代码)
(或者直接安装 Make BiliBili Great Again 试试)

// ==UserScript==
// @name         B站优化
// @namespace    http://tampermonkey.net/
// @version      2024-10-21
// @description  try to take over the world!
// @author       代码来自Make BiliBili Great Again的一部分
// @match        https://*.bilibili.com/*
// @icon   data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @run-at       document-end
// @grant        unsafeWindow
// @grant        GM_addStyle
// @grant        GM_notification
// ==/UserScript==

(function() {
    'use strict';

    // 没用的 URL 参数
    const uselessUrlParams = [
        'buvid',
        'is_story_h5',
        'launch_id',
        'live_from',
        'mid',
        'session_id',
        'timestamp',
        'up_id',
        'vd_source',
        /^share/,
        /^spm/,
    ];

    try {
        Object.defineProperty(unsafeWindow, 'webkitRTCPeerConnection', { value: undefined, enumerable: false, writable: false });
    } catch (e) { }

    delete unsafeWindow.RTCPeerConnection;
    delete unsafeWindow.mozRTCPeerConnection;
    delete unsafeWindow.webkitRTCPeerConnection;

    Object.defineProperty(unsafeWindow, 'PCDNLoader', { value: class { }, enumerable: false, writable: false });
    Object.defineProperty(unsafeWindow, 'BPP2PSDK', { value: class { on() { } }, enumerable: false, writable: false });
    Object.defineProperty(unsafeWindow, 'SeederSDK', { value: class { }, enumerable: false, writable: false });
    if (location.href.startsWith('https://www.bilibili.com/video/') || location.href.startsWith('https://www.bilibili.com/bangumi/play/')) {
        let cdnDomain;

        function replaceP2PUrl(url) {
            cdnDomain ||= document.head.innerHTML.match(/up[\w-]+\.bilivideo\.com/)?.[0];

            try {
                const urlObj = new URL(url);
                const hostName = urlObj.hostname;
                if (urlObj.hostname.endsWith(".mcdn.bilivideo.cn")) {
                    urlObj.host = cdnDomain || 'upos-sz-mirrorcoso1.bilivideo.com';
                    urlObj.port = 443;
                    console.warn(`更换视频源: ${hostName} -> ${urlObj.host}`);
                    return urlObj.toString();
                } else if (urlObj.hostname.endsWith(".szbdyd.com")) {
                    urlObj.host = urlObj.searchParams.get('xy_usource');
                    urlObj.port = 443;
                    console.warn(`更换视频源: ${hostName} -> ${urlObj.host}`);
                    return urlObj.toString();
                }
                return url;
            } catch (e) {
                return url;
            }
        }

        function replaceP2PUrlDeep(obj) {
            for (const key in obj) {
                if (typeof obj[key] === 'string') {
                    obj[key] = replaceP2PUrl(obj[key]);
                } else if (typeof obj[key] === 'array' || typeof obj[key] === 'object') {
                    replaceP2PUrlDeep(obj[key]);
                }
            }
        }

        replaceP2PUrlDeep(unsafeWindow.__playinfo__);

        (function (open) {
            unsafeWindow.XMLHttpRequest.prototype.open = function () {
                try {
                    arguments[1] = replaceP2PUrl(arguments[1]);
                } finally {
                    return open.apply(this, arguments);
                }
            }
        })(unsafeWindow.XMLHttpRequest.prototype.open);
    }


    // 去除地址栏多余参数
    unsafeWindow.history.replaceState(undefined, undefined, removeTracking(location.href));
    const pushState = unsafeWindow.history.pushState;
    unsafeWindow.history.pushState = function (state, unused, url) {
        return pushState.apply(this, [state, unused, removeTracking(url)]);
    }
    const replaceState = unsafeWindow.history.replaceState;
    unsafeWindow.history.replaceState = function (state, unused, url) {
        return replaceState.apply(this, [state, unused, removeTracking(url)]);
    }

    function removeTracking(url) {
        if (!url) return url;
        try {
            const [base, search] = url.split('?');
            if (!search) return url;
            const searchParams = new URLSearchParams('?' + search);
            const keys = Array.from(searchParams.keys());
            for (const key of keys) {
                uselessUrlParams.forEach(item => {
                    if (typeof item === 'string') {
                        if (item === key) searchParams.delete(key);
                    } else if (item instanceof RegExp) {
                        if (item.test(key)) searchParams.delete(key);
                    }
                });
            }
            if (location.pathname === base && !searchParams.size) return;
            return [base, searchParams.toString()].filter(Boolean).join('?');
        } catch (e) {
            return url;
        }
    }

    // 去掉 B 站的傻逼上报
    !function () {
        const oldFetch = unsafeWindow.fetch;
        unsafeWindow.fetch = function (url) {
            if (typeof url === 'string' && url.includes('data.bilibili.com'))
                return Promise.resolve(new Response());
            return oldFetch.apply(this, arguments);
        }
        const oldSend = unsafeWindow.XMLHttpRequest.prototype.open;
        unsafeWindow.XMLHttpRequest.prototype.open = function (method, url) {
            if (typeof url === 'string' && url.includes('data.bilibili.com')) {
                this.send = function () { };
                return;
            }
            return oldSend.apply(this, arguments);
        }
        unsafeWindow.navigator.sendBeacon = () => Promise.resolve();

        unsafeWindow.MReporter = function () { };
        unsafeWindow.MReporter.appear = function () { };
        unsafeWindow.MReporter.click = function () { };
        unsafeWindow.MReporter.tech = function () { };
        unsafeWindow.MReporter.pv = function () { };
        unsafeWindow.MReporter.import = { auto() { } };

        const sentryHub = class { bindClient() { } }
        const fakeSentry = {
            SDK_NAME: 'sentry.javascript.browser',
            SDK_VERSION: '0.0.0',
            BrowserClient: class { },
            Hub: sentryHub,
            Integrations: {
                Vue: class { },
                GlobalHandlers: class { },
                InboundFilters: class { },
            },
            init() { },
            configureScope() { },
            getCurrentHub: () => new sentryHub(),
            setContext() { },
            setExtra() { },
            setExtras() { },
            setTag() { },
            setTags() { },
            setUser() { },
            wrap() { },
        }
        if (!unsafeWindow.Sentry || unsafeWindow.Sentry.SDK_VERSION !== fakeSentry.SDK_VERSION) {
            if (unsafeWindow.Sentry) { delete unsafeWindow.Sentry }
            Object.defineProperty(unsafeWindow, 'Sentry', { value: fakeSentry, enumerable: false, writable: false });
        }
        Object.defineProperty(unsafeWindow, 'ReporterPb', { value: class { click() { } custom() { } exposure() { } report() { } tech() { } pv() { } }, enumerable: false, writable: false });

        Object.defineProperty(unsafeWindow, '__biliUserFp__', {
            get() { return { init() { }, queryUserLog() { return [] } } },
            set() { },
        });
        Object.defineProperty(unsafeWindow, '__USER_FP_CONFIG__', { get() { return undefined }, set() { } });
        Object.defineProperty(unsafeWindow, '__MIRROR_CONFIG__', { get() { return undefined }, set() { } });
    }()
})();

个人感觉,window,(已经是AVC编码,这个编码画质最好)画质最好的是360安全浏览器,其次是chrome,只有一点差距,最差的是edge,edge是真的糊,直播也一卡一卡的。但整体使用而言,还是chrome更好一点。

2 个赞