Bilibili Offline Package Solution for Accelerating H5 Page Load Speed
Bilibili's offline package solution accelerates H5 page load by pre‑downloading resources, intercepting WebView requests, offering snapshot, AB testing, QR‑code debugging, version control, and off‑peak releases; deployed across many projects, it cuts load times by roughly 20‑30% and improves first‑contentful‑paint.
H5 pages are attractive because of low development cost and fast iteration, but they often suffer from poor user experience, especially the first‑screen speed. Since all resources of an H5 page must be downloaded from the network in real time, accelerating resource loading can significantly improve the first‑screen time. The technique of delivering resources to the app in advance and using them to speed up page access is called an “offline package”.
Bilibili’s offline‑package solution follows the same basic resource delivery and interception logic as most internet companies, but adds several innovations such as page snapshot technology, AB‑testing capability, QR‑code debugging, rapid version convergence, and scheduled off‑peak releases. The solution has been integrated into 183 projects across 12 business lines within the company.
Page‑load bottleneck analysis
When analyzing a typical H5 activity page (2024 Documentary Open Week), the main speed bottlenecks are:
HTML request : SSR (server‑side rendering) vs. CSR (client‑side rendering). SSR has later first‑byte time but faster first‑screen rendering once HTML arrives; CSR benefits from CDN caching but incurs a longer JS execution time before the DOM is built.
Main JS download & compilation : Bundles of several hundred KB to a few MB take hundreds of milliseconds to download and additional tens of milliseconds to parse/compile.
Main API request : Usually 30‑100 ms; the UI must wait for the response before constructing the virtual DOM.
Virtual DOM generation : CPU‑intensive, often taking dozens to hundreds of milliseconds.
First‑screen resource loading : After DOM construction, the browser downloads CSS, images, fonts, etc., typically taking several hundred milliseconds.
Overall, a typical page needs 1.2 s–2.5 s from start to a stable view, with network I/O accounting for a large portion of the time.
Offline package technical overview
The core of the offline package relies on WebView’s request‑interception capability. On Android, shouldInterceptRequest is used; on iOS, WKURLSchemeHandler handles HTTPS interception (with special handling for POST bodies). Resources are prepared by collecting all files needed by the page and creating a URL‑to‑local‑path mapping.
Two sources of resources are supported:
Code project: enumerate build output files, filter out large or unused ones, and add any extra online resources.
Online capture: for pages that cannot be built from source (e.g., low‑code platforms), simulate a browser to capture actual requests and apply filtering rules.
The final package directory contains:
config.json – describes the URL list to intercept and the resource mapping.
HTML entry file – loaded by WebView according to config.json .
Other assets (CSS, JS, images, fonts, SVG, etc.) – intercepted and served from local storage.
Distribution mechanism
Offline packages are delivered via the Fawkes ModManager, which provides a unified channel for resource download, incremental updates, peak‑shaving distribution, hot‑push, and version/network constraints. Three release modes are supported:
Regular release : packages are published online; eligible cold‑start users download the full or incremental package.
Off‑peak release : the package becomes effective 1‑3 days after publishing, allowing download during low‑traffic periods to reduce CDN cost.
Scheduled release : a specific low‑traffic window within the next 24 hours is set; the current package is invalidated immediately, and the new package is activated at the scheduled time.
Resource matching flow
Check whether the offline package can be used (global switch, URL whitelist, protocol match).
If the URL matches, verify that the local package version is in the server‑provided whitelist.
Enable HTTPS interception and start loading the offline HTML.
When the HTML loads, subsequent JS, image, etc., requests are intercepted and served from the local mapping.
Special “public resources” are also resolved from a shared package.
If a local resource fails, fall back to the online request.
Version control and fast rollback
Because offline packages are pre‑downloaded, timely updates are challenging. Bilibili adds a version‑whitelist API ( /x/offline/version ) that returns the list of usable package versions for a given app environment. Clients refresh this list on cold start and when returning from background, enabling:
Setting an expiration time for old versions (e.g., 2 hours) so they automatically fall back to online resources.
Fast offline‑package disabling by removing the version from the whitelist.
Scheduled releases that temporarily force online access.
Debugging workflow
To reduce the pain of waiting for package download during development, a QR‑code debugging flow is introduced. Scanning the code triggers a JSAPI that downloads a zip package into a dedicated debug directory; subsequent page loads prioritize this directory, reproducing the production offline‑package experience.
HTML snapshot
HTML snapshots cache the rendered DOM of a page. When a user revisits the URL, the snapshot is displayed instantly while the fresh page loads in the background. Constraints include single‑use deletion after 3 seconds, version‑key isolation, cache‑key strategy based on URL/query/cookie/login state, and limits on storage size (≤10 MB) and count (≤20 snapshots per URL).
AB testing
Since the offline package intercepts the entry HTML, traditional server‑side AB routing is unavailable. Bilibili uses URL rewrite rules generated per user group to map the same logical URL to different offline‑package versions, enabling page‑level AB experiments.
Applicable scenarios & limitations
Requires an online fallback because the offline capability can become unavailable (e.g., low app version, emergency disable, scheduled release).
Increases release complexity: offline‑package validation must be done before the online page is released.
Introduces extra bandwidth cost during package distribution, especially during peak periods.
iOS-specific limitations: POST requests must go through a JSAPI wrapper; history navigation may cause the whole WebView to exit.
Suitable business types include high‑traffic activity pages, revenue‑sensitive flows, and relatively stable pages with a sizable user base.
Performance results
Global measurements show a clear improvement on Android (average onload time reduced from ~2700 ms to ~2300 ms, and further to ~2016 ms after full JS bundling) and a noticeable but smaller gain on iOS. First‑Contentful‑Paint (FCP) dropped from 1550 ms to 1230 ms, achieving near “instant‑open” experience.
Industry comparison
Compared with other solutions (e.g., WebView pre‑loading, interface pre‑fetch, public‑package sharing, incremental packages, hot‑push, Wi‑Fi‑only download), Bilibili’s offline package stands out for its off‑peak release, version control, QR‑code debugging, HTML snapshot, and AB testing capabilities, while maintaining low code intrusion.
Other companies’ solutions (e.g., HuoLala, Alipay Nebula, UC NSR, Tencent VasSonic) are discussed, highlighting trade‑offs in performance, generality, and invasiveness.
Conclusion
The offline‑package strategy balances universality and performance. By prioritizing a generic, Web‑standard‑compatible approach, Bilibili can deploy the solution across many business lines with modest cost, while still allowing specialized optimizations (e.g., WebView resident, NSR‑like techniques) for higher‑performance needs.
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.