Frontend Development 10 min read

Designing a Reusable, Flexible, and Stable Detail Page Framework

This article analyzes the challenges of maintaining high‑traffic detail pages across multiple business teams and proposes a three‑layer, dependency‑injection‑enabled framework that ensures reusability, flexibility, and stability while supporting fast onboarding and robust quality assurance.

Architect
Architect
Architect
Designing a Reusable, Flexible, and Stable Detail Page Framework

The detail page carries the core traffic of the platform, with daily playback counts reaching billions, making its functionality and code complexity among the highest on the client side, which leads to high maintenance costs.

Previously, three separate business teams each maintained their own detail pages, resulting in isolated pages, no code reuse, and difficulty in achieving a unified user experience.

Requirement analysis covers four dimensions: business (unifying multiple business forms), efficiency (standardizing iteration processes), quality (ensuring stability across teams), and team (accelerating newcomer onboarding).

To address these needs, a generic detail‑page framework is designed with three layers: Business Layer (abstracting reusable modules and isolating business‑specific ones), Component Layer (providing common components that can be freely assembled), and Framework Layer (handling lifecycle and data management to guarantee stability).

The framework targets three core goals—reusability, flexibility, and stability. For example, the recommendation module is shown only in UGC and OGV modes, with differing click‑event logic, and it depends on the introduction module, illustrating the need for modular independence and customizable behavior.

To enable business‑specific logic without breaking the generic structure, a dependency‑injection (DI) mechanism is introduced, allowing teams to inject their own implementations.

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() }
}

Business teams can register their implementations:

// Business side injects different implementations
register(service: XXXProtocol.self, to: ABloc.self) // A business form
register(service: XXXProtocol.self, to: BBloc.self) // B business form

Components are resolved via the DI container:

let s: XXXProtocol = store.optional()

Two scopes are defined to manage module lifecycles: page‑level scope and business‑level scope.

class VDScope {
    public static let core = "store.core.scope"
    public static let biz = "store.biz.scope"
}

The framework destroys all modules under the previous business scope when the page form changes and initializes new modules for the new scope.

public class BlocStore {
    typealias ScopeTable = [String: String]
    ...
    func bizTypeDidChanged() {
        // Destroy all modules under the previous biz scope
        xxxx
        // Initialize modules under the new biz scope
        xxx
    }
}

Stability is ensured through full‑link logging, technical telemetry, AB‑fallback strategies, and proactive monitoring and alerting during development, testing, and production phases, complemented by offline data reports and exception alerts.

Overall, the proposed framework unifies disparate detail pages, supports modular reuse, enables flexible business‑specific extensions via dependency injection, and provides a robust quality‑assurance pipeline that helps newcomers quickly contribute while maintaining system stability.

frontendarchitectureModularizationscalabilityquality assurancedependency injection
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.