webpack4.x 系列(二) ☞懒加载 、Preload、Prefetch的讲解

我们总是在想,如何让一些代码先不加载,而是先让核心代码加载,让用户能够快速的看到主页代码,而像一些事件按钮、其他页面通过某些操作再进行加载,或者在浏览器休息时候再进行加载呢!这里我们讲了三种方法去让代码优化。本节还介绍一些打包代码的工具,能够更好的去分析代码,然后去分析代码的使用情况,然后找一个最优的解决办法,使代码找到一个平衡点。

一、二节工具介绍,三节、懒加载,四节、preload与Prefetch

一、打包后代码的分析

我们会对打包的过程做分析,分析步骤:

1.先在package.json里面的script上面写上这个,--profile --json > stats.json,如下面所示:

打包会生成一个stats.json的文件

2.然后Install

# NPM
npm install --save-dev webpack-bundle-analyzer
# Yarn
yarn add -D webpack-bundle-analyzer

3.然后Usage (as a plugin)

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}

打包就会生成下面一样的图片:

里面会包含着各种打包的内容,包括依赖包文件等等,这个可以帮助我们分析哪些东西需要做进一步的优化。

这个模块会帮助你:

  1. 了解你的包里真正有什么东西。
  2. 找出什么模块构成最大的大小。
  3. 找出错误打包的模块文件。
  4. 通过这个我们可以让我们的打包文件达到最优。

在vue-cli4 以后需要使用在vue.config.js中配置,配置如下

/* vue.config.js */
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
 
const isPro = process.env.NODE_ENV === 'production'
 
module.exports = {
    
    ... 
    
    configureWebpack: config => {
        if (isPro) {
            return {
                plugins: [
                    // 使用包分析工具
                    new BundleAnalyzerPlugin()
                ]
            }
        }
    },
    
    ...
}

然后在 http://127.0.0.1:8888/查看

二、查看代码的利用率

首先,我们介绍一种浏览器的工具使用:

我们打开浏览器控制台,然后ctrl + shift + p,输入showCover,然后出现下面这个界面:

然后点击上图黑色按钮:如下图,就会出现代码利用率的景象。

我们可以用这个来查看代码的利用率情况,这也是我们经常用来研究页面性能常用的工具。以后我们可以用代码覆盖率去优化我们的性能,而不是讲如何去做缓存了。

三、webpack中的懒加载

  • 懒加载,也称为按需加载,是一种可以提高网站初始响应速度的方式。
  • 在网站初次加载时,并不会加载全部代码,而是当用户完成某些特定操作后,才会引用新的代码块。

安装依赖:

"webpack": "^4.42.0",
"webpack-cli": "^3.3.11",
"lodash": "^4.17.15"

文件结构:

+ node_modules
+ src
 - index.js
+ dist
 - index.html

入口文件代码index.js:

import _ from 'lodash';

function getComponent() {
    var element = document.createElement('div');
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    return element;
}

document.addEventListener('click', () => {
    var element = getComponent();
    document.body.appendChild(element);
})

问题1:上面这种方法会很早的将getComponent()加载到页面中,如果代码一多就会造成卡顿的情况,如果是在首页加载,可能会造成白屏的状况,用户体验贼差,我们可以用懒加载(按需加载)的方式,也就是异步加载代码(需要异步的方法)的形式

懒加载的案例代码1:

setTimeout(()=>{
    // 也是一个chunk.js,加载后会是一个带数字的js文件
	import('./xxx.js').then(res => {
		// res就是import返回的数据
		console.log(res.data.message)
	})
}, 1500);

也可以让用户需要的时候再加载。

懒加载的案例代码2:

import _ from 'lodash';

//async返回的是一个promise对象
async function getComponent() {
    const _ = await import('lodash');
    var element = document.createElement('div');
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    // 返回值做为resolve的参数 
    return element;
}

// 懒加载
document.addEventListener('click', () => {
    // element就是上面return的资源
    getComponent().then((element) => {
        document.body.appendChild(element);
    })
})

 因为 lodash 模块仅在 getComponent 函数中使用,而 getComponent 函数仅在 click 事件后执行所以我们可以将加载 lodash 模块的代码放在 getComponent 函数当中这样,只有在发生点击事件之后,才会去加载 lodash 模块,从而达到按需加载的效果

我们也可以从下图中可以看到,在打开也买你中先不加载代码,而是在点击时候加载代码,从而提高代码的利用率。

问题2:懒加载是好的,但是当点击按钮时候或者每隔一段时间,才能下载相应页面的js文件,这就导致体验极其不好,每一次点击访问新页面都要等待js文件下载,然后再去请求接口获取数据。频繁出现loading动画的体验真的不好。那么我们可以使用prefetch方式,让代码在空闲时候加载出来,而不是点击某个按钮或者延迟时间

四、webpack中prefetch

我们在想,有没有一种方式让代码第一次加载时候就能达到最优,而不是利用缓存或是点击按钮时候下次加载才能提高访问的速度。

比如说下面这段代码:

// click.js
function handleClick() {
  const element = document.createElement('div');
  element.innerHTML = 'hansen';
  document.body.appendChild(element)
}

export default handleClick;
// index1.js

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

当点击document时候,实现异步加载,这种方式可以让一些代码可以慢点加载,在需要使用的时候再进行加载,这也是我们说的但是也会出现一个问题,比如,我们在使用vue做单页面开发时候,由于单页面应用页面过多,可能会导致代码体积过大,从而使得首页打开速度过慢。所以切分代码,优化首屏打开速度尤为重要。

所以如果我们在进入首页后,在浏览器的空闲时间提前下好用户可能会点击页面的js文件,这样首屏的js文件大小得到了控制,而且再点击新页面的时候,相关的js文件已经下载好了,就不再会出现loading动画。 

所以我们引入了prefetch,让文件可以在空闲时候加载,具体方法如下:在模块里面添加魔法注释/* webpackPrefetch: true */

// index1.js

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

这样子,0.js会在空闲时候被加载,注意:0.js只是被加载,没有被利用

当点击document时候,0.js被加载出来,他只需要1ms钟了,是不是更快了呢。

说到了这里应该就结束了吧,小伙伴会问,Proload还没说呢!哈哈,你们可细心,那这里就介绍下proload,Preload是和父级元素并行加载的,可以被立即使用,通常用于本页面要用到的关键资源。如果使用webpack打包,他也是通过在import模块中添加魔法注释就可以了,像这样子/* webpackPreload: true */。其实有时候,我们可以直接将preload和prefetch用于link标签使用。


附加

我们可以把Preload和Prefetch直接写在link标签上:

1.Preload

<link rel=“preload”> 

preload 提供了一种声明式的命令,让浏览器提前加载指定资源(加载后并不执行),需要执行时再执行

这样做的好处在于:

  1. 将加载和执行分离开,不阻塞渲染和document的onload事件
  2. 提前加载指定资源,不再出现依赖的font字体隔了一段时间才刷出的情况

preload通常用于本页面要用到的关键资源,包括关键js、字体、css文件。preload将会把资源得下载顺序权重提高,使得关键数据提前下载好,优化页面打开速度。

2.prefetch

<link rel=“prefetch”>

这段代码告诉浏览器,这段资源将会在未来某个导航或者功能要用到,但是本资源的下载顺序权重比较低。也就是说prefetch通常用于加速下一次导航,而不是本次的,比如下一个页面会用到的资源,点击事件后弹出model框等等。

被标记为prefetch的资源,将会被浏览器在空闲时间加载。

Preload和Prefetch的区别

下面是Preload和Prefetch的区别吧:

  • 一个预加载块(preload)开始与父块并行加载。预取的块(prefetch)在父块完成加载后启动。
  • 预加载块(preload)具有中等优先级,可以立即下载。而预取块(prefetch)在浏览器空闲时下载预取的块。
  • 一个预加载的块(preload)应该被父块立即请求。预取的块(prefetch)可以在将来的任何时候使用。
  • 浏览器的支持能力是不同的。

虽然说prefetch或者是preload好,但是我们千万要记得,不要所有的异步加载模块都使用这个东西,我们应该根据自己的业务去加载,否则页面性能不是达到最优而是长时间的等待加载。

总结:

不管懒加载还是预加载,只有适合自己,适合业务的才是最好的!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值