1# Troubleshooting White Screen Issues on Web Pages 2 3There are many reasons for white screen issues on web pages. This topic describes how to troubleshoot common white screen issues. 4 51. Check the permissions and network status. 62. Locate the error type (cross-origin issues, 404 errors, or JS exceptions) by referring to [Debugging Frontend Pages by Using DevTools](web-debugging-with-devtools.md). 73. In complex layout scenarios, check the rendering mode and component constraints. 84. Handle the compatibility problem of the HTML5 code. 95. Check the keywords related to the lifecycle and network loading in the log. 10 11## Checking Permissions and Network Status 12If the network or file access permission is not added for the application, or the network status of the device is poor, the **Web** component will fail to be loaded or page elements will be missing, resulting in a white screen. 13* Check the network status of the device, including whether the device is connected to the network and whether the built-in browser of the device can access web pages. 14* Ensure that the network permission **ohos.permission.INTERNET** is added to the application (mandatory for accessing online pages). 15 ``` 16 // Add the required permission in module.json5. 17 "requestPermissions":[ 18 { 19 "name" : "ohos.permission.INTERNET" 20 } 21 ] 22 ``` 23* The following table lists attributes used to enable related permissions. 24 | Attribute | Description | 25 | ---- | -------------------------------- | 26 | [domStorageAccess](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#domstorageaccess) | Sets whether to enable the local storage. If this permission is not enabled, local storage cannot be used to store data, any code that calls local storage will become invalid, and functionalities that depend on local storage will be abnormal.| 27 | [fileAccess](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#fileaccess) | Sets whether to enable the file read/write functionality. If the file read/write functionality is not enabled, the file-dependent modules will crash.| 28 | [imageAccess](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#imageaccess) | Sets whether to enable automatic image loading.| 29 | [onlineImageAccess](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#onlineimageaccess) | Sets whether to enable online image loading (through HTTP and HTTPS).| 30 | [javaScriptAccess](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#javascriptaccess) | Sets whether to enable JavaScript script execution.| 31 32 33 ```ts 34 // xxx.ets 35 import { webview } from '@kit.ArkWeb'; 36 37 @Entry 38 @Component 39 struct WebComponent { 40 controller: webview.WebviewController = new webview.WebviewController(); 41 42 build() { 43 Column() { 44 Web({ src: 'www.example.com', controller: this.controller }) 45 .domStorageAccess(true) 46 .fileAccess(true) 47 .imageAccess(true) 48 .onlineImageAccess(true) 49 .javaScriptAccess(true) 50 } 51 } 52 } 53 ``` 54* Modify the [UserAgent](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#setcustomuseragent10) and check whether the page is restored. 55 56 ```ts 57 // xxx.ets 58 import { webview } from '@kit.ArkWeb'; 59 import { BusinessError } from '@kit.BasicServicesKit'; 60 61 @Entry 62 @Component 63 struct WebComponent { 64 controller: webview.WebviewController = new webview.WebviewController(); 65 @State customUserAgent: string = ' DemoApp'; 66 67 build() { 68 Column() { 69 Web({ src: 'www.example.com', controller: this.controller }) 70 .onControllerAttached(() => { 71 console.log("onControllerAttached"); 72 try { 73 let userAgent = this.controller.getUserAgent() + this. customUserAgent; 74 this.controller.setCustomUserAgent(userAgent); 75 } catch (error) { 76 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 77 } 78 }) 79 } 80 } 81 } 82 ``` 83## Debugging Pages by Using DevTools 84If a white screen issue persists after the network and permission configurations are correctly configured, use DevTools to debug the frontend page and listen for the web-related error reporting APIs to locate the error type. 85 861. Check the error information on the console to locate the resource loading failure. If resource loading fails, page elements may be missing, the layout may be disordered, and images and animations may become invalid. In severe cases, the rendering process may break down and the white screen issue may occur. As shown in the following figure, check the following items in sequence:<br> 87 (1) Whether the elements are complete and whether the HTML elements and structure are correct.<br> (2) Whether there are errors reported on the console.<br>(3) Whether the resource loading time is long.<br> 88  89 902. Check the console to see if there are any exceptions caused by the Mixed Content policy or CORS policy, or JS errors. For details, see [Resolving Cross-Origin Resource Access](web-cross-origin.md). For security purposes, the ArkWeb kernel does not allow the file and resource protocols to access cross-origin requests. As such, the **Web** component blocks such accesses when loading local offline resources. When **Web** components cannot access local cross-origin resources, the DevTools console displays the following error message: 91 ``` 92 Access to script at 'xxx' from origin 'xxx' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, arkweb, data, chrome-extension, chrome, https, chrome-untrusted. 93 ``` 94 You can use either of the following methods to solve the problem: 95 96 Method 1 97 98 Use HTTP or HTTPS instead of the file or resource protocol to ensure that **Web** components can successfully access cross-origin resources. Customize URL domain names for individuals or organizations to prevent conflicts with actual domain names on the Internet. In addition, use the [onInterceptRequest](../reference/apis-arkweb/arkts-basic-components-web-events.md#oninterceptrequest9) method of the **Web** component to intercept and replace local resources. 99 100 The following uses an example to describe how to use HTTP or HTTPS to access local cross-origin resources. The **index.html** and **js/script.js** files are stored in the **rawfile** directory of the project. When the resource protocol is used to access the **index.html** file, the **js/script.js** file is intercepted due to cross-origin access and cannot be loaded. In the example, the domain name **https:\//www\.example.com/** is used to replace the original resource protocol, and the **onInterceptRequest** API is used to replace the resource to ensure that the **js/script.js** file can be successfully loaded. In this way, the cross-origin interception problem is solved. 101 ```ts 102 // main/ets/pages/Index.ets 103 import { webview } from '@kit.ArkWeb'; 104 105 @Entry 106 @Component 107 struct Index { 108 @State message: string = 'Hello World'; 109 webviewController: webview.WebviewController = new webview.WebviewController(); 110 // Construct a mapping table between domain names and local files. 111 schemeMap = new Map([ 112 ["https://www.example.com/index.html", "index.html"], 113 ["https://www.example.com/js/script.js", "js/script.js"], 114 ]) 115 // Construct the local file and the return value format mimeType. 116 mimeTypeMap = new Map([ 117 ["index.html", 'text/html'], 118 ["js/script.js", "text/javascript"] 119 ]) 120 121 build() { 122 Row() { 123 Column() { 124 // For the local index.html file, use HTTP or HTTPS in place of file or resource as the protocol and construct a custom domain name. 125 // In this example, www.example.com is constructed. 126 Web({ src: "https://www.example.com/index.html", controller: this.webviewController }) 127 .javaScriptAccess(true) 128 .fileAccess(true) 129 .domStorageAccess(true) 130 .geolocationAccess(true) 131 .width("100%") 132 .height("100%") 133 .onInterceptRequest((event) => { 134 if (!event) { 135 return; 136 } 137 // Search for the local offline resource to be loaded, and then intercept and replace the resource. 138 if (this.schemeMap.has(event.request.getRequestUrl())) { 139 let rawfileName: string = this.schemeMap.get(event.request.getRequestUrl())!; 140 let mimeType = this.mimeTypeMap.get(rawfileName); 141 if (typeof mimeType === 'string') { 142 let response = new WebResourceResponse(); 143 // Construct the response data. If the local file is in rawfile, you can set the response data as follows: 144 response.setResponseData($rawfile(rawfileName)); 145 response.setResponseEncoding('utf-8'); 146 response.setResponseMimeType(mimeType); 147 response.setResponseCode(200); 148 response.setReasonMessage('OK'); 149 response.setResponseIsReady(true); 150 return response; 151 } 152 } 153 return null; 154 }) 155 } 156 .width('100%') 157 } 158 .height('100%') 159 } 160 } 161 ``` 162 163 ```html 164 <!-- main/resources/rawfile/index.html --> 165 <html> 166 <head> 167 <meta name="viewport" content="width=device-width,initial-scale=1"> 168 </head> 169 <body> 170 <script crossorigin src="./js/script.js"></script> 171 </body> 172 </html> 173 ``` 174 175 ```js 176 // main/resources/rawfile/js/script.js 177 const body = document.body; 178 const element = document.createElement('div'); 179 element.textContent = 'success'; 180 body.appendChild(element); 181 ``` 182 183 Method 2 184 185 Use [setPathAllowingUniversalAccess](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#setpathallowinguniversalaccess12) to set a path list for allowing cross-origin access to the local files using the file protocol. Note that only the resources in the path list can be accessed by the file protocol when this method is used. In this case, the behavior of [fileAccess](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#fileaccess) is overwritten. The paths in the list should be any of the following directories: 186 187 1. The application file directory and its subdirectories, which can be obtained through [Context.filesDir](../reference/apis-ability-kit/js-apis-inner-application-context.md#context), such as: 188 189 * /data/storage/el2/base/files/example 190 * /data/storage/el2/base/haps/entry/files/example 191 192 2. The application resource directory and its subdirectories, which can be obtained through [Context.resourceDir](../reference/apis-ability-kit/js-apis-inner-application-context.md#context), such as: 193 194 * /data/storage/el1/bundle/entry/resource/resfile 195 * /data/storage/el1/bundle/entry/resource/resfile/example 196 197 If a path is not any of the preceding paths, an error code 401 is reported and the path list fails to be set. If the path list is empty, the access scope of the file protocol complies with the [fileAccess](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#fileaccess) rule. The following is an example: 198 199 ```ts 200 // main/ets/pages/Index.ets 201 import { webview } from '@kit.ArkWeb'; 202 import { BusinessError } from '@kit.BasicServicesKit'; 203 204 @Entry 205 @Component 206 struct WebComponent { 207 controller: WebviewController = new webview.WebviewController(); 208 uiContext: UIContext = this.getUIContext(); 209 210 build() { 211 Row() { 212 Web({ src: "", controller: this.controller }) 213 .onControllerAttached(() => { 214 try { 215 // Set the list of paths that allow cross-origin access. 216 this.controller.setPathAllowingUniversalAccess([ 217 this.uiContext.getHostContext()!.resourceDir, 218 this.uiContext.getHostContext()!.filesDir + "/example" 219 ]) 220 this.controller.loadUrl("file://" + this.uiContext.getHostContext()!.resourceDir + "/index.html") 221 } catch (error) { 222 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 223 } 224 }) 225 .javaScriptAccess(true) 226 .fileAccess(true) 227 .domStorageAccess(true) 228 } 229 } 230 } 231 ``` 232 233 ```html 234 <!-- main/resources/resfile/index.html --> 235 <!DOCTYPE html> 236 <html lang="en"> 237 238 <head> 239 <meta charset="utf-8"> 240 <title>Demo</title> 241 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, viewport-fit=cover"> 242 <script> 243 function getFile() { 244 var file = "file:///data/storage/el1/bundle/entry/resources/resfile/js/script.js"; 245 // Use the file protocol to access the local JS file through XMLHttpRequest. 246 var xmlHttpReq = new XMLHttpRequest(); 247 xmlHttpReq.onreadystatechange = function(){ 248 console.log("readyState:" + xmlHttpReq.readyState); 249 console.log("status:" + xmlHttpReq.status); 250 if(xmlHttpReq.readyState == 4){ 251 if (xmlHttpReq.status == 200) { 252 // If the path list is set on eTS, resources can be obtained. 253 const element = document.getElementById('text'); 254 element.textContent = "load " + file + " success"; 255 } else { 256 // If the path list is not set on eTS, a CORS error is triggered. 257 const element = document.getElementById('text'); 258 element.textContent = "load " + file + " failed"; 259 } 260 } 261 } 262 xmlHttpReq.open("GET", file); 263 xmlHttpReq.send(null); 264 } 265 </script> 266 </head> 267 268 <body> 269 <div class="page"> 270 <button id="example" onclick="getFile()">loadFile</button> 271 </div> 272 <div id="text"></div> 273 </body> 274 275 </html> 276 ``` 277 278 ```javascript 279 // main/resources/resfile/js/script.js 280 const body = document.body; 281 const element = document.createElement('div'); 282 element.textContent = 'success'; 283 body.appendChild(element); 284 ``` 285 2863. Check whether error reporting APIs, such as **onErrorReceive**, **onHttpErrorReceive**, **onSslErrorEvent**, **onHttpAuthRequest**, and **onClientAuthenticationRequest**, are called. Rectify the fault based on the returned error code and [List of ArkWeb Network Protocol Stack Errors](../reference/apis-arkweb/arkts-apis-netErrorList.md). 287 288 | Event | Description | 289 | ---- | -------------------------------- | 290 | [onErrorReceive](../reference/apis-arkweb/arkts-basic-components-web-events.md#onerrorreceive) | Called when resources fail to be loaded. For example, 302 (**UNKNOWN_URL_SCHEME**) is reported when a scheme that is not supported by the kernel is accessed.| 291 | [onHttpErrorReceive](../reference/apis-arkweb/arkts-basic-components-web-events.md#onhttperrorreceive) | Called when the server returns an HTTP error code, which requires joint commissioning with the server.| 292 | [onHttpAuthRequest](../reference/apis-arkweb/arkts-basic-components-web-events.md#onhttpauthrequest9) | Called when the server returns 407, indicating that the device needs to provide the user name and password for authentication. If the processing is incorrect, the loading may be abnormal and a white screen may occur.| 293 | [onClientAuthenticationRequest](../reference/apis-arkweb/arkts-basic-components-web-events.md#onclientauthenticationrequest9) | Called when the server requests a certificate from the device. If the request is not processed correctly, the page loading will be abnormal.| 294 | [onSslErrorEvent](../reference/apis-arkweb/arkts-basic-components-web-events.md#onsslerrorevent12) | Called when the certificate is incorrect. The application needs to locate the fault based on the certificate error information.| 295 296 297## Resolving White Screen Issues Caused by Complex Layout and Rendering Modes 298If a page uses a complex layout or rendering mode, pay attention to its application scenarios and constraints. Improper use of the layout or rendering mode may cause layout disorder or white screen. 299The **Web** component provides two rendering modes, which can be adapted to different container sizes as required. For details, see [Rendering Modes of the Web Component](web-render-mode.md). Pay attention to the following points: 300- In asynchronous rendering mode (renderMode: [RenderMode](../reference/apis-arkweb/arkts-basic-components-web-e.md#rendermode12).ASYNC_RENDER), the width and height of a **Web** component cannot exceed 7,680 px (physical pixels). Otherwise, a white screen is displayed. 301- In synchronous rendering mode (renderMode: [RenderMode](../reference/apis-arkweb/arkts-basic-components-web-e.md#rendermode12).SYNC_RENDER), the width and height of a **Web** component cannot exceed 500,000 px (physical pixels). Otherwise, a white screen is displayed. 302 303The **Web** component provides the capability of adapting to the page layout. For details, see [Fitting In the Page Content Layout](web-fit-content.md). Pay attention to the following restrictions when using the capability: 304- Set the synchronous rendering mode through **webSetting({renderingMode: WebRenderingMode.SYNCHRONOUS})**. 305- Disable the scrolling effect through **webSetting({overScrollMode: OverScrollMode.NEVER})**. 306- Do not dynamically adjust the component height in this mode to ensure that the page height is fixed. 307- Do not enable the **RESIZE_CONTENT** attribute in **FIT_CONTENT** mode to avoid layout invalidation. 308- If the CSS **height: <number& > vh** is conflict with the **Web** component size adaptation page layout, check whether **height: vh** is the first CSS height style from the body node. As shown in the following example. The height of the DOM node whose ID is 2 is 0, causing a white screen. 309 310 ``` 311 <body> 312 <div id = "1"> 313 <div id = "2" style = "height: 100vh">Child DOM</div> 314 <div id = "3" style = "height: 20px">Child DOM</div> 315 </div> 316 </body> 317 ``` 318 The reference solution to the white screen problem is as follows: 319 - Use a specific height style for the child DOM to extend the parent element. 320 ``` 321 <body> 322 <div id = "1"> 323 <div id = "2"><div style = "height: 20px"><div/></div> 324 <div id = "3" style = "height: 20px">Child DOM</div> 325 </div> 326 </body> 327 ``` 328 - Use the actual height style for the parent element. 329 ``` 330 <body> 331 <div id = "1"> 332 <div id = "2" style = "height: 20px">Child DOM</div> 333 <div id = "3" style = "height: 20px">Child DOM</div> 334 </div> 335 </body> 336 ``` 337 338## Handling the Compatibility of HTML5 Code 339To avoid white screen issues, you can handle the compatibility issue as follows: 340* Intercept special protocols. 341* If a white screen is displayed due to the **tel:** or **mailto:** protocol invoked by the HTML5 page, intercept the protocol and invoke the system dialing capability through **onInterceptRequest**. 342 ```c 343 .onInterceptRequest((event) => { 344 if (event.request.url.startWith('tel:')) { 345 // Invoke the system dialing capability. 346 call.makeCall({ phoneNumber: '123456' }); 347 return { responseCode: 404 }; // Prevent the default behavior. 348 } 349 return null; 350 }) 351 ``` 352## Monitoring Memory and Lifecycle 353If the memory usage reaches the threshold, the rendering process will be terminated, causing a white screen. Similarly, a white screen will occur if the rendering process fails to start or is abnormally terminated. You can check the cause in logs. For example, check whether the **Web** component is correctly bound to the **WebController** or whether the white screen occurs because the **Web** component is released too early. Check the information related to the render process in the log, for example, whether a memory leak causes insufficient rendering memory. The keyword **MEMORY_PRESSURE_LEVEL_CRITICAL** indicates that the memory usage has reached the threshold. In this case, the web page may encounter exceptions such as black screen, artifacts, or flicker. You need to check whether a memory leak occurs and whether the render process is successfully started or exits abnormally. 354 355The following table lists log keywords and the corresponding descriptions. 356 357| Keyword | Description | 358| ---- | -------------------------------- | 359| StartRenderProcess failed | The rendering process fails to be started.| 360| MEMORY_PRESSURE_LEVEL_CRITICAL | The device memory pressure reaches the threshold. If the device continues to be used, a black screen, screen flickering, or white screen may occur.| 361| crashpad SandboxedHandler::HandlerCrash, received signo = xxx | The render process crashes, causing problems such as white screen and **Web** component suspension.| 362| SharedContextState context lost via Skia OOM | The shared memory is insufficient, which may cause the application to crash, produce artifacts, or become suspended. 363| CreateNativeViewGLSurfaceEGLOhos::normal surface | The EGL surface is successfully created. If this log is not displayed, a white screen occurs.| 364| INFO: request had no response within 5 seconds | Network timeout.| 365| final url: ***, error_code xxx(net::ERR_XXX) | An error is reported during the main resource loading.| 366 367The following figure shows the key points contained during the **Web** component loading process. The following table lists the log keywords during the **Web** component loading process. 368 369 370| Keyword | Description | 371| ---- | -------------------------------- | 372| NWebRenderMain start | The child process starts.| 373| RendererMain startup,<br> render thread init | The child process initialization starts.| 374| event_message: WillProcessNavigationResponse source_id xxx navigation_handle id: xxx| The response of the main resource is received.| 375| event_message: commit navigation in main frame, routing_id: 4, url: *** | The navigation is committed to the child process. 376| RenderFrameImpl::CommitNavigation,<br> event_message: page load start | The child process receives the commit message.| 377| NWebHandlerDelegate::OnNavigationEntryCommitted,<br> event_message: Commit source_id xxx | The main process receives **DidCommitNavigation**.| 378| event_message: load_timing_info errpr_code:0,...| The main resource loading is complete, and the time required for each phase is displayed.| 379| event_message: MarkFirstContentfulPaint| The tag identifies an element with displayable content.| 380| NWebHandlerDelegate::OnPageVisible| The first frame is displayed.| 381| NWebHandlerDelegate::OnFirstContentfulPaint| The first frame content is displayed.| 382| event_message: content load finished | The page content parsing is complete.| 383| event_message: page load finished,<br> NWebHandlerDelegate::OnLoadEnd,<br> NWebHandlerDelegate::MainFrame OnLoadEnd,<br> NWebHandlerDelegate::OnFirstMeaningfulPaint | The page and sub-resources are loaded.| 384