# Poor network experience optimization

When users use Weixin Mini Program, they may fall into some scenarios where the network is not smooth, and some functions that rely strictly on the network may not be used.

# Framework Optimization

In order to make Weixin Mini Program more smooth in the case of weak network, the Mini Program framework has done the following optimization to solve the experience of using Mini Program in weak network:

  1. Launch Weixin Mini Program Support asynchronous launch

Previously, the startup process was synchronous launch, which occurred when the page was stuck in the loading page during a weak network. Weixin Mini Program The framework uses asynchronous launch by default during weak networks to optimize the experience of starting the Mini Program on a lower network:

  • Synchronous launch: Pulls a new configuration, pulls a new code package if there is a new code package, and then starts Weixin Mini Program;
  • Asynchronous launch: Weixin Mini Program is started using the default local cache configuration, code package;
  1. Support for weak network / offline one-time authorization

For interfaces such as wx.getLocation, user authorization is required because the authorization relationship is logged in the background, but requests are difficult to navigate when the network is weak or offline, so the Weixin Mini Program framework supports one-time authorization to navigate the process when the networks are weak / offline:

  • When you call the authorization class interface, whether or not you previously had authorization, click the approval box to go to the local authorization.
  • Use the authorization results during the weak network / outage cycle;
  • After network recovery, clear the one-time authorization result and go back to the logic of making a request to the background to check the authorization.

In addition, Weixin Mini Program provides the cache manager to help developers solve the problem of Mini Programs weak nets.

Currently, the following network-dependent functions can be improved by accessing the cache manager:

  • Purely displays the functionality of the class
  • Relying only on some user-authorized features

# Cache Manager

Weixin Mini Program provides a non-intrusive cache manager that developers can access without modifying the original business code.The cache manager primarily has the following capabilities:

  • Caching network requests that comply with the rules when the network is smooth; Caching is used to return this network request when the network is weak.
  • Caching some WXAPI calls when the network is clear; Calls to these wxapi at weak net use cached returns.

In simple terms, cache managers help developers quickly access cache capabilities without modifying Weixin Mini Program main logic.The access process requires only a few additional lines of code:

// Create a cache manager
const cacheManager = wx.createCacheManager({
  origin: 'https://weixin.qq.com',
})

// Add request rules
cacheManager.addRules([
  '/cgi/home',
  '/cgi/detail/:id',
])

// Listens for wx.request requests that conform to the rules. By default, calling wx.request when the network is weak will trigger
cacheManager.on('request', evt => {
  return new Promise((resolve, reject) => {
    // 匹配是否存在缓存
    const matchRes = cacheManager.match(evt)

    if (matchRes && matchRes.data) {
      // 使用缓存返回
      resolve(matchRes.data)
    } else {
      // 没有匹配到缓存
      reject({errMsg: `catch not found: ${evt.url}`})
    }
  })
})

The above example uses wx.createCacheManager to create a cache manager.There is only one unique instance of the cache manager globally, and once it is successfully created, the access is successful.

Developers need to add request rules to match which requests need to be cached, and requests that are not in the request rules are automatically rejected. Once the request hits the rule, the result is cached when the network is clear, and the request is intercepted when the network is weak, and the request event is triggered to the developer. The developer can decide in an event callback whether to use the cache return, and if the cache return is used, the network request is not initiated again; If you still want to attempt to initiate a network request, you can do something like this:

cacheManager.on('request', async evt => {
  try {
    // 仍然走网络请求
    const res = await evt.request()
    
    // ......
  } catch (err) {
    // ......
  }
})

To accommodate more request scenarios, the request rule supports a variety of writing styles, such as:

cacheManager.addRule('/abc') // uri 串,会自动使用调用 wx.createCacheManager 时传入的 origin 进行拼接,然后匹配
cacheManager.addRule('GET /abc') // 在 uri 串基础上,补充请求方法的匹配
cacheManager.addRule('/abc/:id') // 带可变部分的 uri 串

cacheManager.addRule(/\/(abc|cba)$/ig) // 正则表达式

cacheManager.addRule({
  method: 'POST',
  url: '/abc',
  dataSchema: [
    {name: 'param1', schema: {value: /(aaa|bbb)/ig}},
    {name: 'param2', schema: {value: '123'}},
  ],
}) // 规则对象

More rules can be found in addRule documentation

Each request that hits the rule generates a cache ID according to a certain policy. If two requests generate the same cache ID, the latter covers the former, so be aware of this when writing the rule. In general, different URLs or different request methods, the generated cache ID must be different;If the request parameters are different, you need to consider whether the given rule takes the parameters into account. For detailed caching id generation policies, refer to the addRule documentation .

Caching storage uses separate user space (does not occupy user storage), but there are limits on the number and size of caches, so don't overuse caches. Use the rules to cache only necessary requests as much as possible.

See the api documentation for detailed usage of the cache manager. [is a complete runnable example, which can be experienced by referring to the README of the example.

# Cloud hosting using cacheManager

The interface called through wx.cloud.callContainer can also be optimized for the weak net experience using wx.createCacheManager. Caching requests require the developer to call addRule to add rules.There is a uniform specification for the url field in the addRule parameter: https://wx.cloud.callContainer/env/servicename/path, where env / servicename / path corresponds to the ID field for wx.cloud.callContainer's calling service.For example, for the following cloud call, you can add caching rules as an example:

const res = await wx.cloud.callContainer({
    config: {
      env: 'test-123'
    },
    path: '/api/count',
    header: {
      'X-WX-SERVICE': 'express-server',
      'content-type': 'application/json'
    },
    method: 'GET',
    data: {
      action: 'inc'
    },
})

// Add a cache rule
cacheManager.addRule({
    url: 'https://wx.cloud.callContainer/test-123/express-server/api/count',
    method: 'get'
})

# Other

Some of the wxapi caches after accessing the cache manager. See wx.createCacheManager Documentation, developers can also adjust which wxapi to cache.

It should be noted that such aswx.login,wx.checkSessionThe fact that an interface supports a cache is not equivalent to the fact that the interface is available in a weak network,The cache simply returns the results of the last successful call, and the logic of the interface itself is not changed, meaning that the cache returns content that has a time limit such ascodeis not refreshed and still expires.The cache is provided here only to reduce the cost of retrofitting some scenarios.

Other parts of the interfaces / components that require user authorization will be supported at a repository level for use on weak networks, as before, without developers having to modify them.