加速网站从客户端浏览器到服务器的多个图像上传

时间:2015-12-07 01:58:45

标签: javascript php

我知道有多种方法可以将多个图像从浏览器上传到服务器,并且上传速度也取决于服务器和网络的速度。 标准的做法:

  

点击网站上的上传按钮 - >选择要上传的图像    - >单击“提交”按钮将所有图像上传到服务器(提示"请等待"到用户) - >上传成功!

但就编码部分而言,我只是想知道是否有更快的方法可以有效地将图像从客户端设备上传到服务器? (使用Javascript和php)

目前我正在做的事情是先减少"首先是客户端的图像,然后将图像发送回服务器。 但这很慢,因为javascript需要时间来减少"图像的大小。 通过" cut-down",我的意思是使图像宽度和高度更小。 有更快的方法吗?

(一些javascript和php编码示例也会有所帮助。)

8 个答案:

答案 0 :(得分:6)

简答:,Javascript并不慢,也不是PHP。

如果图像很大(几兆字节),则需要花一点时间在javascript / php中裁剪/调整图像大小。没有办法避免它。

我相信您遇到了性能问题,因为:

  1. 您正在上传许多图片,并且.. ..
  2. 其中一些很大(按兆字节计算)
  3. 在上传之前考虑优化图片。我建议你使用kraken.io,你可以在不改变图像质量的情况下缩小图像的大小(失去模式)。

    另外,请考虑按块上传图片,其中包括:

    1. 允许您跟踪上传进度
    2. AJAX驱动
    3. 有许多块上传插件,其中之一是:

      https://github.com/blueimp/jQuery-File-Upload/wiki/Chunked-file-uploads

      最后但并非最不重要的是,看看kraken.io本身,也许你对如何加快图片上传知之甚少。

答案 1 :(得分:3)

让我们尝试系统地面对这一挑战!您的任务非常简单:尽快将X字节从用户计算机发送到服务器Y.让我们假设一旦数据到达服务器,处理时间可以忽略不计 - 任何现代服务器都可以非常快速地处理大图像。

我们可以将可能的解决方案分为两类:

  1. 减少X - 减少发送的数据量。在JavaScript中缩小用户端的图像,并将较小的图像发送到服务器Y.

  2. 将服务器Y移近用户(令人惊讶的是没有人提到过这个?)没有必要在全球范围内部署多台服务器,你可以只使用CDN(其中很多都是免费或非常便宜的)。尽管CDN最终仍会打到您的网络服务器,但通常可以认为CDN提供商的国际带宽比普通用户更好。

  3. 额外说明:

    1. 进行一些速度测试,您当前的服务器可能会出现带宽问题,并且图像上传的速度比应该的速度慢。只需将网站移动到另一家托管公司,您的图片上传速度就会快一些。

    2. 根据您的应用程序用户体验,您可以通过在选择文件(在JS端完成)时显示图像缩略图来提高用户所感知的速度,同时文件仍在上传。您甚至可以允许用户在上传过程中移动页面/网站 - 如果您不阻止UI,则缓慢上传不那么烦人。

    3. 一般来说,这是一个复杂的问题,没有一种方法 - 这是一系列步骤。如果某个用户的连接很糟糕,那么其他任何事情都无关紧要!

答案 2 :(得分:2)

我以前不得不解决类似的问题,虽然我的解决方案是优化客户端的图像,你声称速度很慢。由于我自己的经验不然,我有兴趣知道你已经尝试了什么解决方案。

我的解决方案是:

  1. 使用FileReader API在客户端读取图像。似乎没有必要。
  2. 使用Canvas API通过缩放和设置质量来优化每个图像。如果由于某种原因,此过程变得缓慢,您始终可以使用WebWorkers API将负载拆分为多个后台进程。好处是优化过程中的性能问题不会影响您的用户界面(不会让它卡住)。
  3. 使用Canvas将所有图像合并为单个精灵,并将精灵的元数据(每个图像:x,y,width,height)保存在单独的对象中。
  4. 使用Canvas toDataURL提取精灵的base64。
  5. 将压缩的精灵文件与精灵的元数据一起上传到服务器。在服务器上解压缩文件,然后根据元数据将其拆分并保存到单独的图像文件中。
  6. 这应该是利用客户端的技巧,在大多数情况下会降低您的网络使用和带宽要求。

    <强>更新

    这里是客户端代码的code example。 您可以在使用输入字段时选择任意数量的文件,然后仅选择图像,调整大小,打包精灵并导出为包含精灵的base64版本的对象以及其中每个图像的元数据。 我将base64数据uri可点击,以便您能够立即看到结果。

    缺少的是服务器端部分,您可以在其中获取对象并使用它。你使用base64数据uri创建一个图像,我建议使用imagemagick,但任何这样的库都可以解决问题,然后根据精灵的元数据使用你选择的库裁剪图像。并单独保存每个图像(或其他)。

    您可以在客户端进行大量小而酷的优化,以减少服务器的负载。

答案 3 :(得分:2)

不,上传仍然会很慢。速度几乎与代码无关。它变慢的主要原因是图像占用了大量空间。通常高达数兆字节。如果您要上传一串文本进行比较,那么它会快得多,因为该文本字符串只有几个字节或千字节。使这个更快一点的一种方法是在上传到服务器之前将图像放在压缩的.zip文件夹中。它仍然需要很长时间。

答案 4 :(得分:2)

  1. 上传原始图片时,除非您的用户上传未压缩的*.bmp,否则优化收益可能无关紧要。如果您在本地重新调整图片大小,请确保已应用适当的压缩 - 至少在使用画布时设置toDataURL encoderOptions,或类似JICdemo)。注意重新采样质量差。

  2. 如果您期望大量上传或处理低带宽用户,您可能需要引入可恢复的上传。像resumablejs这样的库会使用html5文件api并支持分块,这使得上传过程不那么痛苦。与UX增强功能相结合,这是一个非常强大的组合!

  3. 通过专注于感知的性能,您可以获得更好的结果,而不是专注于上传性能。一个有用的模式是将上传移动到工作流程的早期阶段 - 一旦选择了图像,Instagram就会开始上传,并在用户处理标题,位置,共享选项时在后台继续...

    "Secrets to Lightning Fast Mobile Design" slides总结了highscalability的更多想法:

    https://speakerdeck.com/mikeyk/secrets-to-lightning-fast-mobile-design?slide=82

      

    当没有人观看时移动位。图片上传开始之前分享它们,大多数应用等到共享屏幕之后。规则是在数据准备就绪后立即发送,然后将其与用户操作进行匹配。这使请求的数量加倍,但即使稍后发送取消,感知的性能也会得到改善。取消时删除数据。

  4. 上传到CDN。 Stackoverflow集成了imgur用于图像上传和so can you。当然,这取决于上传的敏感程度,预期功能和CDN的T&amp; Cs,但可以节省您的流量和存储空间,同时提供对原始图像,调整大小的副本和其他元数据的专业API访问。

答案 5 :(得分:0)

这是一个很好的解决方案,它可以在上传之前缩小图像的大小。

https://github.com/blueimp/jQuery-File-Upload

你没有说你是否反对使用jQuery,如果你是这样,你可以找到一个纯JavaScript的等效解决方案。

答案 6 :(得分:0)

我认为即使您在一天结束时找到更好的优化算法,如果我们谈论的是移动电话,您应该考虑网络可能非常慢,而CPU也可以。我的建议是尝试web workersthis tutorial可能非常有帮助。

Web工作者在后台独立于用户交互运行脚本,这对于避免对用户的影响以及管理图像处理和在后台上传非常有用。

两个主要优点:

  • 您可以并行运行多个线程/网络工作者
  • 网络工作者不会阻止主线程和用户体验

优势不仅可以加快图像处理速度,还可以避免冻结用户界面。

答案 7 :(得分:-1)

在这种情况下,可能会发现如果你停止缩小图像的大小 - 整个过程会更快。

图像的宽度/高度和大小(mb,kb)有多大? 上传图片需要多长时间? 你为什么要削减图像?

我认为你的javascript中的某些内容不对 - here是一种使用canvas和File API来调整图片大小的方法。