Module version(s) affected
6.1
Description
DBFile::getIsImage() is called in a number of different places when outputting images, but it is surprisingly slow and hampers performance on image-heavy pages. Given that real world servers often have restricted IOPS, I think this is worth looking at.
I’ve been benchmarking this by removing the contents of the main Page.ss to minimise any other influences, and replacing it with this:
<% loop $List('SilverStripe\Assets\Image').Limit(50) %>
{$ScaleWidth('500')}<br />
<% end_loop %>
Loaded once to make sure all resamples have been completed.
Base benchmark:

After replacing the contents of DBFile::getIsImage() with return true (not a proposed solution!):

How to reproduce
<% loop $List('SilverStripe\Assets\Image').Limit(50) %>
{$ScaleWidth('500')}<br />
<% end_loop %>
Benchmark with XHProf
Possible Solution
I’m not sure yet... I don’t think we should rely on just the file extension, as users may not have the silverstripe/mimevalidator module installed, and assets could come from other sources anyway.
Heading further down the rabbit hole, Flysystem checks whether the file exists before eventually calling this method: https://github.com/thephpleague/mime-type-detection/blob/06fd1559cc50ad3300f5ce5c16ad9a53d52ba989/src/FinfoMimeTypeDetector.php#L74-L77. Apparently that internally then looks at chunks of the file data to figure it out, which might explain the slowdown
We could store the mime type in the database, but that would need to be in a major version I think.
We could cache the result of the mime type check, but my concerns would be: (A) how big might that cache end up being? and (B) presumably we’d need to flush it whenever the file hash changed (or at the very least include the file hash in the key)?
Perhaps this isn’t solvable without significant effort, just wanted to raise it.
Additional Context
No response
Validations
PRs
Module version(s) affected
6.1
Description
DBFile::getIsImage()is called in a number of different places when outputting images, but it is surprisingly slow and hampers performance on image-heavy pages. Given that real world servers often have restricted IOPS, I think this is worth looking at.I’ve been benchmarking this by removing the contents of the main
Page.ssto minimise any other influences, and replacing it with this:Loaded once to make sure all resamples have been completed.
Base benchmark:

After replacing the contents of

DBFile::getIsImage()withreturn true(not a proposed solution!):How to reproduce
Benchmark with XHProf
Possible Solution
I’m not sure yet... I don’t think we should rely on just the file extension, as users may not have the
silverstripe/mimevalidatormodule installed, and assets could come from other sources anyway.Heading further down the rabbit hole, Flysystem checks whether the file exists before eventually calling this method: https://github.com/thephpleague/mime-type-detection/blob/06fd1559cc50ad3300f5ce5c16ad9a53d52ba989/src/FinfoMimeTypeDetector.php#L74-L77. Apparently that internally then looks at chunks of the file data to figure it out, which might explain the slowdown
We could store the mime type in the database, but that would need to be in a major version I think.
We could cache the result of the mime type check, but my concerns would be: (A) how big might that cache end up being? and (B) presumably we’d need to flush it whenever the file hash changed (or at the very least include the file hash in the key)?
Perhaps this isn’t solvable without significant effort, just wanted to raise it.
Additional Context
No response
Validations
silverstripe/installer(with any code examples you've provided)PRs