- 前端常见的优化
- (1)按需加载打包,路由按需打包,通过import按需引入方法导入路由组件,打包时会将组件分来打包,仅当加载该组件时才会请求相关文件,大大减少了首屏加载的文件的大小。
- (2)ui库按需引入,elementui为例,全局整体引入大约1.5M,按需引入可以减少一半的体积。需要用到插件babel-component-plugin,从lib库中取相关组件。
- (3)提取公共代码,提取公共依赖,将重复代码单独打包,避免不同文件的重复打包;公共依赖在版本未更新的情况下很少变动,因此单独打包有利于缓存,上线时可以不必更新该包缓存。webpack切分代码,optimization/splitChunks/cacheGroup;主要优先级,先公共依赖,再公共代码(priority越大越先,test:'node_modules'规定依赖检测位置,minChunks:2,最少2个引用算公共,minSize依赖包大小限制检测)。
- (4)CDN 将限定版本的依赖通过cdn引入,可以就近引入相关依赖。external去除打包时的相关依赖,cdn引入地址可以在html模板中手动引入,或者通过html-webpack-plugin进行配置(配置cdnConfig,然后再去html模板中<% htmlWebpackPlugin.options.cdnConfig.forEach(()>={...}) %>)。
- (5)开启productiongWebpackGzip的压缩,开启nginx Gzip压缩。
2.http1,http2区别 http2实现了真正的多路复用,http1.1过切片的方法实现多个请求复用 http2使用二进制传输,更加方便,http1使用字符串 http2默认开启keep-alive长连接
3.浏览器缓存 浏览器缓存主要分为强缓存和协商缓存。 强缓存相当于通过设置来控制缓存,主要为expires和cache-control字段。expires设定一个绝对时间,在时间内命中强缓存,返回200.expires的绝对时间,与客户端本地时间比较,不准确,所有cache-control使用了相对时间。 协商缓存在未触发强缓存时触发,会先发送一个头部去判断是否有新版本文件,比较字段if-modified-since和last-modified,如果有更新,则会取缓存,返回304.if-none-match,比较etag,etag由服务端通过算法生成,一般通过内容索引和时间计算得到。优先级if-none-match高于if-modified-since。if-none-match和if-modified-since的区别,if-modified-since只精确到秒级别;有些文件可能定期生成,但内容没有改变;服务端没有准确获取文件修改时间,与代理服务器不一致;
4、webpack打包
-
常用loader:style-loader,css-loader,postcss-loader,sass-loader 加载顺序,从右到左。style-loader负责将css放到html的标签中,必须载css-loader之后执行。vue-loader,babel-loader。file-loader,url-loader(用于文件和图片解析,url-loader可以设置maxsize,当图片小于某个大小时,转化base64直接放到html中,否则使用file-loader去解析。)
-
常用plugin:html-webpack-plugin,mini-css-extract-plugin(抽取css),mini-css-assets-plugin(压缩css用,使用后必须使用uglyifyjs-plugin来压缩js),BundleAnalyzerPlugin(分析包大小),VueLoaderPlugin(如果使用vue-loader必须使用),babel-components-plugin(外部组件按需加载用)
-
常用配置
entry:path.resolve(process.cwd(),'./src/index.js'),
output:{
filename:'[name].js',
path:path.resolve(process.cwd(),'dist'),
clean:true
},
devServe:{
hot:true,
port:8080,
compress:true,
},
optimization: {
// 分割代码
splitChunks: {
chunks: 'all',
minSize: 20000,
minChunks: 1,
maxAsyncRequests: 30,
maxInitialRequests: 30,
cacheGroups: {
// 自定义包名,commons可以用来存公共业务代码
commons: {
name: "commons", // 抽离出来的模块名
chunks: 'initial', // 初始化,从入口文件开始抽离
minSize: 20000, // 如果这个代码大于20000字节
minChunks: 2, // 这个代码引用多少次才需要抽离
},
// vanders存相同的第三方依赖库
vanders: {
priority: 1, // 权重,权重越高越先抽取
name: 'vendors',
test: /node_modules/, // 如果你多次引用了node_modules第三方模块,就抽取出来
chunks: 'initial',
minSize: 20000,
minChunks: 2
}
}
}
},
module:{
rules:[
{
test:/\.jsx?$/i,
use:'babel-loader',
exclude:/node_modules/
},
{
test:/\.s?css$/i,
use:['style-loader','css-loader','sass-loader'],
exclude:/node_modules/
}, {
test:/\.vue$/i,
use:'vue-loader',
exclude:/node_modules/
}
]
},
plugins:[
new HtmlWebpackPlugin({
template:'path.resolve(process.cwd(),'./public/index.html',
filename:'index.html'},
chunks:['index','venders','commons']
}),
]