MyFeed Performance Rework
After using MyFeed RSS app for about a year or so, I thought i'd take a look to see what kind of performance impact it has on my devices. To do this I measured the network and CPU to see if there were any clear problems and easy adjustments that could be made to improve.
I used Chrome Dev Tools to take network and CPU performance readings of the feed page. As this is the view that has the main functionality of the app I wanted to see the impact of this.
I found a nice alternative called idb by Jake Archibald. Weighing in at around 2kb, it provides a nice Promise based wrapper around the native IndexedDB APIs. I would like to interact directly with native IndexedDB APIs but they're so cumbersome I would probably end up making my own wrapper around them. Switching out localforage made a big difference to total JS size, but the next step was looking into CPU performance.
Dev tools has a nice feature in the performance tab where you can slowdown your CPU when taking performance measurements. I opted to turn this setting to 6x CPU slowdown to simulate low end devices. After taking a performance recording I could drill down through the call stack to understand which functions took the longest to run.
generateFeed() is the function used to create the final HTML to be injected into the page, drilling down you can see the
n.fromNow() function takes quite a long time to run. This comes from the DayJS library and is responsible for creating the relative time for each article e.g "1 hour ago", "5 days ago" etc. As the app only has to support modern browsers, this meant that I could use what's included in modern browsers such as the Intl library, which provides international time formatting, as well as other things.
I created a thin wrapper function
getRelativeTime() to generate the time format and the results were pretty amazing. It now takes only 1.3ms to generate the relative time, down from 59.4ms with DayJS, a huge win for CPU time. Plus it meant I could remove the additional network request for the DayJS library. Another win for application load time!
In summary looking at what the app uses and switching out libraries for others that will fit the use case has allowed for large reductions in network requests and CPU time.
Before: 62.8kb total JS (30.8kb over the wire)
After: 29.1kb total JS (19.9kb over the wire)
Before: 65.8ms to run
After: 5.7ms to run
I will continue to look at different parts of the app to see what can be swapped out / tweaked. The next step will be to look at the feed fetching performance, and see what increases can be made there, such as concurrent fetching via
Promise.all(), as well as performance tweaks and timeouts added to the CORS proxy.