Bilibili-Evolved 高分辨率图片组件(imageResolution)深度解析:DPI 缩放下的图片源替换原理与配置指南
2026/9/19 4:27:14 网站建设 项目流程

Bilibili-Evolved 高分辨率图片组件(imageResolution)深度解析:DPI 缩放下的图片源替换原理与配置指南

【免费下载链接】Bilibili-Evolved强大的哔哩哔哩增强脚本项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved

导读

「高分辨率图片」是 Bilibili-Evolved 内置的实用工具类组件,其核心职责是:当屏幕 DPI 缩放超过 200% 时,自动将哔哩哔哩页面中按@xxxw/@xxxw_xxh规则裁剪缩略的图片替换为更高分辨率的图片源,从而让高分屏用户获得清晰的浏览体验。本文以组件文档 image-resolution/index.md 为骨架,结合源码逐层讲解其工作流程、缩放算法、两个配置选项的语义,以及加载变慢、图片闪动、比例失衡等已知问题的成因与规避方法,帮助你正确启用与调优该组件。

一、组件定位:为什么需要"高分辨率图片"

哔哩哔哩的图片服务(如头像、封面、动态配图)在绝大多数场景下都会返回经过尺寸裁剪的缩略图,URL 中携带形如@672w_378h@96w的缩放后缀。在普通屏幕上这些缩略图足够清晰,但在 Retina 屏、4K 屏等高 DPI 设备上,系统会以高于 1 的逻辑像素比(devicePixelRatio)渲染页面,缩略图被放大后就会出现明显的模糊。

「高分辨率图片」组件正是针对这一痛点:当屏幕 DPI 缩放超过 200%(即devicePixelRatio > 2)时,按比例放大 URL 中的尺寸参数,向 CDN 请求更高分辨率的图片源

从组件元数据(index.ts)可以看到其默认行为:

  • 组件名imageResolution,显示名「高分辨率图片」,归属utils(实用工具)标签;
  • enabledByDefault: window.devicePixelRatio > 1,即只要 DPR 大于 1(任何高分屏)默认即启用
  • 入口为startResolution,选项包含scaleoriginalImageInArticles

二、工作原理:从图片 URL 重写到底层实现

2.1 哔哩哔哩图片 URL 的尺寸规则

B 站图片地址中,@符号后的部分即为尺寸指令,常见两种形态:

  • @200w:仅指定宽度,高度按原图比例自动计算;
  • @200w_112h:同时指定宽度与高度。

源码中的匹配正则(resolution.ts)正是针对这一约定:

const resizeRegex = /@(\d+)Ww[Hh])?/

替换时,若原 URL 只有宽度,则新 URL 写为@${newWidth}w;若宽高都有,则写为@${newWidth}w_${newHeight}h。当计算出的新尺寸为无穷大(请求原图)时,则直接把@...后缀整体移除,等价于请求原始分辨率图片。

2.2 整体流程

组件入口startResolution(resolution.ts)通过styledComponentEntry包装(见 styled-component.ts),先动态注入样式文件 fix.scss,再执行主逻辑:

  1. 计算缩放倍率:读取scale选项,auto时调用getAutoScale(),否则解析为数字;
  2. 全量扫描:用document.createNodeIteratorwalk函数)遍历document.body下所有元素,逐一调用imageResolution处理;
  3. 动态监听:注册allMutations(基于MutationObserver,见 observer.ts),对后续新增节点(如滚动加载的图片)递归执行同样的替换,保证动态内容也被覆盖。

2.3 auto 缩放倍率的算法

getAutoScale()(resolution.ts)逻辑非常简洁:

const getAutoScale = () => { if (window.devicePixelRatio <= 2) { return 1 } return window.devicePixelRatio / 2 }
  • DPR ≤ 2(即 200% 缩放下限之内)时倍率为 1,不做任何替换scale === 1时入口函数直接 return,见第 135-137 行),避免低缩放屏幕上的无谓开销;
  • DPR > 2 时取DPR / 2,例如 DPR = 2.5(250% 缩放)时请求 1.25 倍,DPR = 3(300% 缩放)时请求 1.5 倍。这与文档中"250% 的缩放下会请求 1.5 倍尺寸的图片"略有出入——文档示例按"超出 200% 的比例"理解,而源码实现实际按DPR / 2计算,两者在 DPR = 3 时(1.5 倍)是一致的。以当前仓库源码为准:实际倍率 =devicePixelRatio / 2

2.4 图片源的三类替换通道

imageResolution函数(resolution.ts)对每个元素同时处理三种图片来源,并通过attributes监听(observer.ts)在属性变化时再次替换:

  1. src属性(<img>标签);
  2. srcset属性(响应式图片集合);
  3. style.backgroundImage(CSS 背景图)。

替换前有一系列守卫条件:

  • 排除选择器#certify-img1#certify-img2(认证图片)不处理;
  • 含逗号的 srcset 不处理value.includes(',')时直接跳过,避免破坏多候选源语法;
  • 去重防抖:通过data-resolution-width自定义属性记录已替换的宽度,若当前宽度不大于已记录值则跳过,防止重复放大导致图片被无限放大;
  • 匹配失败(URL 中无@...w规则)直接跳过。

2.5 关键修复:替换图片源后的尺寸比例处理

文档特别提醒:"由于 b 站在很多地方没有设置图片维持原比例,如果计算后的图片尺寸超出原图尺寸则会产生错误的比例"

源码对此做了针对性处理:当元素原本没有显式width/height属性时(resolution.ts),会按选择器类别补写属性以锁定布局:

  • .bili-avatar-img(动态头像框):只设置height,对应 issue #2030;
  • .logo-img(首页 Logo):widthheight都设置,对应 issue #4480;
  • 其余元素:只设置width,由浏览器按原图比例推导高度。

同时,fix.scss 用 CSS 兜底修复了收藏夹封面(favInfo-box)与评论区"航海"挂件图片的宽度/对齐问题,避免替换后布局错乱。

三、配置选项详解

组件共两个选项,定义于 index.ts,并通过defineOptionsMetadata注册(见 define.ts)。

3.1scale(缩放级别,默认auto

文档给出的取值有两类:

取值含义行为
auto自动模式devicePixelRatio / 2计算倍率(DPR ≤ 2 时为 1,不替换)
数字(如1.21.52自定义倍率以该数字作为统一缩放倍率,源码中通过parseFloat解析

数字模式不受 DPR 约束,适合想强制放大、或反过来手动降低缩放级别的用户。文档明确指出:当自动计算出的图片尺寸超出原图尺寸、导致页面出现错误比例时,可在选项中手动调低缩放级别来规避。

3.2originalImageInArticles(在专栏中请求原图,默认false

该选项针对专栏文章页:开启后,命中.article-detail .article-content img选择器的图片,其缩放倍率被设为Infinity(见 resolution.ts),从而在 URL 替换时直接去掉@...尺寸后缀,请求原始分辨率的图片,保证长文配图的最佳清晰度。代价是加载流量与时间显著增加,因此默认关闭,需要用户按需开启。

四、已知问题与使用注意事项

文档明确列出了该组件带来的副作用,使用时应充分权衡:

  1. 加载时间变长:高分辨率图片体积更大,CDN 传输与解码耗时随之增加;
  2. 图片闪动:部分浏览器中,由于本质上是"更换图片源",src被重写后图片会重新加载,出现短暂闪烁。这是源码层面setAttribute('src', ...)直接换源的必然结果,无法完全消除,只能通过降低倍率减少触发;
  3. 比例错误:B 站大量位置未设置图片维持原比例(object-fit等),一旦放大后的尺寸超过原图尺寸,会拉伸变形。应对手段有三:手动调低scale、依赖 2.5 节所述的属性补写逻辑、以及fix.scss中的样式兜底;
  4. DPI 判断边界:DPR ≤ 2 的屏幕默认不替换(auto 模式下倍率为 1),因此普通 100%/125%/150%/200% 缩放下该组件实际不生效,仅在超 200% 缩放时才工作。

五、源码结构速查

文件作用
image-resolution/index.md组件使用文档(本文依据)
image-resolution/index.ts组件元数据与选项定义
image-resolution/resolution.ts核心实现:URL 正则重写、DOM 遍历、MutationObserver 监听
image-resolution/fix.scss替换后的布局修复样式
styled-component.tsstyledComponentEntry工具:动态注入样式后执行入口
observer.tsattributes/allMutations观察器,驱动动态内容替换

结语

「高分辨率图片」组件通过一套极轻量的 URL 重写机制(正则匹配@w/@w_h后缀 → 按 DPR 计算倍率 → 重写src/srcset/backgroundImage),配合 DOM 遍历与 MutationObserver,在保持页面布局稳定的前提下为高分屏用户提供更清晰的图片。理解其auto倍率算法(DPR / 2)、originalImageInArticles的原图直取语义,以及比例修复策略,是正确配置该组件、规避图片闪动与比例失真问题的关键。

【免费下载链接】Bilibili-Evolved强大的哔哩哔哩增强脚本项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询