How We Overcame Front‑End Pitfalls in JD PLUS Mobile Redesign
This article recounts the JD PLUS membership mobile redesign, detailing tight deadlines, complex business logic, front‑end/back‑end separation, Vue.js challenges, UIWebView performance bottlenecks, cross‑origin handling, Flexbox compatibility, ES6 polyfills, array reactivity, WebView caching, and Swiper integration, and how each issue was resolved.
In early March, JD launched a major redesign of the JD PLUS membership channel for the mobile (M) side, aiming to improve user experience and conversion rates for its premium subscription service.
Project Challenges
Very tight schedule due to a looming APP release deadline and late requirement delivery.
Complex business logic involving ~10 user account states, authentication, credit status, auto‑renewal, membership levels, and backend configurations that affect page layout and behavior.
Distributed front‑end, back‑end, and product teams leading to high communication overhead.
Need to support a wide range of mobile browsers and be embedded inside iOS/Android JD, JD Finance, WeChat, and QQ apps, with additional low‑version browser compatibility requirements.
Integration with shared code from other teams.
Choosing Front‑End Architecture
The legacy system used static pages rendered by the back‑end, limiting front‑end flexibility. The team switched to a front‑back separation model, adopting Vue.js 2.0 and JD’s internal scaffolding tool (JDF). Because the JDF version could not parse Vue single‑file components, the full Vue build (including the template compiler) was loaded directly in the browser, which later proved problematic.
UIWebView Performance Bottleneck
Testing revealed that the iOS JD app’s built‑in UIWebView rendered the channel homepage 3‑4 seconds slower than other browsers. Investigation showed the old UIWebView struggled with compiling complex Vue templates. Upgrading to WKWebView was not immediately possible, so the team pre‑compiled Vue templates using vue-template-loader in a Node.js environment via a custom webpack scaffold, converting templates into JavaScript render functions.
Cross‑Origin (CORS) During Development
During development the front‑end and API ran on different domains, causing CORS errors. The team first used Chrome’s --disable-web-security flag, then switched to proper CORS headers and a Chrome extension ( Allow-Control-Allow-Origin: *) for quick testing. For broader testing, they used Fiddler to inject the header in responses.
Flexbox Layout Compatibility
Because Flexbox specifications have evolved, the team documented the need to code to the latest spec and rely on tools like autoprefixer for older browsers. They noted occasional issues on legacy devices (e.g., needing display:block for inline elements, lack of flex‑wrap support) and provided mitigation tips.
iOS HTTPS Capture Issue
When debugging on iPhone, HTTPS traffic could not be captured with Fiddler on iOS 10.3 because the system required manual trust of installed certificates. The fix involved enabling the certificate under Settings → General → About → Certificate Trust Settings.
ES6 Compatibility and Babel Polyfill
Some Huawei devices failed to render product lists because the native browser lacked support for certain ES6 APIs (e.g., Array.from). Although Babel transpiled syntax, it did not polyfill new APIs. The team added babel‑polyfill to the build, noting the polyfill’s size (~80‑90 KB) and the need to evaluate its impact on mobile performance.
npm install --save-dev babel-polyfillVue Array Reactivity Pitfall
Vue cannot detect direct index assignment or length changes on arrays. The solution was to modify the array element then call splice to trigger reactivity.
this.arrtab[index].page = 2; this.arrtab.splice(index, 1, this.arrtab[index]);WebView Cache Issue for Pop‑Up
After closing an operation‑popup, returning to the page caused the popup to reappear because the WebView cached the previous request. Adding a random query parameter (or setting cache:false in jQuery/Zepto) forced a fresh request.
Swiper Integration with Vue
Initial Swiper usage worked in Chrome but caused freezes on low‑end browsers due to multiple instantiations. The fix added a destroy check before creating a new Swiper instance.
if (this.swiper && typeof this.swiper.destroy === 'function') { this.swiper.destroy(); this.swiper = null; }Later the team switched to vue-awesome-swiper, which resolved remaining glitches.
Conclusion
The JD PLUS mobile redesign faced tight timelines, intricate business rules, and numerous platform‑specific quirks. By adopting front‑back separation, pre‑compiling Vue templates, handling CORS properly, using Flexbox with autoprefixing, addressing iOS HTTPS capture, polyfilling ES6 APIs, fixing Vue reactivity, managing WebView caching, and stabilizing Swiper, the team delivered a performant, user‑friendly experience that significantly improved metrics.
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.
JD.com Experience Design Center
Professional, creative, passionate about design. The JD.com User Experience Design Department is committed to creating better e-commerce shopping experiences.
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.
