调整大小和上载脚本花费的时间太长



我使用的脚本在通过Ajax将图像上传到PHP文件之前调整客户端的大小。我正在调整图像客户端的大小,以减少服务器上的电源需求。我的脚本有效,但上传图像的时间太长,我需要帮助理解为什么会出现这种情况。文件的第一部分异步调整图像的大小。第二部分将调整大小的图像源编码为动态创建的隐藏输入,最后,Ajax使用timeout 3秒延迟函数将动态创建的输入值上传到PHP文件。

$(document).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
/* Upload Logo Image */
$("#loader-wrapper").hide();
$("#logo_image").change(function(){
$("#ImgText").fadeOut(10, "linear");
$("#loader-wrapper").css('background-image', 'none').fadeIn(200, "linear");
const form = document.querySelector('#user_update_settings');
form.addEventListener('change', async (e) => {
e.preventDefault();
// Get data URI of the selected image
const formData = new FormData(e.currentTarget);
const photoField = formData.get('logo_image');
const dataUri = await dataUriFromFormField(photoField);
// Defines Resized image URL
const imgEl = document.createElement('img');
imgEl.addEventListener('load', () => {
const resizedDataUri = resizeImage(imgEl, 600);
// Deletes Previous Input
var element =  document.getElementById('new_logo_image');
if (typeof(element) != 'undefined' && element != null)
{
var elementExists = document.getElementById("new_logo_image");
elementExists.remove();
} 
// Creates New Input
var objTo = document.getElementById('LogoInputContainer')
var image_input = document.createElement("input");
image_input.setAttribute("name", "new_logo_image");
image_input.setAttribute("id", "new_logo_image");
image_input.setAttribute("type", "hidden");
image_input.setAttribute("value", resizedDataUri);
objTo.appendChild(image_input);

});
imgEl.src = dataUri;
});
// Resize Script
function dataUriFromFormField (field) {
return new Promise((resolve) => {
const reader = new FileReader();

reader.addEventListener('load', () => {
resolve(reader.result);
});

reader.readAsDataURL(field);
});
}
function resizeImage(imgEl, wantedWidth) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const aspect = imgEl.width / imgEl.height;
canvas.width = wantedWidth;
canvas.height = wantedWidth / aspect;
ctx.drawImage(imgEl, 0, 0, canvas.width, canvas.height);
return canvas.toDataURL();
}
});
// Image Upload
$("#logo_image").change(function(){
setTimeout(() => {  

if(window.File && window.FileReader && window.FileList && window.Blob){
if($(this).val()){
// Checks File Extension
var fileExtension = ['jpeg', 'jpg', 'png', 'gif', 'bmp'];
if ($.inArray($(this).val().split('.').pop().toLowerCase(), fileExtension) == -1) {
alert("Only formats are allowed : "+fileExtension.join(', '));
exit();
}
$.ajax({
url: "/logo_uploader",
type: "POST",
data: new FormData($("#user_update_settings")[0]),
contentType: false,
cache: false,
processData: false,
dataType: 'json',
success:function(response){
if(response.type == 'success'){
$("#loader-wrapper").fadeOut();
$(".logo_image_container").css("background-image", "url("+ response.logo_image +")");
}else{
$("#loader-wrapper").fadeOut();
$("#ImgText").fadein(10, "linear").text("+ response.msg +");
}
}
});
}
} else {
alert("Can't upload! Your browser does not support File API!</div>");
return false;
}
}, 3000);
});
});

客户端,我的徽标上传程序验证文件类型,删除以前的图像[如果存在]解码$request->new_logo_image,并将文件保存在文件夹"logos"和SQL数据库中。

// User ID
$user_id = auth()->user()->id;
// Reserved Goods
$user = Users::where('id', $user_id)->first();
// Path
$FilePathDB = FilePathDB::first();
// Path
$file_path = $FilePathDB->public_img_path;
$path = $file_path.$user->logo_image;
// Deletes Previous Logo [If Applicable]
if(file_exists($path)) {
File::delete($path);
}

// Validates Extension
$validatedData = $request->validate([
'logo_image' => 'required|image|mimes:jpg,png,jpeg',
]);
// Generates a Unique New Name 
$new_name = 'logos/'.$user_id.trim($user->username).uniqid().'.jpg';
// Uploads request Image if file does not exist
if($request->hasFile('logo_image')) {
$image =  $request->new_logo_image; // your base64 encoded
$image = str_replace('data:image/png;base64,', '', $image);
$image = str_replace(' ', '+', $image);
File::put($file_path.$new_name, base64_decode($image));

// Logo Image Variable
$formFields = array(
'logo_image' => $new_name
);
// User ID Update
$users = Users::where('id', $user_id)
->update($formFields);
// If Successful
$response = print json_encode(array(
'type'=> 'success',
'msg' => 'Logo Uploaded Successfully',
'logo_image' => 'storage/'.$new_name,
));  
} else {

// If unsuccessful
$response = print json_encode(array(
'type'=> 'failed',
'msg' => 'Ooops, image upload unsuccessful. Please try again!',
)); 
}

浓缩HTML

<form method="POST" action="/user_update_settings" id="user_update_settings" enctype="multipart/form-data">
<label for="logo_image" class="pointer UploadImgBtn transition">
<input class="DisplayNone" type="file" name="logo_image" id="logo_image" accept="image/*">
<a>Upload Image</a> 
</label>
</form>

平均而言,对于3MB的图像,JS画布调整图像大小需要3秒,上传已经调整大小的文件需要15-20秒,现在大小在40-50KB之间。知道图像已经调整了大小,为什么我的代码需要这么长时间才能上传调整大小的图像?有没有我没有考虑过在后台运行的循环正在消耗客户端的资源?

经过深思熟虑,我刚刚找到了解决方案。当我运行Ajax脚本时,我将整个表单提交给服务器,其中包括旧图像和新图像。为了减少数据负载,可以将隐藏的输入放入新表单中,也可以指定要发送到PHP文件的数据。

最新更新