Abstract:


Click here to view the original: http://click.aliyun.com/m/43049/

Author: Ali Cloud – Mobile Cloud – big front end team

preface

Weex aims to combine the dynamic nature of the Web and native user experience. If you want to maximize the advantages of both, then cache is particularly important. This article describes how to use cache to quickly open weeX pages, or even “open in seconds” effect.

The body of the

To implement native caching, there are two levels:

  • JS file cache
  • Request Request cache

Simply caching JS files is useless unless your JS file is at the Hello World level: no network requests are made inside the JS to load other resources. Someone says my JS also has network request, request a picture, also can ah? Nine times out of ten that’s because SDWebImage, that’s because you implemented the protocol for loading images, and SDWebImage already did the caching for you.

Here’s how weeX supports common network caching on iOS:

JS file cache

There are two general ideas:

  • Preloading type: after startup, the client actively pulls from the server using JS and caching. So the next use of the JS file can be achieved “second open”.
  • It is similar to the traditional network cache type. When loading the JS file for the first time, you need to load it over the network. When accessing the JS file next time, you need to set the cache policy.

The preloading mode is also a common cache mode. It is preloaded after startup and will not be described here.

The second type has been described in detail in an article:

  • Implementation of JS Cache in Weex

The specific ideas are shown in the flow chart as follows:

The specific steps are as follows:

  • Rewrite renderByUrl before downloading JS
  • Overwrite render when rendering
  • Replace the original WXSDKInstance with the custom WXSDKInstance on the page

The first step is to rewrite renderByUrl before downloading JS

After getting the URL of JS on the server side, check whether there is local JS cache first. If there is, check against MD5 of local JS and JS on the server side. If the check passes, use local JS directly; otherwise, download JS on the server side as planned. Weex supports the use of local JS files.

@Override
public void renderByUrl(String pageName, String url, Map<String, Object> options, String jsonInitData, WXRenderStrategy flag) {

   String local = "";
   if(TextUtils.isEmpty(url) || md5Check(url)){
       local= getLocalJs(); // get the local JS path}if(! TextUtils.isEmpty(local){
       super.renderByUrl(pageName, local, options, jsonInitData, flag);
   }else{ super.renderByUrl(pageName, url, options, jsonInitData, flag); }} /** * Get the local JS path */ private StringgetLocalJs(){
   try {
       File f = new File(context.getFilesDir(), "local_js.txt");
       if(f.exists()) {
           return "file://" + f.getAbsolutePath();
       }
   } catch (Exception e) {
   }
   return "";
}Copy the code

The second step is to rewrite the render

If the JS file is downloaded from the server, you need to cache the file.

@Override public void render(String pageName, String template, Map<String, Object> options, String jsonInitData, WXRenderStrategy flag) { saveWeexFile(template); super.render(pageName, template, options, jsonInitData, flag); } @param template */ private void saveWeexFile(String template){if(isLocalFile(getBundleUrl())){
       return; } Observable .just(template) .map(new Function<String, Boolean>() {@override public Boolean apply(String s) throws Exception {// WEEx is not sensitive to file names and saves TXT filesreturn FileUtil.saveFile(context.getFilesDir().getAbsolutePath(), "local_js.txt", s.getBytes("UTF-8"));
                   }
               })
           .subscribeOn(Schedulers.io())
           .subscribe(new Consumer<Boolean>() {
               @Override
               public void accept(Boolean aBoolean) throws Exception {
                   if(aBoolean){// Cach successfully}}},new Consumer<Throwable>(){@override public void accept(Throwable) throws Exception {  throwable.printStackTrace(); }}); Private void saveWeexFile(String template){private void saveWeexFile(String template){if(isLocalFile(getBundleUrl())){
       return;
   }
   Thread thread = new Thread( new Runnable(){
       @Override
       public void run(){
           FileUtil.saveFile(context.getFilesDir().getAbsolutePath(), "local_js.txt", template.getBytes("UTF-8")); }}); thread.start(); } /** * private Boolean isLocalFile(String url){if(TextUtils.isEmpty(url){
       return false;
   }
   Uri uri = Uri.parse(url);
   if(uri ! = null && TextUtils.equals(uri.getScheme(),"file")) {
       return true;
   }
   return false;
}Copy the code

Step 3 Replace the original WXSDKInstance with the custom WXSDKInstance on the page

Note: If the WEEx page is not updated frequently, there is no need to perform file verification every time. Each time the app is started, file verification is performed once and MD5 is cached. Subsequently, the page is opened for local MD5 verification.

The request cache

The above introduction is the JS cache, but after the JS file cache, it is still unable to achieve no network condition, directly open JS page, JS page still has a large number of resource files, JS files will send network requests, these network requests still need to use the cache strategy.

The basic idea for caching in this section is as follows:

  • This is the same as a traditional cache.
  • Add a caching method: cache first, network later.

You can set an extension for the WEEX network request. After setting this extension, all the WEEX SDK network requests are processed by this extension. Therefore, the request part is the same as the traditional cache. For example, we are familiar with NSCache, YYCache and other third-party network request methods can also be reused.