Open andrewgreenh opened 5 years ago
I'm glad you started this discussion :)
In my talk at Chrome Dev Summit, we briefly discussed that CPU reporting is not well exposed in the Web Platform at present, in large-part due to concerns about exposing another fingerprinting vector. There's a great doc about this here. An alternative is to extrapolate the device model ID from the UA string, map the device back to pre-computed CPU benchmark data from Geekbench and use that to define low-end/high-end classifications. Loosely:
We implemented a demo of this idea over in https://github.com/GoogleChromeLabs/adaptive-loading/tree/master/cra-device-class-aware-code-splitting where you can see us using the Device Atlas API for model detection and static Geekbench data for the mapping.
For the local benchmarking idea, I think it would be interesting to think through the caveats a little. e.g I imagine you are limited to changing the loading strategy after initial page load (as the benchmark needs JS to execute), how much time does the benchmark itself take to execute (would it have to run after the page is idle to not content with other main-thread activity) etc.
I really like the idea of benchmarking in a requestIdleCallback. The goal of such a feature would be to check if a device can handle a non-critical feature performance wise. That means, we could maybe live with delaying this feature until the device has time to run the mini-benchmark. We could also rerun the benchmark every x minutes in order to update the score depending on the other work the device has to perform at a given moment.
An alternative is to extrapolate the device model ID from the UA string, map the device back to pre-computed CPU benchmark data from Geekbench and use that to define low-end/high-end classifications.
I've done something similar for detecting GPU's in the past: https://github.com/TimvanScherpenzeel/detect-gpu (mapping reported GPU to a scraped benchmarking list). I've mostly used it for highly interactive WebGL websites where based on the GPU tier it picks a default quality setting (which is still overridable by the user).
The basic idea behind the useHardwareConcurrency hook is great, but I fear that it is not sufficient to identify slow devices. Even the moto G of the first generation (with a Snapdragon 400 CPU) has 4 cores. On the other hand, older iPhones only have 2 cores while the single cores are much faster and are able to run expensive animations more easily compared to low end android devices with more cores.
Could we maybe implement a "mini benchmark" to identify the JS execution speed of the device? Maybe something along the lines of this:
This would however block the mainthread for 8ms (duration could be changed obviously).
Get your score here: https://ogb5i.csb.app/
My Laptop (i7 8565U) manages something around 30.000 while my s10 (Exynos variant) only gets 3.000 - 10.000, the s7 of a friend manages ~1000 and the iPhone 6s of a friend gets 8.000
One would need to source the scores for different devices and implement categories.
Another added benefit would be, that the JS execution speed of the browser is factored in. That would mean, that IE gets fewer heavy animations because it is slower.