其实说到性能优化,他的范围太广了,今天我们就只聊一聊通过webpack配置减少http请求数量这个点吧。
简单说下工作中遇到的问题吧,我们做的一个项目中首页用了十多张图片,每张图片都是一个静态资源,所以都会有http请求,为了减少请求,我们可以通过base64编码的方法来展示图片。webpack中有一个包叫做url-loader,他可以将html以及css中的图片打包成base64,但是js中如果有图片url并不能编译成功(后面我会说明),现附上两张图看下普通图片以及base64编码后的图片有啥不同吧。
简单点说,base64就是一串加密的字符串。而且base64编码过的图片是没有http请求的(注意看此图,为什么有的图使用的base64有的却没有,这是有原因的,这个我们稍后解释)。
好吧,现在先回到我们的主角――url-loader,简单看下他的配置参数吧。
{ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', include: [resolve('static'),resolve('src')], options: { limit: 100000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }
我用的是vue-cli脚手架工具,所以这个实在webpack.base.config,js中配置的,test就是正则匹配图片格式,loader是使用url-loader,options是配置选项,比如我们一般会把小于8kb的图片才做base64转换,这个东西通过limit来控制(当然我们是小于100kb),name就是自定义image的路径以及name,include就是你想让哪个文件夹里面的图片进行url-loader转换,建议写上include,如果不写就会全局搜索,效率低下,而且文件夹不写全也会报错。当然还有一种格式是可以直接写到loader中的,就是以query的形式去拼装options。
{ test: /\.(gif|jpg)$/, loader: 'url-loader?limit=30000', options: { name: '[name].[ext]?[hash]' } }
在这里具体看下咱们配置的name属性吧,他是配合config文件中的那一堆assetsPath来用的,
index: path.resolve(__dirname, '../dist/index.html'), assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: '/'
index必须是本地文件系统上的绝对路径。
assetsRoot是所有静态资源的根路径(必须是绝对路径)
assetsSubDirectory是被webpack编译处理过的文件,比如我们要使用url-loader处理image
assetsPublicPath这个是http服务器运行的根路径(比如我们线上是www.baidu.com/indexbeta这个作为根路径,就需要将它改为'/indexbeta/')。
最终线上就会呈现这种path
现在我们知道打包后的image-url是根据这些配置参数以及url-loader的name来生成的。然后问题又来了,既然有这个好东西,是不是可以让所有的图片都展示base64,这肯定不行,因为上面那张编码过的png只有不到5kb,图片太大的话base64字符串会更长,所以还不如用http请求,这也就是为什么默认limit是10000了,就是让8kb之内的图片才编码。
但我们的项目中有的图片列表是用v-for遍历出来的,也就是url放到了js中(vue文件的data里),这样就不能被base64编码了,url-loader只会去编译html以及css中的image。所以可以使用import图片的方式通过一个变量去接受,然后将这些变量放到v-for中去渲染。
当我们使用base64转码后,首页的渲染时间缩短了2秒,是不是很给力呢。