For the past few days I have been working on something that is a bit of a step outside of my usual Ruby/Rails work on the Services team. Uken is always working on new and exciting projects and one of these is a new game that will be targeting the iOS platform initially. The game itself is developed entirely using web technologies: HTML5, CSS3, AngularJS, web sockets etc. In order to be listed on the iOS app store, app developers must wrap their web applications in a native UIWebView wrapper.
Much of the initial work is not done within this UIWebView context but rather just in a simple web browser. This makes for a much faster development process. For the most part this works really well. Much of the time the way that the game works in the browser is identical to how it works once loaded on the device. However, in this case there is outstanding issue. The typical laptops that we use here might have 8 or 16 GB of RAM which means that the game always runs smoothly. On mobile devices the games can be constrained to 512 MB / 1GB for the entire device.
In profiling the new application, it was found that there was a large memory spike on one particular section of the app. Since I have some experience with iOS development, I was assigned to take a look and see if I could figure out what was causing this large memory spike. To give you an idea of the extent of the problem, memory in our application seemed to spike up to around 250 MB. This level of consumption is fairly unreasonable for many of the older generation devices and the effect becomes very noticeable upon trying to scroll through the content in the app.
To figure out where this memory spike was coming from, I broke out my old friend Instruments, which I used a lot on my first co-op term to track down memory leaks. I could immediately see that the UIWebView itself was consuming the memory. My team lead suggested that I strip down the content in the application itself, piece by piece, in order to see what if anything was affecting the memory usage.
After a lot of trail and error and continued profiling, I found out that the CSS attribute “overflow-x: hidden;” was causing this abnormal memory usage. We are using this on a lot of different DOM elements on the one screen. Removing this element led to a drop in memory consumption to around a stable 65-75MB. I’m still not entirely sure why this was causing the strange behaviour (More resources required for rendering?) but I am glad that I was able to track it down!