Implementation of H5 Preloading

Preloading is a preload if it is small, and it is the most basic function of HybridApp if it is large.
Html5 officially has a prefetch attribute , which is used for prefetching between pages. In fact, this process is more necessary in the process of native jumping h5 container, otherwise it will easily lead to the deterioration of the experience.
There are actually quite a few options:

  • The advantage of directly downloading the url + WebView#loadDataWithBaseURL
    is that it is simple, but the disadvantage is that it can only preload the html content of the next page. In this way, the actual effect is very poor, and often only less than 1% of the data can be preloaded.

  • Loading with a hidden WebViewFragment and doing animation display when needed has the
    advantage of being the fastest, and there are many pits:

    • The html loading process is complete, and the control behavior requires a lot of branch judgments in WebChromeClient/WebViewClient
    • Requires compatible animation effects
    • need to control back
    • Most importantly, it will lead to unreasonable triggering of functions such as window#onload in js, causing logical problems
  • Using WebView to load in advance, relying on WebView's cache
    is still not complicated, because js can be disabled when preloading, and js is allowed when it is actually loaded, and the control part of the previous solution is solved. The problem is that WebView's Cache is integrated, and it is completely clear. Once the cache needs to be cleaned up, there will be various global problems.

  • Using WebView to load in advance, handwriting cache
    is the most complicated solution, but there are no pits at present.
    Specifically:

    • In the prefetch stage, rewrite WebViewClient#onLoadResource to download all resources locally
      • Local cache file structure: use baseUrl#hashCode to generate a folder, and each resource is cached in the file of baseUrl#hashCode/resourceUrl#hashCode
      • During the caching process, mark it to ensure that unfinished resources are not read
      • mime and charset are parsed by the content-type of HttpURLConnection
    • In the reuse phase, rewrite WebViewClient#shouldInterceptRequest and redirect all resource requests to the local stream
    • In the clean-up phase, hand it over to the outside, and the outside will clean up the corresponding cache through baseUrl or the root directory.

The above idea found a problem: all preloaded web pages will be downloaded twice, because the WebView's own download is not blocked. The best way to solve this is to add a proxy to WebView and store all data in the proxy. At first glance, WebView does not have a Proxy interface, so the Internet is unrestrained . However, think about it, isn't shouldInterceptRequest a Proxy? Just wrap a layer on the original InputStream and do what you want in the wrapper. So the final solution is:

  • In the prefetch stage, rewrite WebViewClient#shouldInterceptRequest, generate HttpUrlConnection for each request, register an onValueRead callback for the obtained InputStream, and store the read data in the callback
    • mime will be imprecise, resulting in display errors, solutions

Other parts are the same as the previous method.

To elaborate, there are several areas worth improving:
- fat32 has poor multi-file support. So it's better to do your own resource positioning method
- VasSonic handles streams more carefully, you can make an adapter layer, and it can be used if the file is only half downloaded
- At present, everything is based on md5, in fact, it is changed to the original file path Probably also good
- some resources can be preset, all you need is to distinguish the source of the stream (File or net)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325837310&siteId=291194637