AI摘要:文章介绍了优化Typecho博客性能的多种方法:1)服务器端使用Nginx开启gzip压缩和浏览器缓存;2)图片优化采用原生JS实现懒加载;3)通过PHP压缩HTML输出;4)设置浏览器缓存和页面缓存策略,包括简单的PHP缓存实现。这些技术可显著提升网站加载速度和性能。
服务器端
使用Nginx
作为web服务端可以使用以下开启
# 启用 gzip 压缩
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_types
application/javascript
application/json
application/xml
text/css
text/plain
text/xml;
# 浏览器缓存控制
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
图片优化
使用原生js实现懒加载
document.addEventListener('DOMContentLoaded', function() {
// 获取所有图片(如果主题默认输出 src,可以动态替换为 data-src)
const images = document.querySelectorAll('img[src]:not([data-src])');
// 防止重复处理
images.forEach(img => {
if (!img.getAttribute('data-src')) {
img.setAttribute('data-src', img.src); // 把 src 存到 data-src
img.removeAttribute('src'); // 移除 src,避免立即加载
}
});
// 懒加载逻辑
const lazyLoad = (targets) => {
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img); // 加载后停止观察
}
});
});
targets.forEach(img => observer.observe(img));
} else {
// 兼容旧浏览器(滚动监听)
const checkImages = () => {
targets.forEach(img => {
const rect = img.getBoundingClientRect();
if (rect.top < window.innerHeight + 100) { // 提前 100px 加载
img.src = img.dataset.src;
}
});
};
window.addEventListener('scroll', checkImages);
checkImages(); // 初始检查
}
};
// 对所有 data-src 图片应用懒加载
lazyLoad(document.querySelectorAll('img[data-src]'));
});
资源合并与压缩
压缩HTML输出
// 在主题的 functions.php 中
function compress_html($html) {
$placeholders = [];
$i = 0;
// 匹配 <pre> 和 <code> 区块,替换为唯一占位符
$html = preg_replace_callback(
'/<(pre|code)[^>]*>.*?<\/\1>/is',
function ($matches) use (&$placeholders, &$i) {
$key = "###HTML_COMPRESS_IGNORE_" . $i . "###";
$placeholders[$key] = $matches[0];
$i++;
return $key;
},
$html
);
// 正常压缩
$search = array(
'/\>[^\S ]+/s',
'/[^\S ]+\</s',
'/(\s)+/s'
);
$replace = array(
'>',
'<',
'\\1'
);
$html = preg_replace($search, $replace, $html);
// 恢复占位符
if (!empty($placeholders)) {
$html = str_replace(array_keys($placeholders), array_values($placeholders), $html);
}
return $html;
}
//在head.php中开启
<?php ob_start("compress_html"); ?>
//在footer.php中结束
<?php ob_end_flush(); ?>
缓存策略
浏览器缓存
<meta http-equiv="Cache-Control" content="max-age=86400" />
在header.php
中加入
页面缓存
在主题的 functions.php
中添加简单的页面缓存
function page_cache() {
// 不缓存后台、登录页和提交操作
if (defined('__TYPECHO_ADMIN__') || $_SERVER['REQUEST_METHOD'] != 'GET') {
return;
}
$cache_dir = __TYPECHO_ROOT_DIR__ . '/cache';
if (!is_dir($cache_dir)) {
mkdir($cache_dir, 0755, true);
}
$url_hash = md5($_SERVER['REQUEST_URI']);
$cache_file = $cache_dir . '/' . $url_hash . '.html';
// 缓存过期时间(秒)
$cache_time = 3600; // 1小时
// 如果缓存文件存在且未过期,则直接输出
if (file_exists($cache_file) && (time() - filemtime($cache_file) < $cache_time)) {
echo file_get_contents($cache_file);
exit;
}
// 否则开始输出缓冲
ob_start();
}
function save_cache() {
// 同样跳过后台等页面
if (defined('__TYPECHO_ADMIN__') || $_SERVER['REQUEST_METHOD'] != 'GET') {
return;
}
$cache_dir = __TYPECHO_ROOT_DIR__ . '/cache';
$url_hash = md5($_SERVER['REQUEST_URI']);
$cache_file = $cache_dir . '/' . $url_hash . '.html';
// 保存缓冲内容到文件
$content = ob_get_contents();
file_put_contents($cache_file, $content);
}
// 在页面开始处调用
page_cache();
// 在页面结束前调用
register_shutdown_function('save_cache');