以下是来自 Pascal Klau 的客座文章,他自称是来自德国的 Web 开发培训生,使用 WordPress、Gulp,以及最近的 VueJS 和 Webpack。
在我学习 Web 技术的过程中,我偶然发现了文件缓存的重要性。对于网页性能来说,这是一件非常重要的事情。我也偶尔会注意到,当文件被修改后,刷新页面时,浏览器仍然可能使用旧版本(由于缓存)。有一个解决方案!
哈希打破缓存
在文件名中添加哈希值可以让浏览器认为它是一个完全不同的文件。从而“打破缓存”。例如,如果文件 `main.3hZ9.js` 更改为 `main.8a3s.js`,浏览器将肯定重新下载它。此重命名可以通过任务运行器自动完成。
但是对于我们这些使用 WordPress 的人来说,有一个问题。您需要按名称手动加载文件,但您无法知道随机生成的哈希值。
wp_enqueue_script('main', get_template_directory_uri() . '/js/main.3hZ9.js', array('jquery'), null, true);
使用 Gulp 添加哈希值
在我们解决 WordPress 问题之前,以下是添加哈希值的方法。
由于我使用的是 Gulp,gulp-hash 非常方便。如果您使用的是 Grunt,则有 等效项。
// ES5
var gulp = require('gulp'),
hash = require('gulp-hash');
var options = {
hashLength: 4,
template: '<%= name %>.<%= hash %><%= ext %>'
};
gulp.src('./js/**/*.js')
.pipe(hash(options))
.pipe(gulp.dest('build'));
// ES6 + Gulp 4
import gulp from 'gulp'
import hash from 'gulp-hash'
let options = {
hashLength: 4,
template: '<%= name %>.<%= hash %><%= ext %>'
};
export function hashing() {
return gulp.src('./js/**/*.js')
.pipe(hash(options))
.pipe(gulp.dest('build'))
};
const dev = gulp.series(hashing);
export { dev };
export default dev;
WordPress 解决方案
以下是如何自动加载哈希文件!诀窍是我们不需要知道哈希名称,PHP 会找到文件。
首先,我们准备好 遍历文件系统 中我们的资源所在的目录。
function enqueue_files() {
$dirJS = new DirectoryIterator(get_stylesheet_directory() . '/js');
}
现在我们遍历所有文件并筛选以 `.js` 结尾的文件。
foreach ($dirJS as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) === 'js') {
}
}
依赖项需要 WordPress 中的名称,因此我们可以根据文件名进行设置。“main” 比 “main.3hZ9” 更好(因为它不会改变),因此我们可以去除哈希值以获得加载名称。
foreach ($dirJS as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) === 'js') {
$fullName = basename($file); // main.3hZ9.js
$name = substr(basename($fullName), 0, strpos(basename($fullName), '.')); // main
}
}
在 WordPress 中,您加载的任何资源可能都需要依赖项。您可以通过将它们作为数组传递给加载函数来自行声明。在这里,我们正在检查文件并在需要时添加依赖项
foreach ($dirJS as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) === 'js') {
$fullName = basename($file);
$name = substr(basename($fullName), 0, strpos(basename($fullName), '.'));
switch($name) {
case 'main':
$deps = array('vendor');
break;
default:
$deps = null;
break;
}
}
}
现在全部放在一起!
我们现在拥有加载资源所需的一切,因此将其全部放在一起
foreach ($dirJS as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) === 'js') {
$fullName = basename($file);
$name = substr(basename($fullName), 0, strpos(basename($fullName), '.'));
switch($name) {
case 'main':
$deps = array('vendor');
break;
default:
$deps = null;
break;
}
wp_enqueue_script( $name, get_template_directory_uri() . '/js/' . $fullName, $deps, null, true );
}
}
CSS 文件的工作方式相同,只是 WP 加载函数略有不同。
PHP filemtime 怎么样?
使用 WordPress,您可以在其加载函数中添加一个破坏缓存的 URL 参数,使用 filemtime。它会在每次修改文件时添加时间戳
$file = get_template_directory_uri() . '/js/main.js'
wp_enqueue_script( 'main', $file, null, filemtime($file), true );
// => [...]/main.js?1203291283
为什么我不使用此技术?
我将 JavaScript 文件捆绑到 `main.js` 和 `vendor.js` 中(在我的情况下,使用 Webpack)。当编辑 `main.js` 时,`vendor.js` 的时间戳也会发生变化。因此它将每次都被下载,而实际上并没有任何不同。
另一方面,哈希值保持不变。
结论
现在,您可以通过 Gulp 在文件更改时动态地向文件添加哈希值。并且您可以在 WordPress 中加载这些文件,而无需知道新文件名的目录。
在 wp_enqueue_script 参数中,第四个选项是版本号,用于破坏缓存。为什么不直接使用内置功能?这种方法的优势是什么?
嘿,Chris,
您不希望每次保存文件时都手动编辑哈希值。让 PHP 来做这件事。
您可以为此使用 PHP filemtime。
但文章最后说明了可能不是您想要的那个原因。:)
我也有同样的想法。。
同意;不要使用时间戳,而是使用动态哈希作为“版本”。根据文件/服务器的不同,这可能有点密集,但您可以始终缓存哈希值并获得讽刺的积分。
我只是使用我动态更改的构建版本,该版本在主题中定义,然后 wp_enqueue_script 参数使用它。一直有效,但这也是一个很酷的解决方案。