Andrew Grieve was speaking at Full Frontal about mobile performance, these are my notes from his talk.
The first Gmail for iPhone was a web page. Docs started as a mobile page but is now an app but that runs a web view in the background.
A blank web page loads really fast. If your page doesn't load fast then you've done something to make it slow.
Clicks on mobile. There is an intentional delay in a click event. Use large targets, use
:active for highlights. Use viewport meta. Use fast click library.
JS Parsing: iPhone 1 => 3 seconds to parse 300Kb of JS. iPhone 5S is 110ms, with lazy parsing it's down to 40ms. The best thing you can do for mobile performance is to buy a new phone.
Creating DOM: In 2010
innerHTML() was fastest. Now
cloneNode() are now about parity with a few variations between browsers. For 5000 DOM nodes (bigger than Gmail!) it's still fast.
Registering events: In 2010 inline handlers were fastest, weren't parsed until triggered. Now having events at all has a ~7% overhead with inline events being slower and taking much more memory in some cases. Don't use inline event handlers and minimise the number of handlers. Use event delegation - one handler at a higher level and filter out the actual target.
Application cache: Much better than it used to be but it's still a bit of a douchebag.
- Always-on app cache (used even online) has big performance benefits. Any page that includes an manifest gets included in the cache - don't embed user-specific data or make URLs unique per user.
- Offiline-only app cache. This uses a fallback section and loads the page with the manifest into an
<iframe>. This then uses the offline page as a fallback to load into the iframe.
Offline storage: Store data in JS Heap, LocalStorage, WebSQL/IndexDB, server and browser cache. Use the right one for the job - pre-fectch from your server to the client.
Network matters: Slow start to page load on flaky network.
- Render above the fold in the first 14kb. Also start your application logic in that first 14kb. Sending an XHR for the data at the very start of the page and handling the result later can save a lot of time.
- Send your data with the correct content type, saves data.
- JSON.parse is 3 - 4 times faster than eval. String.split is faster than JSON.parse, Arrays are faster than objects. At best you'll gain 10ms so it's not a bottleneck.
- Network requests are a bottleneck so batch up requests. Start parsing the request as it comes in, don't wait for it to complete. Uploads are really slow - don't batch large uploads.
- Have a timeout for your request. Fail faster. Use progress events for upload and downloads. Reset your timeout every time you get an event and have different timeouts for different stages of the process.