我正在使用 Google Lighthouse 找出加快页面加载时间的方法。
其中一个红点是我缺少一个 Service Worker。 所以我得到了一个工作。
在我使用 Service Worker 之前,我的页面在 7 秒内完全加载并准备就绪。 添加 Service Worker 后,我的页面在 29 秒内完全加载!
当我检查 Fiddler 是否正在运行时,Service Worker 似乎在让页面呈现之前加载了所有文件。
我在我的 webpack.config 中使用 SWPrecacheWebpackPlugin 插件来自动生成 service-worker.js 文件,因为我的库名称会自动散列以优化缓存。
这是我的 webpack.config:
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ChunkManifestPlugin = require('chunk-manifest-webpack-plugin');
const WebpackChunkHash = require('webpack-chunk-hash');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
var SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
// To handle the regeneratorRuntime exception
require('babel-polyfill');
require('file-loader');
require('css-loader');
require('style-loader');
require('html-webpack-template');
/* Shared Dev & Production */
const config = {
context: path.resolve(__dirname, 'src'),
entry: {
index: [
// To handle the regeneratorRuntime exception
'babel-polyfill',
'./index.js'
],
vendor: ['react', 'react-dom', 'react-router', 'react-redux', 'history', 'react-router-dom', 'redux', 'react-router-redux', 'redux-form', 'lodash'],
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.(ico|jpg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
exclude: /\/favicon.ico$/,
use: [
{
loader: 'file-loader',
query: {
name: '[path][name][hash].[ext]',
publicPath: '/'
}
}
]
},
{
test: /\.css$/,
include: path.join(__dirname, 'src/style'),
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(ico)(\?.*)?$/,
exclude: /node_modules/,
use: {
loader: 'file-loader',
options: { name: '[name].[ext]' },
},
},
{
test: /\.xml/,
use: {
loader: 'file-loader',
options: { name: '[name].[ext]' },
},
},
],
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js',
publicPath: '/',
},
resolve: {
extensions: ['.js'],
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
},
plugins: [
// New moment.js optimization
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity
}),
new webpack.optimize.ModuleConcatenationPlugin(),
new HtmlWebpackPlugin({
appMountId: 'app-root',
inlineManifestWebpackName: 'webpackManifest',
template: 'templateIndex.html',
title: 'Our Site',
}),
new SWPrecacheWebpackPlugin()
],
devServer: {
historyApiFallback: true,
},
};
//if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
config.plugins = [
...config.plugins,
new BundleAnalyzerPlugin({analyzerMode: 'static'}),
];
//}
//if (process.env.NODE_ENV === 'production') {
config.output.filename = '[name].[chunkhash].js';
config.plugins = [
...config.plugins,
new webpack.HashedModuleIdsPlugin(),
new WebpackChunkHash(),
/*new ChunkManifestPlugin({
filename: 'chunk-manifest.json',
manifestVariable: 'webpackManifest',
inlineManifest: true,
}),*/
];
//}
module.exports = config;
还有我的 templateIndex.html(出于同样的原因,我正在使用 HtmlWebpackPlugin,散列文件名) 服务加载器加载在主体的末尾。 如果我删除它,事情又很快了。但是随后 Lighthouse 提示...
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#242424" />
<title itemprop="name">My Site</title>
<base href="/">
<link rel="apple-touch-icon" sizes="57x57" href="/images/favicon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/images/favicon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/images/favicon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/images/favicon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/images/favicon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/images/favicon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/images/favicon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/images/favicon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/images/favicon-180x180.png">
<link rel="icon" type="image/png" href="/images/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/images/favicon-192x192.png" sizes="192x192">
<link rel="icon" type="image/png" href="/images/favicon-160x160.png" sizes="160x160">
<link rel="icon" type="image/png" href="/images/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="/images/favicon-16x16.png" sizes="16x16">
<link type="image/png" href="/images/favicon.png" rel="icon">
<link rel="icon" href="/images/favicon.ico" />
<link rel="shortcut icon" href="/images/favicon.png" />
</head>
<body>
<div id="app"></div>
<script type="text/javascript">
// ServiceWorker is a progressive technology. Ignore unsupported browsers
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js').then(function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
// registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
} else {
console.log('CLIENT: service worker is not supported.');
}
</script>
</body>
</html>
我在 Google 上进行了搜索,但找不到与我遇到的问题相关的任何内容。 这是预期的行为吗?因为如果是这样,那么我就不会使用 Service Loader。 否则,有人知道如何让我的页面与 Service Worker 并行加载吗?
最佳答案
您很可能应该在页面加载事件之后注册 SW。当前,当浏览器执行 HTML 脚本标记中的脚本时,您会立即注册 SW。注册甚至发生在任何关键应用程序逻辑之前,因为 Webpack 很可能会在结束 body 标记之前插入您的实际 JS 文件。
这里有更多关于这个主题的详细信息和解释! https://developers.google.com/web/fundamentals/primers/service-workers/registration
关于javascript - HTML5 ServiceWorker 显着降低页面加载速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48176741/