3 Steps to Make Web Page Load 3x Faster in Mobile App

ohdarling
5 min readApr 27, 2022

--

Speed up vector created by starline — freepik

There are a lot of cross-platform technologies that develop features for both iOS and Android, such as Flutter, React Native, but they all require a huge size of framework to embed in the mobile app. So I think HTML pages are the quickest and lightest way to do that, both platforms have a standard web view component to display web pages.

In general, HTML pages will load more slower than Flutter or React Native pages, is there any way to improve it?

Yes, let’s try it and speed up the web page loading time in mobile app.

Note: Demo codes are written in Swift and performance data is tested on iOS Simulator.

Baseline

We will use reactjs.org as a demo to compare the loading speed before and after optimization.

First of all, let’s track the loading time of the remote web site in mobile app.

It is a simple web view controller for displaying a web page:

We will track two metrics for measure performance of loading a web page:

  • Duration between click and viewDidAppear
  • Time cost of domContentLoaded event

Then we will get the baseline performance data:

viewDidAppear 1620.163917541504 ms
Optional({
dcl = "1107.999755859375";
dcl2click = "2534.98095703125";
fcp = 1087;
})

It takes almost 3 seconds to load a web page and display to user, which is a bad experience for the user.

First Step: Use Offline Package

The first step, we can learn from React Native, package all content of our web pages and embedded into the mobile app. When users visit the speified web site, we can load the content from local disk directly, which can reduce a lot of network transmission time.

Getting the web view to load content from the local disk is easy, we can use WKURLSchemeHandler and change web site URL to local-package://reactjs.org.

First, write a scheme handler:

Then change web site URL to local-package://reactjs.org:

Build and run! Now we get the new performance data:

viewDidAppear 1527.724266052246 ms
Optional({
dcl = 108;
dcl2click = "1410.2900390625";
fcp = "87.00000000000001";
})

Wow, the domContentLoaded event reduced 90% of time, only took 108ms to reach it, and duration between domContentLoaded and user click event reduced 44%, which is a huge improvement.

But why does viewDidAppear take so much time?

Secend Step: Use WebView Pool

The WKWebView is a heavy component in iOS, and takes a lot of time to get ready for use, which can block the progress of user interface navigate.

Then, we can separate the web view creation and prepare the web view already ready to use in future, which will reduce a lot time and make users feel better.

Whenever the user needs to visit a local package, we will get a web view controller from the already prepared instance, and display the controller directly.

Let’s check the new performance data:

viewDidAppear 930.3610324859619 ms
Optional({
dcl = "109.999755859375";
dcl2click = "558.899169921875";
fcp = 91;
})

Yes, the duration between domContentLoaded and user click event is reduced to 558ms, almost a 60% reduction.

Now we will see the domContentLoaded is triggered before viewDidAppear, which means that the user can see the entire web page content at the end of the page navigation animation.

Thrid Step: Pre-load Common Runtimes

Is there any way to further improve the loading speed?

Let’s check the loaded contents of a web page:

We can assume that the following content are required by every local package:

  • webpack-runtime-630d8949f3fa725c595a.js
  • framework-ff9c508ebfda0f33cb0b.js
  • commons-5ebc24be6c266c74a8e2.js

Why not load them in the prepared web view instance?

Then we can load all the other content with document.write:

Let’s check the final performance data we get:

viewDidAppear 720.9508419036865 ms
Optional({
dcl = 49;
dcl2click = "-502.916259765625";
fcp = 645;
})

The time cost of viewDidAppear has been reduced to 720ms, about a 22% reduction.

The time of domContentLoaded event is incorrect here because the web view is already loaded, but when running in the simulator we can feel that the animation is smoother than before.

Final Comparison

Finally let’s look at the screen recordings, and compare the loading speed after these three steps and before:

Conclusion

As we can see, an HTML page can load as fast as a page in native app, so I think it is worth taking time to improve the loading speed of web pages.

These three steps are easy to use in a production environment, but the above demonstration is not the complete code, and there are many details to consider.

Thanks for reading, follow me to get more iOS development tips.

--

--