-
Notifications
You must be signed in to change notification settings - Fork 739
Description
First of all, thank you for this package, really amazing work you put in so far.
That said, using cloud filesystem (s3, spaces) requires some optimizations, because right now it makes multiple requests for every LfmItem
when trying to fill()
the attributes. I've been playing around and managed to get the /jsonitems
request with 20 folders and 1 image from over 1 min (it would timeout after 1 min) down to around 2 seconds. Here are my insights:
Avoid extra isDirectory()
and isFile()
requests
Right now isDirectory()
does this weird check:
public function isDirectory()
{
$working_dir = $this->path('working_dir');
$parent_dir = substr($working_dir, 0, strrpos($working_dir, '/'));
$parent_directories = array_map(function ($directory_path) {
return app(static::class)->translateToLfmPath($directory_path);
}, app(static::class)->dir($parent_dir)->directories());
return in_array($this->path('url'), $parent_directories);
}
Since it's already making 2 different calls to filesystem to fetch folders and files separately, it can be implemented like this:
LfmPath.php
public function folders()
{
$all_folders = array_map(function ($directory_path) {
return $this->pretty($directory_path, true);
}, $this->storage->directories());
$folders = array_filter($all_folders, function ($directory) {
return $directory->name !== $this->helper->getThumbFolderName();
});
return $this->sortByColumn($folders);
}
public function files()
{
$files = array_map(function ($file_path) {
return $this->pretty($file_path);
}, $this->storage->files());
return $this->sortByColumn($files);
}
public function pretty($item_path, bool $isDirectory = false)
{
return Container::getInstance()->makeWith(LfmItem::class, [
'lfm' => (clone $this)->setName($this->helper->getNameFromPath($item_path)),
'helper' => $this->helper,
'isDirectory' => $isDirectory
]);
}
Note: I only added
$isDirectory
variable topretty()
function and passingtrue
fromfolders()
function.
LfmItem.php
class LfmItem
{
private $lfm;
private $helper;
private $isDirectory;
private $columns = ['name', 'url', 'time', 'icon', 'is_file', 'is_image', 'thumb_url'];
public $attributes = [];
public function __construct(LfmPath $lfm, Lfm $helper, bool $isDirectory = false)
{
$this->lfm = $lfm->thumb(false);
$this->helper = $helper;
$this->isDirectory = $isDirectory;
}
...
public function isDirectory()
{
return $this->isDirectory;
}
public function isFile()
{
return ! $this->isDirectory();
}
Folders do not need an isImage()
check
This can be easily avoided adding an isFile()
check first:
LfmItem.php
public function isImage()
{
return $this->isFile() && starts_with($this->mimeType(), 'image');
}
Avoid extra mimeType()
requests
Mime time request gets called at least 3 times when trying to fill is_mage
, icon
and thumb_url
.
This can be optimized by including another private property $mimeType
and requesting mimeType like this:
public function mimeType()
{
if (is_null($this->mimeType))
$this->mimeType = $this->lfm->mimeType();
return $this->mimeType;
}
Note: I left out uploaded file comment since it was not implemented yet.
I've also removed time
property (lastModified()
) since I don't need it and it isn't visible in thumbnails mode.
These optimizations made this package somewhat usable with cloud disks. Further improvements are needed with files though, because they are still making a lot of requests for icons, thumbs and urls. IMO these can be optimized using lazy loading, by showing a generic file on load and then doing ajax requests and loading extra data separately. Also cache would be a nice boost in user experience, because right now when you navigate back to a folder you already were before, it has to load the same stuff again.