preface

As the project is very large, the use of medium and low-end mobile phones will be stuck or slow, which is also the disadvantage of non-native apps, including React Native and Flutter. These non-native frameworks have more or less a lot of loss in the communication with Native apps.

Operation principle

When uniApp runs in non-H5 terminal, it is architecturally divided into logical layer and view layer. The logic layer is responsible for executing the page logic and the view layer is responsible for rendering the page.

Logical layer explanation:

  • The logic layer runs in a separate jscore and does not depend on the native webview, so on the one hand it has no browser compatibility issues and can run es6 code on Android4.4. On the other hand, It cannot run browser-specific JS apis like Window, Document, Navigator, localStorage, etc.
  • Jscore is a standard JS engine. Standard JS runs normally, such as if, for, various strings, date processing, etc. The difference between JS and browser should be distinguished.

Js engine details:

  • The js engine for browsers is a new set of browser-specific apis, such as DOM, added to jScore or V8.

  • The Node. js engine, which is based on V8, is supplemented with some computer-specific apis, such as local IO.

  • So uni-App’s APP-side and app-side JS engines complement jScore with a number of js apis commonly used on mobile, such as scanning.

View layer detail:

  • H5 and applets, and app-Vue, the view layer is webView. The view layer of app-NVue is a native render view based on WEEX modification.

  • On iOS, you can only use the Webview provided by iOS (WKWebview by default). It has some browser compatibility issues, and its performance varies slightly between iOS versions (generally negligible).

  • Most of the small programs on Android have their own Chromium Webview of tens of meters, while the App side cannot carry such a large three-party package, so the App side uses Android System WebView by default, and the webview of this system varies with different mobile phones. Of course, the App side also supports the use of Tencent X5 engine, at this time you can unify the view layer on the Android side.

Pros and cons of separating the logical and view layers:

  • Advantage: form animation stability

  • Disadvantages: Communication between logic layer and view layer has loss, especially continuous high frame rate drawing canvas animation, scrolling event, gesture operation, etc. It needs to continuously feed back to the logic layer, and then notify the view layer to make updates after the logic processing is complete.

  • Solutions:

  • The view layer for webView rendering

  • On app-Vue and wechat applet, a kind of exclusive JS running in view layer is provided, wechat is called WXS

  • Renderjs is more powerful on the app side, and the official case portal is also provided. The case portal that runs Echart based on RenderJS, such as F2, Threejs and other Web libraries can run.

  • Native render view layer

  • Weex provides a set of bindingX animation rendering engine, can be in JS one-time pass an expression to the native layer, by the native layer after parsing according to the instructions to operate the native view layer, avoid repeated cross-layer communication

  • The plugin market also offers a cross-platform animation plugin, Lottie

Optimization Suggestions

  1. App if not v3 mode, please change to V3 compiled mode, portal

  2. Avoid the use of large image resources, do not reduce multiple large images in one screen and put them in one screen, it is very easy to crash.

  3. Each change in the data defined in data notifies the view layer to re-render the page. So if a variable is not required by the view, you can define the variable externally, not in data, or hang it on the vue instance.

  4. Long list of Numbers

  5. Use NVUE for rendering

  6. The data is loaded in pages

  7. Make each item into a component

  8. Minimize scrolling event listening and add throttling if listening is necessary

  9. Reduce the number of components, each component will render communication, can be packaged into one component rather than two

  10. Reduce the level of node nesting, because the rendering process, the real DOM will be traversed to generate vDOM and some other operations, so it is recommended to reduce the deep node nesting

  11. App-nvue and H5, support page preloading, portal

Optimize startup speed

  1. The more the project code, including the background image and the larger the local font file, the speed of the small program has an impact, should pay attention to the control volume. The foreground diagram referenced by the component does not affect performance. App side in V3 before also have the same problem as small program, but V3 has solved this problem.

  2. The App splash closed, hang detection mechanism, if the page has been white during or home page itself is an empty page, may lead to splash ten seconds to shut down, may refer to this article solve ask.dcloud.net.cn/article/355…

  3. If the App uses the V3 compiler and the home page is nvUE, and the startup mode is set to Fast, the App can start at the fastest speed.

  4. The App is set up as a pure NVUE project (the Renderer under app-Plus :”native” in the manifest), which can start up faster in 2 seconds. Because it uses native rendering throughout the application, it doesn’t load the WebView-based framework.

Use skeleton screen

  1. For entering a new page, triggering the life cycle function, loading HTML, JS, CSS, calling the interface to return data, it may take a period of time, page members blank screen or empty data, user experience is poor, then how to optimize?

  2. Loading loading is commonly used, but is relatively low

  3. Commonly used method

  4. UI shows the skeleton screen

  5. CSS draws the stock price screen

  6. The skeleton screen is used by many companies. Compared with VUE, there is a more mature scheme called VUE-Content-Loader

  7. .

  8. I wrote up a plan: a portal

pre-rendered

  1. Preload page, is a performance optimization technology, currently only supports Nvue,H5, preload trigger page life cycle, onLoad onReady, do not trigger onShow. Page prerendering

Using nvue

  1. Nvue is used for page development. Nvue page rendering engine belongs to native rendering, which reduces communication loss and improves performance compared with WebView.

  2. The difference between NVUE and VUE, portal

  3. The home page recommends using NVUE for rendering

Animation using Lottie,bindingX

  1. lottie

  2. bindingX

Use work threads to process data

  1. Process the countdown portal

Image optimization

  1. In the case of complex page structure and too many CSS styles, add image {will-change: transform} to app.vue to optimize slow image loading.

  2. > 50K, compress all, compress address: portal

  3. Add image lazy load attribute

Page composition

  1. A good page should be composed of multiple word components, PageA = ComponentsA + ComponentsB + ComponentsC…

  2. Data updates only update the current component, reducing unnecessary updates.

  3. Component reuse reduces workload and makes the code hierarchy clearer and easier to maintain

Lazy loading

  1. Picture lazy loading reference: portal

  2. Loading can be added for lazy page loading and disabled after data loading is complete

Data optimization

  1. When there is a large amount of data on a page, data is loaded in pages

  2. Some constants in the page do not need to be mounted in data, just define variables.

  3. Some data can be mounted to a VUE instance

  4. .

Throttling stabilization

  1. Frequently click events and search, placing repeated click calls multiple times.

    let timer, flag; / * *

    • Throttling principle: Trigger only once in a certain period of time
    • @param {Function} func Specifies the callback Function to execute
    • @param {Number} Wait Delay time
    • @param {Boolean} immediate Specifies whether the command is executed immediately
    • @return null

    */ function throttle(func, wait = 500, immediate = true) { if (immediate) { if (! flag) { flag = true; Typeof func === ‘function’ && func(); // If immediate, typeof func === ‘function’ && func(); timer = setTimeout(() => { flag = false; }, wait); } } else { if (! Flag) {flag = true // If the execution is not immediate, Timer = setTimeout(() => {flag = false Typeof func === ‘function’ && func(); }, wait); }

    }
    Copy the code

    }; export default throttle

    let timeout = null;

    / * *

    • Anti-shake principle: The function is executed only after the last operation within a certain period of time and wait milliseconds
    • @param {Function} func Specifies the callback Function to execute
    • @param {Number} Wait Delay time
    • @param {Boolean} immediate Specifies whether the command is executed immediately
    • @return null

    */ function debounce(func, wait = 500, immediate = false) { == null) clearTimeout(timeout); If (immediate) {var callNow =! timeout; timeout = setTimeout(function() { timeout = null; }, wait); if (callNow) typeof func === ‘function’ && func(); } else {// Set timer, timeout will not be cleared after the last operation, Timeout = setTimeout(function() {typeof func === ‘function’ && func(); }, wait); }}

    export default debounce

Related articles

  • Performance comparison of FLUTTER, RN and UNIAPP
  • Uniapp solves performance optimization from the operational principle