让网站使用webp格式的图片降低加载速度吧!
- 2017-05-25 15:01:05
- 幻音い
- 8254
温馨提示: 这篇文章于2760天前编写,现在可能不再适用或落后.
jpg,png这些图片是不是很慢呢?现在浏览器很多人都是用chrome内核的浏览器了吧,既然用chrome为啥不试试把网站图片转成webp的格式呢?
这样还可以加快图片加载速度呢.webp格式目前只可以在谷歌浏览器(内核)下使用,其他浏览器并不可以.
首先怎么弄呢?如果是你用的云服务转的webp格式图片,那么可以无视这篇文章了.
这篇文章主要是针对图片存在自己网站服务器里面的,比如我....
关于转换webp格式图片有很多方法,
1,可以用php的gd库的webp转(貌似一些服务器默认都是不装的..我也没找到这个扩展)
2.使用谷歌的libwebp进行转换(推荐)
3.使用php其他扩展(反正都慢...)
4.使用手动转(这....)
首先下载libwebp,可以从官网下载也可以从一些镜像站下载.
注:linux版(windows版?没有 快滚)
下载地址:http://mirrors.bysb.net/libwebp/
下载了之后就可以安装了
tar --strip-components 1 -xzvf libwebp*.gz -C /usr/local
命令可以使用
cwebp 需要转的图片地址 -o 输出的图片地址
恩,就这样...这样就完了吗?当然没有,这要是就完了那就干脆不写了....
然后按照图片在本地的管理,难道你要一个一个的转换?没睡醒吧..
我写了一个php脚本,可以直接运行php进行转换图片
md,,水印越来越有问题了..
上图为转换完成的图片...
脚本如下(autoToWebp)
class ToWebp{
private $rootDir = './';
private $quality = 75;
private $ext = ['jpg','jpeg','png','gif'];
private $rule = [];
private $errorList = [];
private $runtime = 0;
private $count = 0;
private $success = 0;
private $error = 0;
private $path = "/usr/local/bin/";
public function __construct($rootDir,$ext,$rule){
if(!$rootDir){
echo "\|反斜杠033[31m请设置图片文件夹反斜杠|反斜杠"{$rootDir}反斜杠|反斜杠"反斜杠|反斜杠033[0m反斜杠|反斜杠n";
exit;
}
$this->rule = $rule;
$this->rootDir = $rootDir;
if(substr($this->rootDir,strlen($rootDir)-1)!="/")$this->rootDir.="/";
$this->ext = $ext;
}
public function check(){
if(!file_exists($this->path."cwebp")){
echo "反斜杠|反斜杠033[31m转换工具cwebp不存在,即将开始下载....反斜杠|反斜杠033[33m反斜杠|反斜杠n";
shell_exec("wget http://mirrors.bysb.net/libwebp/libwebp-0.6.0-linux-x86-64.tar.gz&&tar --strip-components 1 -xzvf libwebp*.gz -C /usr/local");
if(!file_exists($this->path."cwebp")){
throw new Exception("下载libwebp失败....");
}
echo "反斜杠|反斜杠033[32m下载完成=>>>开始转换反斜杠|反斜杠033[0m反斜杠|反斜杠n";
}
foreach($this->rule as $ext=>$type){
if(!file_exists($this->path.$type)){
throw new Exception("转换工具:{$type}不存在");
}
}
}
public function start($quality){
try{
$this->quality = $quality;
$this->runtime = microtime();
echo "反斜杠|反斜杠033[32m================================================反斜杠|反斜杠n";
echo "开始准备转换{$this->rootDir}目录下的所有图片为Webp反斜杠|反斜杠n";
echo "================================================反斜杠|反斜杠033[0m反斜杠|反斜杠n";
$this->check();
$this->change($this->rootDir);
}catch(Exception $e){
echo "反斜杠|反斜杠033[31m================================================反斜杠|反斜杠n";
echo "转换失败,耗时{$this->runtime()}!反斜杠|反斜杠n";
echo "转换图片时发生错误:{$e->getMessage()}反斜杠|反斜杠n";
echo "反斜杠|反斜杠033[33m总共所要转换的图片数量:{$this->count}张反斜杠|反斜杠n";
echo "反斜杠|反斜杠033[32m成功转换为webp格式的数量:{$this->success}张反斜杠|反斜杠n";
echo "反斜杠|反斜杠033[31m转换失败的图片数量:{$this->error}张反斜杠|反斜杠033[0m反斜杠|反斜杠n";
foreach($this->errorList as $k=>$file)echo "反斜杠|反斜杠033[31m失败的图片".($k+1).":{$file}反斜杠|反斜杠033[32m反斜杠|反斜杠n";
exit;
}
}
private function runtime(){
$time = $this->runtime;
$start_date = explode(" ",$time);
$startMs = floor(current($start_date)*1000);
$startS = end($start_date);
$end_date = explode(" ",microtime());
$endMs = floor((current($end_date)*1000));
$endS = end($end_date);
if($startS==$endS){
return $endMs-$startMs."ms";
}else{
if($startMs>$endMs){
$endS-=1;
$ms = $endMs+1000-$startMs;
}else{
$ms = $endMs-$startMs;
}
return $endS-$startS.".{$ms}s";
}
}
private function change($root){
if(is_null($root)||!is_dir($root))throw new Exception("文件夹目录不存在:反斜杠|反斜杠"{$root}反斜杠|反斜杠"");
$dir = scandir($root);
foreach($dir as $file){
if($file!='.'&&$file!='..'){
if(is_dir($root.$file)){
$this->change($root.$file."/");
}else if(is_file($root.$file)){
$this->toWebp($root,$file);
}else{
throw new Exception("未知文件{$root}{$file}");
}
}
}
if($this->rootDir==$root){
echo "反斜杠|反斜杠033[32m================================================反斜杠|反斜杠n";
echo "目录反斜杠|反斜杠033[35m{$root}反斜杠|反斜杠033[32m下的图片转换完成,总共耗时反斜杠|反斜杠033[35m{$this->runtime()}反斜杠|反斜杠033[32m!反斜杠|反斜杠n";
echo "反斜杠|反斜杠033[33m总共所要转换的图片数量:{$this->count}张反斜杠|反斜杠n";
echo "反斜杠|反斜杠033[32m成功转换为webp格式的数量:{$this->success}张反斜杠|反斜杠n";
echo "反斜杠|反斜杠033[31m转换失败的图片数量:{$this->error}张反斜杠|反斜杠033[32m反斜杠|反斜杠n";
foreach($this->errorList as $k=>$file)echo "反斜杠|反斜杠033[31m失败的图片".($k+1).":{$file}反斜杠|反斜杠033[32m反斜杠|反斜杠n";
echo "图片全部转换为webp格式完成,请检查是否转换完成!反斜杠|反斜杠n";
echo "自动转换脚本By:幻音丶小涛!https://www.acgxt.com反斜杠|反斜杠n";
echo "================================================反斜杠|反斜杠033[0m反斜杠|反斜杠n";
}
}
private function toWebp($path,$file){
$fileData = pathinfo($file);
$fileName = $fileData['filename'];
if(isset($fileData['extension'])&&in_array($fileData['extension'],$this->ext)&&$fileData['extension']!="webp"){
$this->count++;
echo "反斜杠|反斜杠033[33m";
$c = "cwebp";
foreach($this->rule as $ext=>$cc){
if($fileData['extension']==$ext){
$c = $cc;
break;
}
}
shell_exec("{$c} -q {$this->quality} ".$path.$file." -o ".$path.$fileName.".webp");
if(is_file($path.$fileName.'.webp')){
$this->success++;
}else{
$this->error++;
array_push($this->errorList,($path.$file));
}
echo "反斜杠|反斜杠033[0m反斜杠|反斜杠n";
}
}
}
//开始运行
if(substr(php_sapi_name(), 0, 3) !== 'cli')die("PHP文件必须在cli模式下运行.反斜杠|反斜杠n");
//图片根目录
$root = null;
$quality = 75;
$root = isset($argv[1])?$argv[1]:$root;
//webp质量 0-100
$quality = isset($argv[2])?$argv[2]:$quality;
//需要允许转换的图片格式,请设置libwebp允许的格式,否则可能会报错
$ext = ['jpg','jpeg','png','gif'];
//使用什么libwebp处理
//默认使用cwebp
$rule = [
//图片格式 //使用的工具
'gif'=>'gif2webp'
];
(new ToWebp($root,$ext,$rule))->start($quality);
有了脚本之后你可以不用去下载libwebp了,脚本会根据是否安装,自动下载libwebp
运行脚本(cli模式下运行):
sudo php autoToWebp ./upload 75
./upload为需要转换的图片文件夹
75为图片质量
转换之后就可以成功转换了,最好在root下或sudo运行
转换了就完成了?当然没有,输出肯定还要写一个方法的....
然后先获取网站的全部生成的html内容,关于这个获取可以参考:https://www.acgxt.com/425.html通过拿缓存区的获取
然后拿到网站内容可以正则获取网站的img标签然后进行替换
function toWebp($content){
$pre = "//i";
if(preg_match_all($pre,$content,$m)){
foreach($m[1] as $k=>$path){
$content = str_replace($path,useWebp($path),$content);
}
return $content;
}else{
return $content;
}
}
//最后输出
如果是单个域名可以用这个方法
下面的方法用于检查浏览器是否支持webp图片,并判断图片是否存在,如果你觉得麻烦,可以自己写一个
//单域名可用
function useWebp($path,$isForce=false){
if(strpos($_SERVER['HTTP_ACCEPT'],"image/webp")===false){
return $path;
}else{
$dir = ".";
if(dirname($_SERVER['PHP_SELF'])!="/"){
$count = count(explode("/",$_SERVER['PHP_SELF']))-2;
for($i=0;$i<$count;$i++)$dir .= "/..";
}
$info = pathinfo($path);
$dirname = $info['dirname'];
if(substr($dirname,0,2)=="//"){
$dirname = substr($dirname,2);
}else if(substr($dirname,0,7)=="http://"){
$dirname = substr($dirname,7);
}else if(substr($dirname,0,8)=="https://"){
$dirname = substr($dirname,8);
}
$domain = explode("/",$dirname);
$domain = current($domain);
$filepath = str_replace($domain,"",$dirname)."/";
$file = $dir.$filepath.$info['filename'].".webp";
if(is_file($file)){
return $info['dirname']."/".$info['filename'].'.webp';
}else{
if(is_file($file)){
return $info['dirname']."/".$info['filename'].'.webp';
}else{
if($isForce){
return $info['dirname']."/".$info['filename'].'.webp';
}else{
return $path;
}
}
}
}
}
如果是泛域名类似我的网站这样可以用这个
//泛域名可用
function useWebp($path,$isForce=false,$isTop=false){
if(strpos($_SERVER['HTTP_ACCEPT'],"image/webp")===false){
return $path;
}else{
$dir = ".";
if($isTop){
$dir = ".";
}else{
if(dirname($_SERVER['PHP_SELF'])!="/"){
$count = count(explode("/",$_SERVER['PHP_SELF']))-2;
for($i=0;$i'../blog',
'account.acgxt.com'=>'../account',
'space.acgxt.com'=>'../space',
'search.acgxt.com'=>'../search',
'message.acgxt.com'=>'../message',
];
$severName = $_SERVER['SERVER_NAME'];
if(substr($dirname,0,2)=="//"){
$dirname = substr($dirname,2);
}else if(substr($dirname,0,7)=="http://"){
$dirname = substr($dirname,7);
}else if(substr($dirname,0,8)=="https://"){
$dirname = substr($dirname,8);
}
$domain = explode("/",$dirname);
$domain = current($domain);
$filepath = str_replace($domain,"",$dirname)."/";
$file = null;
if(strpos($domain,$severName)===false){
if(array_key_exists($domain,$rule)){
$file = $rule[$domain].$filepath.$info['filename'].'.webp';
}
}else{
$file = $dir.$filepath.$info['filename'].'.webp';
}
if(is_file($file)){
return $info['dirname']."/".$info['filename'].'.webp';
}else{
if($isForce){
return $info['dirname']."/".$info['filename'].'.webp';
}else{
return $path;
}
}
}
}
自动转换脚本:http://dl.acgxt.com/autoToWebp
最后记得文件夹要有权限啊....
直接shell_exec调用命令转换就行了
阁下需要登录后才可以查看评论哦~