前言我们将通过一个完整的实例, 一步步的优化加载, 渲染等各方面的体验. 开始首先我们先看一下项目的文件构成
这之中包含了一个基本网页的元素, js(React App), css, 还有图片. 相关资源见 https://github.com/joesonw/web-accelerate-example 我们先来看一下来serve整个网页的部分. server.js 'use strict';
const fs = require('fs');
const path = require('path');
const koa = require('koa');
const app = koa();
app.use(function* (next) {
const file = this.path.slice(1) || 'index.html';
try {
const content = yield cb => fs.readFile(path.resolve('./dist', file), cb);
this.body = content;
this.type = path.extname(file).slice(1);
this.status = 200;
} catch (e) {
this.status = 404;
}
yield next;
});
app.listen(process.env.PORT || 3000);这段代码只是简单的将 打开网页便可以看到相关加载情况.
我们可以看到, 整个 接下来我们将逐步优化, 然后每次将结果进行比较. 优化(一) --- 304网页加载优化中最常见的就是 具体代码如下: app.use(function* () {
const file = path.resolve(__dirname, path.resolve('dist', this.path.slice(1) || 'index.html'));
const headers = this.headers;
let ifLastModified = this.headers['if-modified-since'];
if (ifLastModified) {
ifLastModified = new Date(ifLastModified);
}
try {
const stat = yield cb => fs.stat(file, cb);
const now = Date.now();
if (ifLastModified &&
file !== path.resolve(__dirname, path.resolve('dist/index.html'))) {
if (ifLastModified >= stat.mtime) {
this.status = 304;
return;
}
}
console.log(file)
const content = yield cb => fs.readFile(file, cb);
this.body = content;
this.type = path.extname(file).slice(1);
this.status = 200;
this.set('Last-Modified', stat.mtime);
} catch (e) {
this.status = 404;
}
});(模拟实际情况中, 首页会动态生成, 加入一些广告,追踪或个性化数据, 最终效果:
我们可以看见, 下载时间为2ms, 可以几乎忽略掉(只有HTTP Headers), 总共的加载时间也只有了120ms, 相比之前, 整整少了 869ms. 但是, 我们满足了吗? 优化(二) --- 分别打包我们可以注意到, 我们打包出来最终只有一个js文件, 当依赖变多后(此例中只有react和react-dom, 每次修改都导致整个js文件被重新请求.所以我们想要把不同的library(甚至是项目内部公用的代码模块)提取出来. 我们首先要创建一个 const path = require('path');
const WebpackCleanupPlugin = require('webpack-cleanup-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"',
},
}),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
screw_ie8: true,
drop_console: true,
drop_debugger: true,
},
}),
new webpack.DllPlugin({
path: path.resolve(__dirname, 'dist/vendor/[name]-manifest.json'),
name: '[name]',
context: '.',
}),
],
devtool: 'hidden-source-map',
entry: {
'react': ['react', 'react-dom'],
},
output: {
path: path.resolve(__dirname, 'dist/vendor'),
filename: '[name].js',
library: '[name]',
},
};注意到 entry: {
'react': ['react', 'react-dom'],
},意味着我们可以将同一类型的包打包成一个js文件. 当然, 我们也要对 const dlls = fs.readdirSync(path.resolve(__dirname, 'dist/vendor/'))
.filter(file => path.extname(file) === '.js')
.map(file => path.basename(file, '.js'))
const dllReferencePlugins = dlls
.map(dll =>
new webpack.DllReferencePlugin({
context: '.',
manifest: require(`./dist/vendor/${dll}-manifest.json`),
})
);
module.exports = {
plugins: dllReferencePlugins.concat([
...
]),
...
}在这, 我们将自动扫描 这样我们就实现了分包加载(还有一些细节的修改, 包括
对于一般类型网站, 优化到这已经可以取得非常不错的效果了, 但是对于大型网站来说, 我们可以做的还有很多. 优化(三) --- 强制缓存我们可以注意到优化一种, 一个304的请求仍然花掉了100多毫秒, 对于大型网站, 资源特别多的情况, 这仍然是一个不小的开支. 那我们可以把这个省掉吗? 答案是可以的. 浏览器缓存当中, 还有一个特别的字段. 但是, 这仍旧需要每隔一段时间去请求. 我们该如何做呢? 答案就是, 设置超长的缓存时间, 例如10年. 但是这样我们便无法更新任何内容了. 我们该如何用到这样的特性, 而又很方便的更新呢. 我们可以给文件名加上 具体细节改动见git branch step-3. 实现效果: 从原始的1000毫秒, 到现在的20毫秒, 简简单单的三个步骤便可以让你的网页加载提速50倍 扩展阅读1.在实际生产中, 我们通常看到的是加载的CDN域名, 这是为何呢?
2.还有一种情况是, 资源分布在不同的服务器上
这是因为浏览器对于同一域名下资源的并行下载数量有限制. 使用不同的资源服务器可以避开这种限制, 加大下载并发数. 但是, 这样同样带来的缓存命中率的问题, 所以还需要存储用户缓存相关的数据. 合理的利用下, 对于页面整体的加载速度还是很有好处的. 3.其他的方法 在技术飞速发展的当下, 还有很多技术都是可以对终端用户的体验带来提升的. |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|