Optimizing First‑Screen Loading in Qunar React Native (QRN) Framework
This article explains the RN and QRN loading processes, analyzes the causes of long white‑screen times, and presents practical techniques such as JS bundle splitting, Bridge pre‑loading, lazy requires, and asynchronous component registration to significantly reduce QRN first‑screen loading latency.
React Native (RN) is a popular cross‑platform mobile framework that uses JavaScript to build native iOS and Android apps, and Qunar React Native (QRN) is a heavily customized RN framework that further smooths platform differences.
When a QRN page is opened, a loading animation is shown during the white‑screen phase; this animation appears only on the first entry to a page, and its duration grows as the page becomes more complex and includes more tools such as Redux.
1. RootView and Bridge
RootView is the canvas on which all RN Views are placed; only one component registered via AppRegistry.registerComponent() can be displayed on a RootView.
The Bridge connects JavaScript and native code, allowing JS to call native APIs and render Views. Each RootView has a corresponding Bridge, and multiple RootViews can share a Bridge, thus sharing the same JS environment.
2. RN Loading Process
A typical RN page component imports react and react‑native , defines a class extending Component , and registers it with AppRegistry.registerComponent('Page', () => Page) . The RN loading flow can be simplified into four stages:
Initialize RN environment (create Bridge, JS environment, RN modules, UI components)
Download JS Bundle
Run JS Bundle
Render page
The JS Bundle contains the page component code, the core react / react‑native code, and any additional modules such as Redux . A typical demo bundle after minification is around 700 KB, so downloading it takes noticeable time. Rendering itself only takes a few dozen milliseconds; the white‑screen time is mainly spent before AppRegistry.runApplication() is called.
3. QRN Loading Process
QRN splits the JS Bundle into two parts: framework JS (including react , react‑native , and the QRN extension Ext ) and business JS (page layout, data fetching, etc.). This reduces the size of business code per page.
After splitting, the QRN loading flow becomes five stages:
Initialize RN environment
Load framework JS (built into the app, no network cost)
Download business JS
Run business JS
Render page
Because the framework JS is pre‑bundled, only the business JS download time varies. Large business bundles (>1 MB) can still cause >1 s delays.
3.2 Bridge Pre‑loading and Caching
Since the first two stages are business‑independent, QRN pre‑loads a Bridge that already has the framework JS loaded. When a QRN page is opened, only the remaining three stages are executed. A successfully run business JS can also be cached; subsequent openings of the same page reuse the cached Bridge, skipping all preparation work.
3.3 QRN Loading Time
Testing on iPhone 6 shows that the first four stages (the loading animation) take roughly 300 ms less when the Bridge is pre‑loaded. If the business JS is fetched from an offline bundle, the download time is negligible; otherwise, network download can exceed 1 s, and running the business JS often exceeds 300 ms before optimization.
4. QRN First‑Screen Loading Optimizations
4.1 Lazy Requires in RN
Facebook’s RN blog describes “lazy requires”: a module is required only when it is first used. Components are exposed via getters on react‑native , e.g.:
const ReactNative = { get Image() { return require('Image'); }, /* … */ };This reduces the time spent initializing modules because subsequent requires are simple pointer assignments.
4.2 Pre‑requiring Common Components in QRN Framework JS
QRN’s framework JS pre‑requires frequently used components such as View , Text , Image , ScrollView , ListView , and the QRN extension Ext . Although this adds ~200 ms to framework JS execution, it saves a similar amount in business JS runtime, cutting overall first‑screen time by ~200 ms.
4.3 Asynchronous Require for Pages
When a QRN business contains many pages (e.g., 20 hotel pages), loading all page modules during business JS execution wastes time. By moving the require call inside the component registration function, the page code is only loaded when the page is actually rendered:
// Before optimization
const Page1 = require('Page1');
AppRegistry.registerComponent('Page1', () => Page1);
// After optimization
AppRegistry.registerComponent('Page1', () => require('Page1'));This change reduced the loading time of a 20‑page hotel business from >500 ms to about 112 ms.
4.4 Ext.registerView for QRN‑Ext Projects
Since QRN v1.6.0, the QRN‑Ext framework provides Ext.registerView , which registers a view with a lazy require callback, achieving the same effect as the previous optimization.
// Before
require('./views/hotelList');
require('./views/hotelDetail');
// After
Ext.registerView('HotelList', () => require('./views/hotelList'));
Ext.registerView('HotelDetail', () => require('./views/hotelDetail'));5. Summary
The article introduced the RN and QRN loading pipelines and proposed two main techniques to speed up QRN first‑screen loading: pre‑requiring necessary components in the framework JS and using asynchronous require for page modules. Combined, these methods make the initial QRN experience much closer to native performance.
Qunar Tech Salon
Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.
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.