From 918f84f568c7cb4eb389a698642727cf22fcfa23 Mon Sep 17 00:00:00 2001 From: Bernd Bestel Date: Wed, 18 Sep 2019 13:59:37 +0200 Subject: [PATCH] Lazy load all images to increase page load times (references #275) --- controllers/FilesApiController.php | 4 ++-- controllers/RecipesController.php | 2 +- package.json | 3 ++- public/js/grocy.js | 9 +++++++++ public/viewjs/components/productcard.js | 2 +- public/viewjs/mealplan.js | 3 ++- services/FilesService.php | 17 ++++++++++++++--- views/components/productcard.blade.php | 2 +- views/layout/default.blade.php | 1 + views/productform.blade.php | 2 +- views/recipeform.blade.php | 2 +- views/recipes.blade.php | 10 +++++----- yarn.lock | 9 ++++++++- 13 files changed, 48 insertions(+), 18 deletions(-) diff --git a/controllers/FilesApiController.php b/controllers/FilesApiController.php index fb7f619b..29c4b98f 100644 --- a/controllers/FilesApiController.php +++ b/controllers/FilesApiController.php @@ -59,13 +59,13 @@ class FilesApiController extends BaseApiController if ($forceServeAs == FilesService::FILE_SERVE_TYPE_PICTURE) { - $bestFitHeight = 999999; + $bestFitHeight = null; if (isset($request->getQueryParams()['best_fit_height']) && !empty($request->getQueryParams()['best_fit_height']) && is_numeric($request->getQueryParams()['best_fit_height'])) { $bestFitHeight = $request->getQueryParams()['best_fit_height']; } - $bestFitWidth = 999999; + $bestFitWidth = null; if (isset($request->getQueryParams()['best_fit_width']) && !empty($request->getQueryParams()['best_fit_width']) && is_numeric($request->getQueryParams()['best_fit_width'])) { $bestFitWidth = $request->getQueryParams()['best_fit_width']; diff --git a/controllers/RecipesController.php b/controllers/RecipesController.php index be309aaf..61838c6d 100644 --- a/controllers/RecipesController.php +++ b/controllers/RecipesController.php @@ -63,7 +63,7 @@ class RecipesController extends BaseController 'selectedRecipe' => $selectedRecipe, 'selectedRecipePositionsResolved' => $selectedRecipePositionsResolved, 'products' => $this->Database->products(), - 'quantityunits' => $this->Database->quantity_units(), + 'quantityUnits' => $this->Database->quantity_units(), 'selectedRecipeSubRecipes' => $selectedRecipeSubRecipes, 'selectedRecipeSubRecipesPositions' => $selectedRecipeSubRecipesPositions, 'includedRecipeIdsAbsolute' => $includedRecipeIdsAbsolute, diff --git a/package.json b/package.json index 27cf9823..c8dd94ec 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "tempusdominus-bootstrap-4": "https://github.com/berrnd/tempusdominus-bootstrap-4.git#master", "timeago": "^1.6.7", "toastr": "^2.1.4", - "bootstrap-select": "^1.13.10" + "bootstrap-select": "^1.13.10", + "jquery-lazy": "^1.7.10" } } diff --git a/public/js/grocy.js b/public/js/grocy.js index 03fd0bc3..b2f13fff 100644 --- a/public/js/grocy.js +++ b/public/js/grocy.js @@ -526,3 +526,12 @@ $("textarea.wysiwyg-editor").summernote({ minHeight: "300px", lang: __t("summernote_locale") }); + +function LoadImagesLazy() +{ + $(".lazy").Lazy({ + enableThrottle: true, + throttle: 500 + }); +} +LoadImagesLazy(); diff --git a/public/viewjs/components/productcard.js b/public/viewjs/components/productcard.js index 78f2cf8e..111f2ca4 100644 --- a/public/viewjs/components/productcard.js +++ b/public/viewjs/components/productcard.js @@ -82,7 +82,7 @@ Grocy.Components.ProductCard.Refresh = function(productId) { $("#productcard-no-product-picture").addClass("d-none"); $("#productcard-product-picture").removeClass("d-none"); - $("#productcard-product-picture").attr("src", U('/api/files/productpictures/' + btoa(productDetails.product.picture_file_name) + '?force_serve_as=picture&best_fit_height=400&best_fit_width=400')); + $("#productcard-product-picture").attr("src", U('/api/files/productpictures/' + btoa(productDetails.product.picture_file_name) + '?force_serve_as=picture&best_fit_width=400')); } else { diff --git a/public/viewjs/mealplan.js b/public/viewjs/mealplan.js index 463ddbbf..bb78a02c 100644 --- a/public/viewjs/mealplan.js +++ b/public/viewjs/mealplan.js @@ -103,12 +103,13 @@ var calendar = $("#calendar").fullCalendar({ if (recipe.picture_file_name && !recipe.picture_file_name.isEmpty()) { - element.html(element.html() + '') + element.html(element.html() + '') } }, "eventAfterAllRender": function(view) { RefreshLocaleNumberDisplay(); + LoadImagesLazy(); if (GetUriParam("week") !== undefined) { diff --git a/services/FilesService.php b/services/FilesService.php index c1824b2f..47ed79a4 100644 --- a/services/FilesService.php +++ b/services/FilesService.php @@ -33,13 +33,13 @@ class FilesService extends BaseService return $groupFolderPath . '/' . $fileName; } - public function DownscaleImage($group, $fileName, $bestFitHeight, $bestFitWidth) + public function DownscaleImage($group, $fileName, $bestFitHeight = null, $bestFitWidth = null) { $filePath = $this->GetFilePath($group, $fileName); $fileNameWithoutExtension = pathinfo($filePath, PATHINFO_FILENAME); $fileExtension = pathinfo($filePath, PATHINFO_EXTENSION); - $fileNameDownscaled = $fileNameWithoutExtension . '__downscaledto' . $bestFitHeight . 'x' . $bestFitWidth . '.' . $fileExtension; + $fileNameDownscaled = $fileNameWithoutExtension . '__downscaledto' . ($bestFitHeight ? $bestFitHeight : 'auto') . 'x' . ($bestFitWidth ? $bestFitWidth : 'auto') . '.' . $fileExtension; $filePathDownscaled = $this->GetFilePath($group, $fileNameDownscaled); try @@ -47,7 +47,18 @@ class FilesService extends BaseService if (!file_exists($filePathDownscaled)) { $image = new ImageResize($filePath); - $image->resizeToBestFit($bestFitHeight, $bestFitWidth); + if ($bestFitHeight !== null && $bestFitHeight !== null) + { + $image->resizeToBestFit($bestFitWidth, $bestFitHeight); + } + else if ($bestFitHeight !== null) + { + $image->resizeToHeight($bestFitHeight); + } + else if ($bestFitWidth !== null) + { + $image->resizeToWidth($bestFitWidth); + } $image->save($filePathDownscaled); } } diff --git a/views/components/productcard.blade.php b/views/components/productcard.blade.php index edd0058d..fe98809e 100644 --- a/views/components/productcard.blade.php +++ b/views/components/productcard.blade.php @@ -28,7 +28,7 @@ {{ $__t('Spoil rate') }}:
{{ $__t('Product picture') }}
-

+

{{ $__t('No picture available') }}
{{ $__t('Price history') }}
diff --git a/views/layout/default.blade.php b/views/layout/default.blade.php index 73d91932..071ce8da 100644 --- a/views/layout/default.blade.php +++ b/views/layout/default.blade.php @@ -390,6 +390,7 @@ @if(!empty($__t('summernote_locale') && $__t('summernote_locale') != 'x'))@endif @if(!empty($__t('bootstrap-select_locale') && $__t('bootstrap-select_locale') != 'x'))@endif + diff --git a/views/productform.blade.php b/views/productform.blade.php index 71201c24..18fba278 100644 --- a/views/productform.blade.php +++ b/views/productform.blade.php @@ -275,7 +275,7 @@ @if(!empty($product->picture_file_name)) -

+

{{ $__t('The current picture will be deleted when you save the product') }}

@else

{{ $__t('No picture available') }}

diff --git a/views/recipeform.blade.php b/views/recipeform.blade.php index c12da217..bd1aabca 100644 --- a/views/recipeform.blade.php +++ b/views/recipeform.blade.php @@ -209,7 +209,7 @@ @if(!empty($recipe->picture_file_name)) -

+

{{ $__t('The current picture will be deleted when you save the recipe') }}

@else

{{ $__t('No picture available') }}

diff --git a/views/recipes.blade.php b/views/recipes.blade.php index a39dd86b..af59fbdc 100644 --- a/views/recipes.blade.php +++ b/views/recipes.blade.php @@ -102,7 +102,7 @@
@if(!empty($recipe->picture_file_name)) - + @endif
{{ $recipe->name }}
@@ -173,7 +173,7 @@
@if(!empty($selectedRecipeSubRecipe->picture_file_name)) -

+

@endif @php $selectedRecipeSubRecipePositionsFiltered = FindAllObjectsInArrayByPropertyValue($selectedRecipeSubRecipesPositions, 'child_recipe_id', $selectedRecipeSubRecipe->id); @endphp @@ -203,7 +203,7 @@ @else @if($selectedRecipePosition->recipe_amount == round($selectedRecipePosition->recipe_amount, 2)){{ round($selectedRecipePosition->recipe_amount, 2) }}@else{{ $selectedRecipePosition->recipe_amount }}@endif @endif - {{ $__n($selectedRecipePosition->recipe_amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }} + {{ $__n($selectedRecipePosition->recipe_amount, FindObjectInArrayByPropertyValue($quantityUnits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityUnits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }} @if($selectedRecipePosition->need_fulfilled == 1)@elseif($selectedRecipePosition->need_fulfilled_with_shopping_list == 1)@else@endif @if(FindObjectInArrayByPropertyValue($selectedRecipeSubRecipesPositions, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $__t('Enough in stock') }} @else {{ $__t('Not enough in stock, %1$s missing, %2$s already on shopping list', round(FindObjectInArrayByPropertyValue($selectedRecipeSubRecipesPositions, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount, 2), round(FindObjectInArrayByPropertyValue($selectedRecipeSubRecipesPositions, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list, 2)) }} @endif @@ -225,7 +225,7 @@ @if(!empty($selectedRecipe->picture_file_name)) -

+

@endif @if($selectedRecipePositionsResolved->count() > 0) @@ -254,7 +254,7 @@ @else @if($selectedRecipePosition->recipe_amount == round($selectedRecipePosition->recipe_amount, 2)){{ round($selectedRecipePosition->recipe_amount, 2) }}@else{{ $selectedRecipePosition->recipe_amount }}@endif @endif - {{ $__n($selectedRecipePosition->recipe_amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }} + {{ $__n($selectedRecipePosition->recipe_amount, FindObjectInArrayByPropertyValue($quantityUnits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityUnits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }} @if($selectedRecipePosition->need_fulfilled == 1)@elseif($selectedRecipePosition->need_fulfilled_with_shopping_list == 1)@else@endif @if(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $__t('Enough in stock') }} @else {{ $__t('Not enough in stock, %1$s missing, %2$s already on shopping list', round(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount, 2), round(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list, 2)) }} @endif diff --git a/yarn.lock b/yarn.lock index 6ce0dfaf..36b4cc68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -211,6 +211,13 @@ gettext-translator@^2.1.0: dependencies: sprintf-js "^1.0.3" +jquery-lazy@^1.7.10: + version "1.7.10" + resolved "https://registry.yarnpkg.com/jquery-lazy/-/jquery-lazy-1.7.10.tgz#aa3d43d058bf1ea89284214f4521f6d9a162d051" + integrity sha512-1vBpU+igfZJ58BrQrk2OFl3TMriGeIfZUg35uSIajZF4GcxF96NtdS3LbWk5a72rH2ypz0odTsAkqhUsICknhw== + dependencies: + jquery ">=1.7.2" + jquery-serializejson@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/jquery-serializejson/-/jquery-serializejson-2.9.0.tgz#03e3764e3a4b42c1c5aae9f93d7f19320c5f35a6" @@ -236,7 +243,7 @@ jquery@3.3.1: resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca" integrity sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg== -jquery@>=1.12.0, "jquery@>=1.5.0 <4.0", jquery@>=1.7, jquery@>=1.9.1, jquery@^3.0, jquery@^3.4.1: +jquery@>=1.12.0, "jquery@>=1.5.0 <4.0", jquery@>=1.7, jquery@>=1.7.2, jquery@>=1.9.1, jquery@^3.0, jquery@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2" integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==