打包分析,Preloading,Prefetching

打包分析,是指当我们使用webpack 对项目进行打包之后,可以使用打包分析工具,来对我们打包生成的文件进行分析,来看看打包是否合理。

webpack 官方提供了它的一个分析工具的github 仓库:https://github.com/webpack/analyse

下面我们就来使用一下这个分析工具,来分析一下我们打包生成的代码文件。

我们要对我们打包的代码进行分析,首先要生成一个打包过程的描述文件。这个在官网的README 中有写,在运行webpack 的时候,加上“--profile --json > stats.json”

那么我们打开项目的package.json, 我们在script 中添加上上面的配置,如下。

  "scripts": {
    "bundle": "webpack --profile --json > stats.json",
    "start": "webpack-dev-server"
  },

然后,我们重新运行打包命令.

完了后,会发现在项目根目录下,多了一个文件 stats.json 。这个文件里面的内容,就是对打包过程的描述。

当然,我们也可以自己看这个文件,这样会比较不友好,很多项。我们可以借助一些工具,来分析这个文件的内容。

在webpack/analyse 的README 中,给出来这个工具的地址:http://webpack.github.io/analyse/

我们进入这个网址。然后把刚刚生成的stats.json 传上去。就会显示,如下结果。

这是Home 页,点击Modules 可以看到各模块之间的关系。

这是官方提供的工具。除了官方工具,还有很多工具,可以使用。

我们打开webpack 官方文档 documentation > guides > code splitting > bundle analysis 

它也列出了很多工具, 比如 webpack-chart , webpack-bundle-analyzer 可以试试。

接下来,Preloading, Prefetching 。

我们在webpack 配置项中,optimizaiton.splitChunks.chunks 不是‘all’ 而是‘async’。也就是默认只对异步加载代码进行分割。而代码分割,比如 lodash 实际上,是对第二次加载时会有性能提升(从缓存中获取),而对第一次页面加载是没有大的提升的(除了页面加载后触发某一条件下才进行异步加载)。

而真正对页面性能做优化,我们希望的是,当第一次访问页面的时候,它的加载速度就是最快的。那么上面的仅进行代码分割,是满足不了需求的。所以就有了Preloading,Prefetching。

我们先将项目webpack.config.js 代码分割部分配置改简单一些:

  optimization: {
    splitChunks: {
      chunks: 'async'
    }
  },

然后,我们把index.js 中的代码稍微改一下。

document.addEventListener('click', () => {
  const element = document.createElement('div');
  element.innerHTML = 'hello hello';
  document.body.appendChild(element);
})

然后,打包,运行页面。

那么这段代码是否有优化空间呢?有!

我们在页面里打开(chrome)控制台,然后在控制台里输入 Comand+Shift+p , 然后在搜索框中输入 coverage 关键词,打开show coverage .如图

然后我们点击左边录制的圆点,刷新。下面显示了,代码未使用率是17%

实际上,我们看到,document 的click 的事件处理函数代码,它在页面刷新的时候是放在Unused Bytes 中的。如果这部分代码量很大,而它在页面加载的时候不需要用到,那么把它放在页面加载的时候一起加载,是会拖慢页面首次加载的性能的。

因此,比较好的方式是,这种异步交互的代码,放在一个单独的模块中编写。

比如,我们在src 下新建一个click.js 文件,如下。

function handleClick () {
    const element = document.createElement('div');
    element.innerHTML = 'hello hello';
    document.body.appendChild(element);
}

export default handleClick;

然后,再修改一下index.js 文件,如下。

document.addEventListener('click', () => {
  import('./click.js').then(({default: func}) => {
    func()
  })
})

下面,我们运行打包命令,然后重新刷新一下页面,发现,Unused Bytes 百分比反而增加了。这是为什么呢!因为我们的代码量变少了!hhh...

来看看,打包后的代码,如下。click 事件处理函数现在变得比以前少了,因此分母小了。

当然,在我们点击页面后,百分比就降下来了。

这种方式,是让页面较快加载的方式!

当我们用这种方式编写代码的话,我们是可以在交互的时候,再去发送网络请求,加载交互代码,但是这也有一个问题。当交互发生时,才去网络请求代码,然后执行代码,那么可能会影响交互性能。那么我们希望首屏核心代码加载不会变慢,后续交互操作也很顺畅,那么就可以通过,在首屏核心代码加载后,再程序自己去加载一些交互代码,类似偷偷地加载。这种方式,就得依赖Preloading, Prefetching 这种打包特性来实现。

参考官网:documentation > guides > code splitting > Prefetching/Preloading Modules

使用magic comment 语法,如下(index.js)

document.addEventListener('click', () => {
  import(/* webpackPrefetch: true */ './click.js').then(({default: func}) => {
    func()
  })
})

上面的意思是,当点击页面的时候加载click.js,但不是非要等到点击的时刻去加载。一旦发现,目前主要的js 都加载完成了之后,网络带宽有空闲的时候,就可以加载了。

然后打包,刷新页面。会发现,分割的js 文件,就不是在点击页面的时候加载了,它会提前加载。再点击页面的时候,就会使用缓存中的文件了。

preloading 与 prefetching 的主要区别是,prefetching 的代码会等到主要的js代码加载完 浏览器空闲时才会去加载,preloading 代码会与主要的js 代码一起加载。官网解释如下,更详细的应该翻阅官网。

因此,这里推荐的提高性能的一个思路是,提高代码的利用率,把一些代码放入异步加载中,使用懒加载 prefetching 的方式加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值