Design and Implementation of a Unified Multi‑Business Detail Page Framework
The project consolidates three separate detail‑page implementations into a single, reusable framework that separates business, component, and framework layers, employs dependency‑injection and scoped lifecycles to support diverse scenarios while ensuring stability through comprehensive logging, monitoring, and staged gray‑release testing.
Background
The detail page carries core traffic on the platform, with daily playback counts reaching hundreds of millions. Its complexity makes it one of the most code‑intensive client pages, leading to high maintenance costs.
Clear Requirements
Previously, three business teams maintained separate pages, resulting in isolated capabilities and no reuse.
The goal of the project is to merge these pages into a single unified detail page that can support multiple business scenarios (large‑scale events, host‑guest mode, playlist mode, PUGV/OGV, etc.) while allowing each business to retain its unique logic.
Requirement Analysis
Business perspective: Resolve the inconsistency of multi‑business forms and enable simultaneous use of features such as UGC large‑event capabilities and OGV multi‑view.
Efficiency perspective: Align iteration processes across teams to avoid duplicated effort when a feature (e.g., progress‑bar optimization) is needed by multiple business units.
Quality perspective: Ensure stability when multiple teams collaborate on the same page.
Team perspective: Lower the onboarding barrier for new developers by abstracting complex business logic.
Specific Solution
The unified detail page framework must satisfy three core principles: reusability, flexibility, and stability.
We decompose the page into three layers:
Business layer: Separate modules into common business components (reusable across scenarios) and business‑specific components (handled by each team).
Component layer: Provide a library of generic components that can be freely selected and assembled by the business side.
Framework layer: Abstract lifecycle management, data handling, and other core logic to guarantee overall stability.
Analysis of multiple business forms shows many shared modules (e.g., interaction panel, bullet‑screen input, recommendation list) both horizontally and vertically, indicating ample reuse opportunities.
Dependency Injection
To support business‑specific logic without tightly coupling modules, we introduce a dependency‑injection container that allows teams to register and resolve services.
public class BlocStore {
typealias StoreLock = RecursiveLock
typealias StoreTable = [String: BlocTable]
private let lock: StoreLock = StoreLock()
private lazy var storeTable: StoreTable = [:]
}
extension BlocStore {
public func register
(service: Service.Type = Service.self, to: Bloc.Type) {
let key = "\(service)"
lock.lock()
defer { lock.unlock() }
serviceTable[key] = to
}
@discardableResult
public func optional
(service: Service.Type = Service.self) -> Service? {
let key = "\(service)"
lock.lock()
defer { lock.unlock() }
let service = resolve(bloc)
return s
}
}
// Bind and unbind
extension BlocStore {
public func bindBloc(bloc: Bloc) {}
public func unbindBloc
(_ blocType: T.Type) {}
}
// BlocLifeCycle
extension BlocStore {
func onStart(bloc: Bloc?) { bloc?.onStart() }
func onPause(bloc: Bloc?) { bloc?.onPause() }
func onResume(bloc: Bloc?) { bloc?.onResume() }
func onStop(bloc: Bloc?) { bloc?.onStop() }
}Component registration example:
// Business can inject different implementations
register(service: XXXProtocol.self, to: ABloc.self) // A business form
register(service: XXXProtocol.self, to: BBloc.self) // B business formComponent resolution:
let s: XXXProtocol = store.optional()Scope Introduction
Two scopes are defined: page‑level scope and business‑level scope.
class VDScope {
public static let core = "store.core.scope"
public static let biz = "store.biz.scope"
}Scope management ensures that modules tied to a business scope are destroyed and re‑initialized when the business form changes, allowing developers to focus on their own features without worrying about underlying transitions.
Ensuring Throughput and Quality
With unchanged development and testing resources, we adopt a three‑stage strategy:
Development stage: Add full‑link logging to core flows, trigger exceptions on unexpected data, enforce AB‑fallback for critical changes, and embed technical telemetry.
Testing stage: Use monitoring and alerts to catch hidden bugs that do not affect UI but corrupt internal processes.
Gray‑release / Production stage: Deploy comprehensive monitoring, automatic DEBUG dialogs on error logs, and real‑time telemetry to maintain stability.
By integrating full‑link logs, monitoring, and alerting, a closed‑loop from issue discovery to rapid定位 is established.
Bilibili Tech
Provides introductions and tutorials on Bilibili-related technologies.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.