Optimizing Static Resource Loading for Meituan Scan-to-Pay with ThunderJS and Build Service
Meituan’s Scan‑to‑Pay H5 app uses ThunderJS and a dedicated Build Service to deliver character‑level incremental JavaScript updates, switching to Myers’ algorithm, isolating computation in a Mixer service, caching results, and adding timeout recovery, which cut data transfer up to 99%, reduced 90th‑percentile latency from 5.8 s to 90 ms, and raised success rates above 99%.
Initial Solution
Meituan Financial Smart Payment’s Scan-to-Pay is an H5‑based payment product for end‑users. After a purchase, users can scan a QR code with various apps (Meituan, Dianping, WeChat, Alipay, Meituan Wallet) to complete payment and leave feedback. The service handles tens of millions of daily page views.
Because merchants are often located in dense indoor spaces (shopping malls, office buildings) with poor network conditions, the team adopted the internally built module loader ThunderJS. ThunderJS performs character‑level incremental updates to reduce file transfer size, save bandwidth, and improve page load success and speed. The incremental calculation is powered by Meituan’s static‑resource hosting solution, Build Service.
ThunderJS Workflow
ThunderJS stores JS resources and version information in LocalStorage. On page load it compares the online version with the local version to decide whether an update is needed. If an update is required, it issues a diff‑merge request, receives a patch, and applies it locally. If no update is needed, the cached resources are executed directly. When a diff request fails, ThunderJS falls back to loading individual files.
Update Decision Rules
The file name exists both online and locally.
The file’s version is identical online and locally.
The file is present in LocalStorage.
Diff Merge Request & Patch Diff
A diff‑merge request returns a JSON structure that describes how to reconstruct the latest file from the original file and a series of patches. The JSON specifies the offset, length, and inserted characters for each patch.
Build Service Workflow
Build Service is Meituan’s static‑resource hosting platform. It deploys, processes, and distributes resources via CDN. When a request misses the CDN cache, it is routed back to the origin server, processed, and then served through the CDN. Incremental computation is performed as a resource‑processing task on the origin.
Choosing the Incremental Algorithm
The initial implementation used an edit‑distance algorithm with O(N²) complexity, which was too slow for large texts. Build Service switched to Myers’ incremental algorithm, reducing the complexity to O(N·D) (N = text length, D = difference length). In typical web iterations D is small, making the algorithm close to linear time.
Initial Effects
Compared with full‑file requests, incremental updates reduced transferred data by up to 99% and cut the number of HTTP requests by about 95%.
Business Growth and Computation Bottlenecks
By April 2017 the project reached millions of PVs. The modular design led to an ever‑increasing number of files; a single merge request could contain more than 30 files. Incremental computation across many version combinations caused the Build Service to hit a 3‑second timeout threshold, with failure rates exceeding 50%.
Build Service Optimization Strategies
Service Splitting & Isolation
The original Build Service shared a common cluster with other tasks (compression, reference calculation). Incremental computation monopolized CPU resources, causing latency for other jobs. The team extracted the merge and incremental computation into a dedicated “Mixer” service, isolating it from the rest of the platform.
Persistent Computation Cache
Mixer now caches the output of each file’s computation task. Subsequent merge requests can reuse cached fragments, reducing redundant work. After deployment, Mixer’s success rate stabilized at 100% and each patch was generated within 50 ms.
Timeout Auto‑Restart
When a diff computation became slow (worst‑case O(N²)), the Mixer process would be killed and automatically restarted by PM2. The failed request would fall back to single‑file loading, allowing fast computations to proceed while the slow one was retried.
ThunderJS Optimization Strategies
Limit Merged File Count
The team capped the number of files per merge request to 10 (instead of unlimited). This split a 30‑file merge into three parallel requests, easing memory pressure and reducing timeouts.
Degradation Mechanism
If a merge request timed out, ThunderJS switched from creating script elements to using XHR to fetch individual files and store them in LocalStorage, improving cache reuse during network degradation.
Weak‑Network Prioritization
Network types are classified as WiFi, 4G, 3G, 2G, unknown. 2G and unknown are treated as weak networks (≈10% of users). For these users ThunderJS prefers cached files; if a cache miss occurs it falls back to single‑file requests.
Fundamental Solution to the Bottleneck
Asynchronous Computation Service (Brain)
The architecture was redesigned to separate computation (Brain service) from distribution. Brain stores a unique trace ID for each computation in MySQL and ensures only one node processes a given trace. Other nodes can retrieve the result directly, enabling horizontal scaling and eliminating resource contention between computation and serving processes.
After launch, Mixer no longer performed computation, availability rose to 99.99%, 90th‑percentile latency dropped from 5800 ms to 90 ms, and diff‑merge success increased by at least 50%.
Pre‑warm Strategy Before Release
Because some computation time is unavoidable, the team pre‑computes diffs for upcoming versions. By pre‑warming the last 5 versions, timeout rates fell to 1.5%; pre‑warming 10 versions reduced them to 1.1%.
Summary
ThunderJS’s incremental update scheme has delivered significant traffic and latency savings for Scan‑to‑Pay. Approximately 90% of requests come from mobile networks; daily bandwidth savings reach 49.37 GB, with incremental updates alone saving 33.41 GB per day.
Recruitment
The Meituan Financial Smart Payment front‑end team is hiring senior front‑end engineers and technical experts. Interested candidates can contact via the team’s public account, WeChat (yoyo779269), or email ([email protected]).
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Meituan Technology Team
Over 10,000 engineers powering China’s leading lifestyle services e‑commerce platform. Supporting hundreds of millions of consumers, millions of merchants across 2,000+ industries. This is the public channel for the tech teams behind Meituan, Dianping, Meituan Waimai, Meituan Select, and related services.
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.
