preface

Many apps are now embedded with H5 pages, which are characterized by short development cycle and good flexibility. However, WebView performance issues continue to affect the user experience. In particular, slow loading and traffic consumption are highlighted.

General H5 loading process

Usually, static resources such as HTML/JS/CSS are put on THE CDN, and then after the page is loaded, CGI is used to pull the latest data for splicing display. The loading flow of this mode is as follows:

  1. Initialization before loading, including Runtime initialization, WebView creation, etc.
  2. After initialization, the WebView starts to request resources to load the H5 page;
  3. The page initiates a CGI request for the corresponding data (or gets it from the local cache), and then updates the DOM.

Intuitive problems from the perspective of the process:

  1. Terminal time: During the terminal initialization phase (the network data shows that the time is more than 1s), the network is in idle waiting state, wasting time.
  2. Resources and data are dynamically pulled, the speed of which is limited by the network speed.

Existing problems

The rendering speed of H5 page mainly depends on three points: rendering speed, resource loading speed and WebView creation time: The rendering speed depends on two aspects:

  1. JS parsing efficiency: If there are many JS files and the parsing process is complex, the parsing speed will be slow.
  2. Hardware performance: Mobile phone hardware performance is also an important factor affecting the rendering speed, Android models are seriously fragmented, performance is uneven.

Resource loading speed: Generally, loading an H5 page will generate multiple network requests, including:

  1. H5’s own main URL request;
  2. Images, CSS files, external reference JS files held by H5, etc., are all a separate HTTP request. These files are downloaded before rendering is completed, and each request is serial, causing the H5 to load slowly.

WebView creation time: It takes a long time to initialize a local WebView. The initial initialization of a WebView is different from the second initialization, which is much slower than the second initialization. Cause guess: After the webView is initialized, some global service or resource objects shared by the WebView are not released even though the WebView has been released. These objects do not need to be initialized during the second initialization. H5 traffic consumption is mainly due to the need to reload the H5 page every time the H5 page is used. Each load generates more network requests. The problem is summarized as follows:

The solution

Mainstream solutions to the above problems include:

  1. WebView has its own H5 caching mechanism
  2. preload
  3. The offline package

Caching mechanisms

There are many features in H5, including the important feature of offline storage (also known as caching). The inclusion of caching means that Web applications can be cached and accessed offline without a network. The benefits of caching include:

  1. Offline access: Users can use it in offline environment
  2. Improved speed: Cached local resources load faster
  3. Reduce server stress: Download the updated file instead of going through the full request process every time the page loads

So far, there are six cache mechanisms of H5, which are as follows:

  1. Browser caching mechanism
  2. Dom Storgage (Web Storage) Storage mechanism
  3. Web SQL Database storage mechanism
  4. Indexed Database (IndexedDB)
  5. Application Cache (AppCache) mechanism
  6. File System API

Browser caching mechanism

The browser Cache mechanism is based on cache-Control, Expires, Last-Modified, and Etag headers in the HTTP protocol header:

  • Cache-control: used to Control the local Cache duration of a resource: There are more than a dozen cache-control values, including those carried in the request header and those carried in the response header. For example, max-age=

    Sets the maximum period during which the cache is stored. After this period, the cache is considered expired (in seconds). If the cache is requested again within this period, the browser does not send an HTTP request, but directly uses the locally cached file. No-cache does not mean no cache and forces the cache to submit requests to the original server for validation before publishing a copy of the cache. The cache resource is not directly fetched before any cached response is used in each request. Instead, the server validates the request first, and then the cache is used. Otherwise, the new resource returned by the server is used. The no-store is truly non-cached and does not store anything about client requests or server responses. Local and proxy servers are not buffered and are fetched from the server each time. Neither request nor response information is stored on each other’s disk systems.

  • Expires: Similar to cache-control, the response header contains a date/time (GMT) indicating that the response Expires after this time. The browser will not request the resource again until Expires is set. However, if the local time and the server time are not synchronized, this can cause problems, hence the above cache-control. Note that cache-Control takes precedence over Expires. If a max-age is set in the cache-control response header, the Expires header is ignored. Example: Expires: Wed, 21 Oct 2015 07:28:00 GMT

  • Last-modified: contains the date and time when the resource identified by the source server was Modified, indicating the Last update of the file on the server. Determine whether the received or stored resources are consistent with each other. If the file cache expires on a second request, the browser sends this time in the if-Modified-since field to the server, which compares the timestamp to determine whether the file has changed. If the requested resource has not been modified since the time it was received, a 304 response with no message body is returned telling the browser to use the cache. Otherwise, 200 is returned, along with the latest resource. Less accurate than ETag, it is a backup mechanism.

  • ETag: Similar to last-Modified, it identifies the Last time a file was updated on the server. The difference is that the value of ETag is a character string that identifies the file. When querying the server for updates to the file, the browser sends the character string to the server via the if-none-match field. The server compares the client’s ETag with the ETag of the current version of the resource. If the two values Match (i.e., the resource has not changed), The server returns 304 unmodified status with no content telling the browser to use the cache. The method for generating ETag values is not explicitly specified. Typically, you use the hash of the content, modify the hash of the timestamp last, or simply use the version number. Either ETag or Last-Modified can be used together as required. When two files are used at the same time, the file is considered not updated as long as one of the base conditions is met.

Common uses are cache-Control with last-Modified and Expires with ETag. One is responsible for controlling how long the cache lasts, and one pair is responsible for determining whether the cache needs to be updated after it has expired. There are also two special cases:

  1. Manual refresh (F5) the browser thinks the cache has expired and adds a field to the requestCache-Control:max-age=0, directly queries the server for files that need to be updated.
  2. When you force a page refresh (Ctrl+F5), the browser ignores the local cache and adds a field to the requestCache-Control:no-cacheTo request new resources directly from the server.

Browser cache is mainly used to store static resource files, such as JS, CSS, fonts, pictures and other resources. Webview will store cached file records and file contents in the data directory of the current APP. WebView is automatically implemented using the default CacheMode. You can also set the cache mode manually:

WebSettings webSettings = webView.getSettings();
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
Copy the code
  1. LOAD_CACHE_ONLY: Does not use the network, only reads the local cache data
  2. LOAD_DEFAULT: Determines whether to fetch data from the network according to cache-control
  3. LOAD_CACHE_NORMAL:API level 17 is deprecated. From API level 11, the LOAD_DEFAULT mode is used
  4. LOAD_NO_CACHE: Does not use caching and only gets data from the network
  5. LOAD_CACHE_ELSE_NETWORK: Data in the cache is used whenever it is locally available, regardless of expiration or no-cache. It is obtained from the network only when there is no local cache.

Generally set to the default cache mode is ok. The advantage of browser caching is that it supports the Http protocol layer. The disadvantages are:

  1. The cache file can be generated only after the first load;
  2. The space of the terminal cache is limited, and the cache may be cleared.
  3. Cache usage lacks verification and may be tampered with.

Description of each header: cache-Control, Expires, Last-Modified, ETag

Dom Storage mechanism

Dom Storage’s official description is:

DOM storage is an umbrella term for a set of storage-related features first introduced in the Web Applications 1.0 specification that have been separated and developed into a separate W3C Web storage specification. DOM storage is designed to provide a larger, more secure, and more convenient way to store information in cookies that the server does not need to know. The Dom Storage mechanism is similar to Cookies, but has some advantages. Dom Storage is provided by storing key-value pairs of strings. Dom Storage stores data locally, unlike Cookies, which are sent to the server each time a page is requested. DOM Storage is divided into sessionStorage and localStorage. The use methods of the two are basically the same. The difference lies in the different scope of function: The former is temporary, storing page-related data that cannot be used after the page is closed, and the latter is persistent, that is, the saved data can be used after the page is closed.

  • SessionStorage is a global object that maintains storage available for the duration of a page session. The page session cycle lasts as long as the browser is open. The page session is also always present when the page is reload or restores. Each time a new page is opened in a new TAB or window, a new session is initiated.
  • LocalStorage stores data that is persistent. The current PAGE is closed (after the PAGE Session ends), and the saved data still exists. Re-open the PAGE and the data saved last time can be retrieved. In addition, the Local Storage is global. When two pages are opened at the same time, the Storage data is shared. Data modification in one PAGE can be detected in the other PAGE.

Dom Storage has the following advantages: large Storage space (5M), much larger than Cookies (4KB). In addition, data is stored locally without frequent interaction with the server, making Storage secure and convenient. Can be used to store temporary simple data. The mechanism is similar to SharedPreference. However, if you want to store structured data, you might want to use JSON, where the objects to be stored are converted to JSON strings. It is not suitable for storing complex data or large storage space, and it is not suitable for storing static files. The usage method is as follows:

webSettings.setDomStorageEnabled(true);
Copy the code

Web SQL Database storage mechanism

Web SQL Database The Web SQL Database storage mechanism is used to store structured data suitable for the Database. It makes full use of the advantages of the Database to store structured data suitable for the Database. The Web SQL Database storage mechanism provides a set of convenient data adding, deleting, modifying, and querying. Android also uses a large number of databases to store data, such as contacts and short messages. The database format is SQLite. Android also provides apis to manipulate SQLite. The Web SQL Database storage mechanism provides this Native functionality to the Web by providing a set of apis that are implemented by browsers. The implementation method is as follows:

String cacheDirPath = context.getFilesDir().getAbsolutePath()+"cache/"; / / set the cache path webSettings. SetDatabasePath (cacheDirPath); webSettings.setDatabaseEnabled(true);
Copy the code

The Web SQL Database storage mechanism is officially no longer recommended and has been discontinued in favor of the IndexedDB caching mechanism

Indexed Database caching mechanism

IndexedDB is also a Database storage mechanism, unlike the Web SQL Database caching mechanism, which is no longer supported. IndexedDB is not a traditional relational database, but a NoSQL database that provides Storage by storing key-value pairs of strings (similar to Dom Storage, but more powerful and with more Storage space). The Key is required and unique. The Key can be defined or automatically generated by the system. Value is also required, but Value is very flexible and can be any type of object. Generally, Value is accessed by Key. IndexedDB provides an asynchronous set of apis for storing, fetching, and traversing data. IndexedDB has a very powerful feature: index. It can generate an index for any property in a Value object and then quickly query the Value object based on the index. IndexedDB combines the advantages of Dom Storage and Web SQL Database to store large or complex structures of data, providing greater Storage space and making it easier to use. Can be used as an alternative to Web SQL Database. But it’s not very good for caching static files. IndexedDB is now supported in Android 4.4. Enable IndexedDB as follows:

webSettings.setJavaScriptEnabled(true);
Copy the code

Application Cache (AppCache)

The caching mechanism of AppCache is similar to that of the browser Cache (cache-Control and Last-Modified). Both files are cached on a per-file basis, and files are updated to a certain extent. But AppCache complements, not replaces, the browser caching mechanism. AppCache has two key points: the manifest property and the MANIFEST file. When loading the manifest file for the first time, the browser parses the manifest attribute, reads the manifest file, retrieves a list of files to be cached under Section:CACHE manifest, and then caches the file. AppCache also has an update mechanism. To update cached files, update the manifest file. When changes are found, the manifest file is retrieved, and the manifest file and the cache file are checked and updated in accordance with the browser cache mechanism. Used to store static files (such as JS, CSS, font files). AppCache is no longer recommended and is no longer supported by the standard. Usage:

String path = getApplicationContext().getDir("cache", Context.MODE_PRIVATE).getPath(); / / set the cache path webSettings. SetAppCachePath (path); / / set the cache size webSettings. SetAppCacheMaxSize (10 * 1024 * 1024); / / open the cache webSettings. SetAppCacheEnabled (true);
Copy the code

File System

File System is a new storage mechanism added to H5. It provides Web Apps with a virtual file system running in a sandbox. The virtual file systems of different WebApps are isolated from each other, and the virtual file system is isolated from the local file system. Web App Creates, reads, writes, deletes, and traverses files (folders) through a set of File and folder operation interfaces provided by File System API in a virtual File System. Browsers provide two types of storage for virtual file systems: temporary and persistent:

  • Temporary storage is automatically allocated by the browser, but may be reclaimed by the browser;
  • Persistent storage space needs to be displayed. When applying for persistent storage space, the browser will prompt the user to confirm the application. The storage space for persistence is managed by the WebApp itself, and the browser does not recycle or clean up the content. The storage space size is managed by quota. You need to apply for an initial quota for the first time and apply for another quota when the quota is used up.

The advantages of File System are:

  • Binary data that can store large volumes of data
  • Preloadable resource files
  • Edit files directly

Unfortunately, since File System is a new caching mechanism added to H5, it is not currently supported by Android WebView.

Summary of Caching mechanisms

The name of the The principle of advantages The applicable objects instructions
Browser cache Use HTTP header fields for cache control Supports the HTTP protocol layer Storing static Resources Android Default implementation
Dom Storage By storing key-value pairs Large storage space, local data, safe and convenient Similar to Cookies, storing temporary, simple data Similar to SP in Android
Web SQL DataBase Based on SQL Take advantage of database, add, delete, change and check conveniently Store complex and large amount of structured data IndexedDB is not recommended
IndexedDB Implementation by storing key-value pairs (NoSQL) Large storage space, simple and flexible use Store complex and large amount of structured data Collection of Dom Storage and Web SQL DataBase
AppCache Similar to browser caching, caching is done on a file basis Build convenient Offline cache, storage of static resources Additions to the browser cache
File System Provides a virtual file system Can store binary data, preload resources and edit files between Manage data through the file system Currently not supported on Android

preload

  • Preloading data: Build cache in advance and load THE H5 pages that will be used in advance — When initializing the WebView, the network requests data directly from Native. When the page initialization is completed, the data requested by its proxy is obtained from Native. Data requests and WebView initialization can be carried out in parallel, shortening the overall page loading time. Implementation idea: Configure a pre-loaded list of pages and resources containing the required H5 modules, request them in advance when appropriate, the client takes over the cache of all requests, and the two shouldInterceptRequest methods of the WebViewClient. No need for webView default cache logic, self-implementation of the cache mechanism.

  • Preloading a WebView: It takes longer to initialize a WebView for the first time than for subsequent uses. After a WebView is initialized, even if the WebView is released, some global service or resource objects shared by the WebView are still not released, and these objects do not need to be initialized again during the second initialization. And creating WebView objects multiple times takes time and resources. Initializing a WebView object in Application; Build a WebView reuse pool, reuse it, and avoid creating it every time.

The offline package

H5 pages and resources such as static resource files (CSS, images, etc.) that are frequently updated can be packaged and delivered to the client. The client can decompress the files to local storage. Intercept the network request and detect it before loading the H5 request network resource. If the local static resource is successfully matched, the system directly reads the local resource for replacement, thus avoiding obtaining the H5 request from the server. Implementation method:

mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                view.loadUrl(url);
                return true; } @Nullable @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { boolean isMatch = ... // Determine whether the resource matchesif (isMatch) {
                    WebResourceResponse response = ...
                    if(response ! = null) {returnresponse; }}returnsuper.shouldInterceptRequest(view, url); }});Copy the code

Advantages are localization, fast loading of the first screen, user experience is closer to native, can not rely on the network, offline operation. The disadvantage is the complexity of the development process and update mechanism, which requires the cooperation of the client and the server.

Open source solutions

CacheWebView: Use Okhttp to download resources by intercepting shouldInterceptRequest, and configure a cache interceptor for OkHttpClient

VasSonic: VasSonic is a lightweight, high-performance Hybrid framework designed to speed up the first screen of a page. It supports both static and dynamic pop-up pages, and supports pre-loading and offline packages. Advantage is good performance, fast speed, large factory produced, the disadvantage is complex configuration, at the same time need to access the front and back end.

conclusion

Although this article lists and analyzes some performance issues and solutions of Android WebView, it does not provide in-depth analysis and detailed optimization tutorials. Specific use should be combined with their own project optimization. Here are some articles for you to learn:

  • Brief analysis of H5 Cache mechanism – Optimization of mobile Web loading performance
  • Android H5 seconds open scheme research — Toutiao H5 seconds open scheme details
  • Tencent has come up with VasSonic to make the first screen of your H5 page open in seconds