preface

Our weekly knowledge review program at 📖 continues. This article is a collection of the second and third issues of the Hybrid APP Theme.

This issue sorted out 10 questions, and the corresponding reference answers, more text and pictures, we suggest that you can collect, according to the article catalog to read.

Previously shared weekly content, I have sorted into the nuggets collection 📔 “EFT Every Monday practice” on the, welcome to click on the collection 💕💕.

Content Review:

  1. EFT Weekly review of 5 Essential Knowledge Points for Hybrid App Development

  2. EFT Share of the Week: a Review of 15 common Facts about HTTP

  3. EFT Weekly Share — A Collection of Data Structures and Algorithms

Articles included:

All articles in this series will be posted on Github.

Note: this article collates some data source network, some pictures/paragraphs can not find the original source, if there is infringement, contact delete.

What is the difference between UIWebView and WKWebView in iOS platform?

Reference article: UIWebView and WKWebView

UIWebView is a class that Apple inherits from UIView to load Web content. It can load any remote web data to display on your page, and you can do things like forward and backward refresh like a browser. However, After iOS8, Apple introduced WKWebView to load the Web and apply it to iOS and OSX. It replaces UIWebView and WebView and supports the same SET of apis on both platforms.

It breaks up the design of UIWebView, it breaks it up into 14 classes and 3 agent protocols, but it’s actually a little bit easier to use, according to the principle of single responsibility, what each protocol does is classified by function.

WKWebView differs from UIWebView:

  • WKWebView has much less memory overhead than UIWebView, and no cache;

  • WKWebView has a scrolling refresh rate of up to 60FPS and built-in gestures;

  • WKWebView supports more HTML5 features;

  • WKWebView efficient APP and Web information exchange channel;

  • WKWebView allows JavaScript’s Nitro library to be loaded and used, UIWebView limits;

  • WKWebView currently lacks an API for page numbers;

  • WKWebView provides properties for loading web pages.

  • WKWebView uses the same JavaScript engine as Safari;

  • WKWebView added the loading progress attribute: estimatedProgress;

  • WKWebView does not support page caching and requires its own cookie injection, whereas UIWebView automatically injects cookies.

  • [Fixed] WKWebView cannot send POST parameter

  • WKWebView can intercall functions with js directly, unlike UIWebView, which requires a third-party library called WebViewJavascriptBridge to help handle interaction with js.

Note:

Most apps need to support iOS7 or higher versions, and WKWebView can only be used after iOS8, so a compatibility solution is needed, which is UIWebView under iOS7, WKWebView after iOS8. But there are very few under IOS10 right now,

Summary:

Compared with UIWebView, WKWebView has a great improvement on the whole, meeting the function of using the same set of controls on iOS, while optimizing the whole memory overhead, scrolling refresh rate and JS interaction.

According to the principle of single responsibility, it is divided into three protocols to realize the response of WebView, which decouples the RESPONSE processing of JS interaction and loading progress.

WKWebView does not cache processing, so the load performance of the web page need cache is not so high or can consider UIWebView.

WKWebView has some pits?

Reference article: WKWebView Pits

1. The WKWebView screen is blank

WKWebView is actually a multi-process component, which is why it loads faster and has lower temporary memory usage.

In UIWebView, when the memory usage is too high, the App Process will crash; In WKWebView, when the overall memory consumption is relatively large, the WebContent Process will crash, resulting in a white screen phenomenon.

Solutions:

  1. With the help of WKNavigtionDelegate

When WKWebView’s total memory usage is too large and the page is about to go blank, the system will call the above callback function. We perform [webView reload] in this function (webView.URL value is not nil at this time) to solve the blank screen problem. The current page may be frequently refreshed on some pages with high memory consumption. Therefore, you need to perform corresponding adaptation operations on H5.

  1. Check whether webView.title is empty

Not all H5 pages will call the above callback function when the H5 page is blank. For example, I recently encountered a system camera presented on a H5 page with high memory consumption, and a blank screen appeared when I returned to the original page after taking pictures (the process of taking pictures consumes a lot of memory, resulting in memory strain. The WebContent Process is suspended by the system), but the above callback function is not called. Another phenomenon is that webView.titile is empty when WKWebView is white, so you can check webView.title is empty when viewWillAppear to reload the page.

2. WKWebView Cookie problem

The problem with WKWebView cookies is that requests made by WKWebView don’t automatically carry cookies stored in the NSHTTPCookieStorage container, whereas UIWebView does.

The reason is:

WKWebView has its own private storage and does not store cookies in the standard Cookie container NSHTTPCookieStorage.

Practice found that WKWebView instances actually store cookies in NSHTTPCookieStorage, but there is a delay in the storage timing. On iOS 8, when the page jumps, The Cookie on the current page is written to NSHTTPCookieStorage, and on iOS 10, Cookies injected by JS document.cookie or server set-cookie are quickly synchronized to NSHTTPCookieStorage, FireFox engineers recommended that you reset WKProcessPool to trigger the Cookie synchronization to NSHTTPCookieStorage. However, the reset WKProcessPool does not work and may cause the loss of session cookies on the current page.

Solution 1:

Before WKWebView loadRequest, set the Cookie in the request header to solve the problem that the Cookie cannot be carried in the first request.

Solution 2:

Cookie through document.cookie set cookie to solve the subsequent page (domain)Ajax ‘ ‘, iframe request cookie problem; (Note: document.cookie() cannot set cookies across domains).

3. WKWebView loadRequest problem

The body data of a POST request made from loadRequest on WKWebView will be lost. Also due to interprocess communication performance, the HTTPBody field is discarded.

4. WKWebView NSURLProtocol problem

WKWebView performs network requests in a separate process from the app process. The request data does not pass through the main process, so using NSURLProtocol directly on WKWebView cannot intercept requests.

Solutions:

Because WKWebView performs network requests in a separate process. Once the HTTP (S) Scheme is registered, Network requests are sent from Network Process to App Process so that NSURLProtocol can intercept Network requests. In the design of Webkit2, MessageQueue is used to communicate between processes. The Network Process will encode the request into a Message, and then send it to the App Process through IPC. HTTPBody and HTTPBodyStream are discarded for performance reasons.

5. WKWebView page style problem

In the process of WKWebView adaptation, we found that the position of some H5 page elements was downward offset or stretched and deformed. After tracing, we found that it was mainly caused by abnormal height value of H5 page.

Solutions:

Adjust WKWebView layout, avoid to adjust the webView scrollView. ContentInset. In fact, even on the UIWebView directly adjust the webView is not recommended. The scrollView. ContentInset value, it will bring some strange questions. If you have to adjust the contentInset in some special cases, you can use the following methods to restore the H5 page to normal display.

6. WKWebView screenshot problem

In WKWebView, using -[CALayer renderInContext:] to capture a screen is invalid. You need to use the following methods to capture a screen:

@implementation UIView (ImageSnapshot) 
- (UIImage*)imageSnapshot { 
    UIGraphicsBeginImageContextWithOptions(self.bounds.size,YES,self.contentScaleFactor);
    [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES]; 
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return newImage; 
} 
@end
Copy the code

However, this approach still does not solve the problem of webGL page screenshots, which result in blank or plain black images.

Solutions:

In desperation, we can only agree on a JS interface, and let game developers implement this interface. Specifically, the canvas getImageData() method is used to obtain image data and return base64 data. When the client needs screenshots, Call this JS interface to get the Base64 String and convert it to UIImage.

7. WKWebView crash problem

If WKWebView exits and JS executes window.alert(), the alert box may not pop out, and the completionHandler is not executed, causing crash.

The other case is that as soon as WKWebView is opened, JS executes window.alert(). This time, because the animation of the UIViewController (push or present) in which WKWebView is located has not yet finished, The alert box might not pop up, and the completionHandler might not be executed at the end, causing crash.

8. Automatic video playback

WKWebView need WKWebViewConfiguration. MediaPlaybackRequiresUserAction set whether to allow automatic playback, but must be set before the WKWebView is initialized, Setting invalid after WKWebView initialization.

9. GoBack API problems

WKWebView -[WKWebView goBack] will not trigger window.onload() and JS will not be executed.

10. Page scroll rate

WKWebView needs to adjust the scrolling rate via scrollView Delegate:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    scrollView.decelerationRate = UIScrollViewDecelerationRateNormal; 
}
Copy the code

What is a Crosswalk and what does it do?

Reference site: Crosswalk Github Reference Article: Crosswalk Introduction

Crosswalk is an open source Web engine. Currently Crosswalk officially supports mobile operating systems including Android and Tizen. The Crosswalk Web application in Android 4.0 and above can have a consistent experience in HTML5. Meanwhile, integrated interaction with the system (such as splash screen, permission management, application switching, social sharing, etc.) can be similar to native apps.

Crosswalk is now a recommendation engine for many well-known HTML5 platforms and applications, including Google Mobile Chrome App, Intel XDK, Famo.us and Construct2, to name a few. Crosswalk integration is also planned for future Cordova 4.0.

Four, what are some common WebView performance optimization schemes?

0. Problem analysis

First of all, we need to know what stages an ordinary user usually goes through to open a WebView. There are generally these stages:

  1. Interaction without feedback;

  2. A new page is displayed, showing a blank screen.

  3. The basic frame of the page appears, but there is no data; The page is in loading state.

  4. The required data appears;

When the App is first opened, the browser kernel is not initialized by default; The basic framework of the WebView is created only when the WebView instance is created.

So unlike a browser, the first step to open a WebView in an App is not to establish a connection, but to launch the browser kernel.

So we found one of the reasons why WebViews are always slow:

  • In the browser, when we enter the address (or even before), the browser can start loading the page.

  • On the client side, the client takes time to initialize the WebView before loading it.

At this point, since the WebView doesn’t exist yet, all subsequent processes are completely blocked. Therefore, since this process occurs in native code, it is impossible to optimize it solely by front-end code. Most of the solutions are front-end and client collaboration. Here are a few that have been used in the industry:

1. Global WebView

When the client is just started, it initializes a global WebView to be in use, and hides it. When the user accesses the WebView, it directly uses this WebView to load corresponding web pages and display them.

This method can effectively reduce the first opening time of WebView in App. There is no need to initialize the WebView time when the user accesses the page.

Of course, there are some problems with this, including:

  • Extra memory consumption.

  • Skipping between pages requires clearing the traces of the previous page, which is more prone to memory leaks.

2. Dynamic loading of WebView

Reference article: “WebView common optimization scheme”

WebView loads dynamically. So instead of writing a WebView in XML, you write a layout, and then you add the WebView.

WebView mWebView = new WebView(getApplicationgContext());
LinearLayout mll = findViewById(R.id.xxx);
mll.addView(mWebView);

protected void onDestroy(a) {
    super.onDestroy();
    mWebView.removeAllViews();
    mWebView.destroy()
}
Copy the code

There is a problem with getApplicationContext(), which is also used to prevent memory leaks. If you need to open a link in a WebView or if you’re opening a page with Flash, getting your WebView and trying to pop up a dialog will cause a cast error from ApplicationContext to ActivityContext, So your app crashes.

This is because when loading Flash, the system will first treat your WebView as the parent control, and then draw Flash on that control. It wants to find an Activity Context to draw it, but you pass in an ApplicationContext. And then it crashed.

3. An independent Web process, separated from the main process

Reference article: “WebView common optimization scheme”

This method is used in super apps like QQ and wechat, and it is a proven solution to any WebView memory problem for encapsulated Webactivities set in manifest.xml.

<activity 
    android:name=".webview.WebViewActivity" 
    android:launchMode="singleTop" 
    android:process=":remote" 
    android:screenOrientation="unspecified" 
/>
Copy the code

Then destroy the process when closing the WebActivity:

@Overrideprotected void onDestroy(a) {                
super.onDestroy(); 
    System.exit(0);
}
Copy the code

Close the browser and destroy the entire process, which generally doesn’t cause memory leaks or anything like that 95% of the time, but it does involve interprocess communication on Android, which is not easy to handle, and is an alternative.

4. Release the WebView

Reference article: “WebView common optimization scheme”

public void destroy(a) {
    if(mWebView ! =null) {
        // If you call destroy() first, you will hit if (isDestroyed()) return; For this line of code, onDetachedFromWindow(), and
        // destory()
        ViewParent parent = mWebView.getParent();
        if(parent ! =null) {
            ((ViewGroup) parent).removeView(mWebView);
        }
​
        mWebView.stopLoading();
        // Call this method on exit to remove the bound service, otherwise some specific system will report an error
        mWebView.getSettings().setJavaScriptEnabled(false);
        mWebView.clearHistory();
        mWebView.clearView();
        mWebView.removeAllViews();
​
        try {
            mWebView.destroy();
        } catch (Throwable ex) {
​
        }
    }
}
Copy the code

How to debug WebView on Android platform?

1. Debug on Chrome

Reference article: Android Debugging WebView

1.1 conditions:

  • Enable USB debug mode on an Android device or emulator running Android4.4 or higher.

  • Chrome 30 or later. More powerful WebView interface debugging features require Chrome31 or later.

  • Webviews in Android applications are configured to be debuggable.

1.2 Configuring WebView as debuggable in Android code:

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  
    WebView.setWebContentsDebuggingEnabled(true);  
}  
Copy the code

Note that Web commissioning is not affected by the debuggable flag state in the app manifest file. If you want to use Web commissioning only when debuggable is true, then the runtime detects this flag as follows:

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  
    if ( 0! = ( getApplcationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE ) ) { WebView.setWebContentsDebuggingEnabled(true); }}Copy the code

1.3 Enable USB debugging on the mobile phone and connect the COMPUTER with USB:

To open the Developer option of an Android phone, click the system Setting-Android version for several times to trigger the developer option, and then enter the developer option page to start USB debugging.

To avoid seeing this warning every time you debug, check Always allow from this computer and click OK.

1.4 Enabling USB Web Debugging in Chrome (does not affect WebView) :

Visit Chrome ://inspect/# Devices or about:inspect to access a list of debuggable WebViews.

Then select the page you want to debug from the WebView list, click the “Inspect” option, and use the Chrome console as you would a PC web page.

1.5 Tips:

//inspect/#devices if chrome does not detect the page in Remote Target, you may need to install the ADB plugin for Chrome. You can also visit https://chrome-devtools-frontend.appspot.com in Chrome;

(2) For Tencent APP, X5 kernel is used by default. We can open https://debugx5.qq.com/ inside the APP to use its Vconsole debugging tool for debugging. a.

2. Use the DebugGap for debugging

Reference article: WebView Debugging on Android

2.1 Downloading and Configuring the DebugGap on Windows:

Download the Windows DebugGap software package (download link: DebugGap) on the PC, and decompress it.

After the installation is complete, run the DebugGap and start the configuration:

  • In general,DebugGapYou can automatically get the IP and set the default port, if not, you can manually set;
  • Click the “Connect” button to start listeners for various clients;

2.2 Configuration on the Client:

Introduce debugap.js into the HTML interface to be tested in a debug project.

<script src="debuggap.js" type="text/javascript"></script>
Copy the code

When the debug project loads, your application will have a blue area, click on something that will appear as a four-leaf shamrock, click on “Configure” to display the configuration page. Enter the same host and port as those on the remote DebugGap, such as 192.168.1.4:11111, and click the Connect button.

1.4 PC remote DebugGap will detect incoming clients, and developers can click each client for debugging.

How to debug WebView in iOS platform?

Reference article: Safari Debugging webView/H5 page for iOS

Normally we debug through Safari on the Mac, but there are two things to note:

  • If the debugging is the WebView page in the APP, the package of this APP needs to support debugging. If it cannot be debugged, iOS developers need to re-sign the APP (the ID of our iOS device may need to be written into the list of trusted devices, Then use iTunes to install the test package provided by the client).

  • If you want to debug the H5 page, you can directly open the Safari browser on the mobile phone.

Here’s how to debug on a Mac:

1. Open the Safari development menu

Connect the iPhone to the Mac and open the Development menu in the Mac’s Safari preferences. The steps are as follows: Safari -> Preferences… -> Advanced -> Check Displays the “Development” menu in the menu bar.

2. Enable the Web inspector on the iPhone

The steps are as follows: Settings -> Safari -> Advanced -> Web Inspector.

3. Debug WebView in APP

Reference article: Front-end WEBVIEW Guide for IOS Debugging

In Safari-> development, when you see your device and the web page in the WebView, click the Inspector to open the corresponding page, which can be used for breakpoint debugging.

7. What role can Fiddler or Charles play in inline debugging?

Both are powerful packet capture tools that work as a Web proxy server, using the proxy address 127.0.0.1 and the default port 8888, which can also be changed by setting.

Proxy is to set up a checkpoint between the client and the server, the client will first request data sent out, the proxy server will intercept data packets, proxy server impersonates the client to send data to the server; Similarly, the server will respond with data, and the proxy server will intercept the data and send it back to the client.

The main functions of Fiddler or Charles are:

  • Can proxy requests, used to view the page sent requests and received responses;
  • You can modify the response to the request to simulate the data you want;
  • Can simulate the speed of network requests;
  • Can proxy server static resource request, point to the local file, save frequent release H5 package, achieve the purpose of fast debugging;

Additional link: Fiddler Tool Introduction 1

Eight, debugging enterprise wechat, wechat and nail version, which tools can be used?

1. Debug enterprise wechat and wechat

  • Wechat developer tools, can be used to debug the basic functions of the page;
  • Enterprise wechat interface debugging tool, can be used to debug the enterprise wechat interface;

2. Debug the nails

  • Nail Android development version, used to debug the Nail application on Android;

3. The general

  • Fiddler or Charles can debug applications by intercepting interface replacement files.

What are the common debugging skills?

1. Chrome console debugging

Reference article: Summary of common Front-end debugging Tips (continuously updated…)

1.1 Source panel breakpoint debug JS from left to right, each icon represents the function respectively:

  • Pause/Resume script execution: pauses/resumes script execution (program execution stops at the next breakpoint).
  • Step over next function call: Executes to the next function call (skip to the next line).
  • Step into next function call: Enters the current function.
  • Step out of current function: Jumps out of the currently executing function.
  • Deactive/Active all breakpoints: Closes/opens all breakpoints (does not cancel).
  • Pause on exceptions: Automatic breakpoint setting for exceptions.

1.2 Element panel debugging DOM:

Right-click on the element and select the Break on option:

  • Subtree modificationsThe choices areA breakpoint when children within a node change;

  • Attributes modificationsThe choices areBreakpoints when node properties change;

  • node removalThe choices areBreakpoint when node is removed;

2. The console debug

Reference article: Common Uses of Console Debugging

2.1 Commands for Displaying Information:

console.log("normal");         // Used to output general information
console.info("information");   // Is used to output suggestive information
console.error("error");        // Used to output error information
console.warn("warn");          // Displays warning information
console.clear();               // Clear the console information
Copy the code

2.2 Timing function:

The console. Time () and the console. TimeEnd () :

console.time("Console timer");
for(var i = 0; i < 10000; i++){
    for(var j = 0; j < 10000; j++){}       
}
console.timeEnd("Console timer")
Copy the code

2.3 Information Grouping:

The console. Group () and the console. GroupEnd () :

console.group("First set of information");
    console.log("Group one, Number one: My Blog.");
    console.log("Group 1, Section 2: CSDN");
console.groupEnd();

console.group("Second set of messages");
    console.log("Group 2 # 1: Program Lovers QQ Group");
    console.log("Group two, Number two: Welcome to the club.");
console.groupEnd();
Copy the code

2.4 Display objects in a tree structure:

Console.dir () displays all of an object’s properties and methods:

var info = {
    name : "Alan".age : "27".grilFriend : "nothing".getName : function(){
        return this.name; }}console.dir(info);
Copy the code

2.5 Displaying the Contents of a Node

Console.dirxml () is used to display the HTML/XML code contained in a node of the web page:

var node = document.getElementById("info");
node.innerHTML += "

Is the append element displayed

"
; console.dirxml(node); Copy the code

2.5 Count the number of times the code is executed:

Use the console. The count () :

function myFunction(){
    console.count("Number of times myFunction is executed");
}
myFunction();       // the number of times myFunction is executed: 1
myFunction();       // the number of times myFunction is executed: 2
myFunction();       // the number of times myFunction is executed: 3
Copy the code

2.6 Output table:

console.table(mytable);
Copy the code

3. Debug various page sizes

While it may seem cool to have all kinds of phones on the table, it’s unrealistic. However, everything you need is provided in the browser. Enter the inspection panel and click “Switch device mode” button. In this way, you can resize the window within the window.

4. The debugger breakpoints

Specifically, by adding “Debugger; “Statement, which automatically breaks when the code executes into the statement.

conclusion

For the new mixed application development partners, and often need to debug mixed application partners, I believe it will be helpful 😁

Come on, everybody!