采取高效编码 采用 webp
,webm
等格式进行编码,可以使用cwebp
命令压缩图片。视频可以通过在线网站进行转换;
推荐的格式
图片 webp,avif 视频/动图 webm 字体 woff2 Best Practice While MP4 has been around since 1999, WebM is a relatively new file format initially released in 2010. WebM videos are much smaller than MP4 videos, but not all browsers support WebM so it makes sense to generate both.
批量转换图片格式 下载libwebp
库,使用cwebp
命令;下面为个人自用的批量转换的 Python 脚本
windows 自带截图和 qq 截图并不支持 webp 格式的截图; 最新版的 pixpin,snipaste 等第三方截图软件支持 webp 格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 from pathlib import Path
import subprocess
import shutil
import argparse
covert_these_types = ( " .png " , " .jpg " , " .jpeg " )
def convert_to_webp ( input_dir : Path , output_dir : Path ):
"""
将指定目录及其子目录中的文件转换为.webp格式。输出文件保存在指定的输出目录下,并保留原有目录结构。
"""
for file_path in input_dir . rglob ( " * " ):
# 检查文件是否为需要转换的类型
if file_path . suffix . lower () in covert_these_types :
# 构建输出文件路径,/ 操作符在这里将 output_dir 和 relative_path 组合成一个新的路径对象
relative_path = file_path . relative_to ( input_dir )
output_path = output_dir / relative_path . with_suffix ( " .webp " )
output_path . parent . mkdir ( parents =True, exist_ok =True)
# 使用cwebp命令进行转换
try :
subprocess . run (
[ " cwebp " , str ( file_path ), " -o " , str ( output_path )], check =True
)
except subprocess . CalledProcessError as e :
print ( f "Failed to convert { file_path } : { e } " )
else :
output_path = output_dir / relative_path
shutil . move ( file_path , output_dir )
def main ():
# 创建命令行参数解析器
parser = argparse . ArgumentParser (
description = " Convert PNG, JPG, and JPEG files to WEBP format. "
)
parser . add_argument (
" input_dir " , type = str , help = " Input directory containing images to convert "
)
parser . add_argument (
" output_dir " , type = str , help = " Output directory to save converted images "
)
args = parser . parse_args ()
input_dir = Path ( args . input_dir )
output_dir = Path ( args . output_dir )
convert_to_webp ( input_dir , output_dir )
if __name__ == " __main__ " :
main ()
[ USAGE ]
python ./cwebp.py ../source/img/unused/ ./output
效果测试 下面是本网站图片压缩前后的体积对比:
╭───┬───────────────────┬──────┬───────────╮
│ # │ name │ type │ size │
├───┼───────────────────┼──────┼───────────┤
│ 0 │ gallery │ dir │ 66.2 MiB │
│ 1 │ gallery_origin │ dir │ 186.8 MiB │
│ 2 │ thumbnails │ dir │ 19.6 MiB │
│ 3 │ thumbnails_origin │ dir │ 88.0 MiB │
│ 4 │ unused │ dir │ 18.4 MiB │
╰───┴───────────────────┴──────┴───────────╯
gallery 目录的体积缩小了约 64.57%原始大小: gallery_origin: 186.8 MiB;图片*54(jpg,png),视频*3(mp4)
压缩后大小: gallery: 66.2 MiB
压缩体积: 186.8 MiB - 66.2 MiB = 120.6 MiB
thumbnails 目录的体积缩小了约 77.73%原始大小: thumbnails_origin: 88.0 MiB;图片×100(jpg,png)
压缩后大小: thumbnails: 19.6 MiB
压缩量: 88.0 MiB - 19.6 MiB = 68.4 MiB
使用 gulp 压缩代码 添加以下依赖,并在scripts.build
里添加gulp
,这样执行build
操作后会对代码进行压缩
// File: package.json
" scripts " : {
" build " : " hexo generate && gulp " ,
" clean " : " hexo clean " ,
" deploy " : " hexo deploy " ,
" server " : " hexo server "
} ,
" dependencies " : {
" gulp " : " ^5.0.0 " ,
" gulp-clean-css " : " ^4.3.0 " ,
" gulp-html-minifier-terser " : " ^7.1.0 " ,
" gulp-uglify-es " : " ^3.0.0 " ,
}
网站根目录添加gulpfile.js
文件,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 // File: Efterklang.github.io/gulpfile.js
const gulp = require ( " gulp " ) ;
const cleancss = require ( " gulp-clean-css " ) ;
const uglify = require ( " gulp-uglify-es " ) . default ;
const htmlmin = require ( " gulp-html-minifier-terser " ) ;
// 压缩public目录下的css文件
// 可接受参数的文档:https://github.com/jakubpawlowicz/clean-css#constructor-options
gulp . task ( " minify-css " , () => {
return gulp
. src ( " ./public/**/*.css " ) // 处理public目录下所有的css文件,下同
. pipe ( cleancss ( { compatibility : " ie8 " } )) // 兼容到IE8
. pipe ( gulp . dest ( " ./public " )) ;
} ) ;
// 压缩public目录下的js文件
gulp . task ( " minify-js " , () => {
return gulp
. src ([ " ./public/**/*.js " , " !./public/**/*.min.js " ])
. pipe ( uglify ())
. pipe ( gulp . dest ( " ./public " )) ;
} ) ;
// 压缩public目录下的html文件
// 可接受参数的文档:https://github.com/terser/html-minifier-terser#options-quick-reference
gulp . task ( " minify-html " , () => {
return gulp
. src ([ " ./public/**/*.html " , " !./public/about/index.html " ])
. pipe (
htmlmin ( {
removeComments : true , // 移除注释
removeEmptyAttributes : true , // 移除值为空的参数
removeRedundantAttributes : true , // 移除值跟默认值匹配的属性
collapseBooleanAttributes : true , // 省略布尔属性的值
collapseWhitespace : true , // 移除空格和空行
minifyCSS : false , // 压缩HTML中的CSS
minifyJS : true , // 压缩HTML中的JS
minifyURLs : true , // 压缩HTML中的链接
ignoreCustomFragments : [
/ <% [ \s\S ]*? %> / ,
/ < \? [ \s\S ]*? \? > / ,
/ \$\$ [ \s\S ]*? \$\$ / ,
] ,
} )
)
. pipe ( gulp . dest ( " ./public " )) ;
} ) ;
// 默认任务,不带任务名运行gulp时执行的任务
gulp . task ( " default " , gulp . parallel ( " minify-css " , " minify-js " , " minify-html " )) ;
压缩时可能会报 parseError,可以在ignoreCustomFragments
里添加相应的规则忽略某些语法的解析。如添加/\$\$[\s\S]*?\$\$/]
,以忽略$$...$$
中的代码;不会写 js 正则表达式,可以询问 ai
Error in plugin " gulp-html-minifier-terser "
Message:
Parse Error: < W_{T} \l t 2 ^{n-1} ; n为分组中的bit数 \\\\
& 若W_ {T} = 1 ,则退化为停止等待协议 ; 若W_ {T} \g t 2 ^{n-1},则会造成接收方无法辨别新旧数据分组的问题 \\\\
& 接收窗口尺寸W_ {R} 必须满足: 1 < W_{R} \l eq W_{T} \\\\
& 若W_ {R} = 1 ,则退化为回退 N 帧协议 ; W_ {R} \g t W_{T}没有意义
\end {align*}
$$
< /div >
图片懒加载 npm install hexo-native-lazy-load --save
lazy_load :
enable : true
onlypost : false
hexo clean
,部署后在页面打开 devtools;可以看到 img 已添加loading="lazy"
Instant Page instant.page uses just-in-time preloading — it preloads a page right before a user clicks on it.
根目录创建scripts/instant-page.js
,注入以下代码
hexo . extend . injector . register (
" body_end " ,
' <script src="//instant.page/5.2.0" type="module" integrity="sha384-jnZyxPjiipYXnSU0ygqeac2q7CVYMbh84q0uHVRRxEtvFPiQYbXWUorga2aqZJ0z"></script> ' ,
" default "
) ;
Pjax 目前 Icarus 仅初步支持 Pjax,详见https://github.com/ppoffice/hexo-theme-icarus/pull/1287
OSS + CDN 一种广泛采用的免费方案:github 作为图床,jsdelivr 作为 CDN;优点是免费,但国内访问效果一般。如果预算充足的话可以考虑替换掉 引用图片时:<img src="https://cdn.jsdelivr.net/gh/<user_name>/<repo_name>@<branch_name>/<path_to_your_image>" alt="">
此外 Cloudflare 也免费提供了一定额度的 R2 + CDN 服务,可以考虑使用;需要信用卡,下载 Paypal 绑定国内银联的信用卡即可。这也是本站目前使用的方案
To be continued(?) Tools
更多优化方案