首页 > 其他分享 >webpack性能优化(1):分隔/分包/异步加载+组件与路由懒加载

webpack性能优化(1):分隔/分包/异步加载+组件与路由懒加载

时间:2023-03-18 19:04:51浏览次数:52  
标签:异步 js webpack 组件 import 加载

webpack ensure相信大家都听过。有人称它为异步加载,也有人说做代码切割,那这个家伙到底是用来干嘛的?其实说白了,它就是把js模块给独立导出一个.js文件的,然后使用这个模块的时候,webpack会构造script dom元素,由浏览器发起异步请求这个js文件。

这样解决整个项目打包成同一个非常大js、css,首屏加载慢。其实和我们加载百度统计代码类似, 把一些js模块给独立出一个个js文件,然后需要用到的时候,在创建一个script对象,加入到document.head对象中即可,浏览器会自动帮我们发起请求,去请求这个js文件,在写个回调,去定义得到这个js文件后,需要做什么业务逻辑操作。

什么是懒加载

懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。

当页面中一个文件过大并且还不一定用到的时候,我们希望在使用到的时才开始加载,这就是按需加载。要实现按需加载,我们一般想到的方法:动态创建script标签,并将src属性指向对应的文件路径

为什么需要懒加载

在单页应用中,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,延时过长,不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载时间

实现过程中存在的问题:

  • 怎么保证相同的文件只加载一次?
  • 怎么判断文件加载完成?
  • 文件加载完成后,怎么通知所有引入文件的地方?

webpcak 的按需加载已经完美解决了上述问题,但如何与webpack配合实现组件懒加载?

如何与webpack配合实现组件懒加载

webpack chunk 流

webpack配置文件中的output路径配置chunkFilename属性

output: {
path: resolve(__dirname, 'dist'),
filename: '[name].js?[chunkhash]',
chunkFilename: '[name].js?[hash:5]',
publicPath: '/assets/'
},

chunkFilename路径将会作为组件懒加载的路径

webpack支持的异步加载方法

System.import(); 

已废除,不推荐——webpack2官网上已经声明将逐渐废除

() => system.import(URL)

() => import(URL)

需要webpack > 2.4,v1不支持——webpack2官网推荐使,官方文档​​webpack中使用import()​​, 属于es7范畴,

require是由webpack社区提供方案,import为es官方提供;

如果遇到使用import 报错,需要安装babelrc, 需要配合babel的syntax-dynamic-import插件使用, 具体使用方法如下

npm install --save-dev babel-core babel-loader babel-plugin-syntax-dynamic-import babel-preset-es2015

webpack babel-loader 需要配置

use: [{
loader: 'babel-loader',
options: {
presets: [['es2015', {modules: false}]],
plugins: ['syntax-dynamic-import']
}
}]

使用如下

//导入整个模块
import('./component').then(Component => /* ... */);
//使用await
async function determineDate() {
const moment = await import('moment');
return moment().format('LLLL');
}
determineDate().then(str => console.log(str));

vue-router配置路由:vue官方文档:​​路由懒加载(使用import())​

{
path: '/',
component: () => import('../pages/home.vue'),
meta: {
title: 'home'
}}


require.ensure

require.ensure([…modules],()=>{}[,errorCallBack[,chunkName]]);

v1和v2均可使用

require.ensure([], function() {
var module = require('../../jsLib/module');
//do something
})

require方式可以将多个模块js组合分割打包,

require下面方法ensure第一个参数是依赖,如果不需要请写[](空数组)

而import只能将每个模块独立打包成一个js文件;

也就是说,如果现在有三个导航A、B、C,你现在用require可以将A单独分割出来做懒加载,进入a模块只请求A,B和C你可以组合在一起进行分割,进入B和C将加载共同一个文件;

component: resolve => require(['../pages/home.vue'], resolve)

vue-router配置路由,使用webpack的​​require.ensure​​技术,也可以实现按需加载。

{
// 进行路由配置,规定'/'引入到home组件
path: '/',
component: resolve => require(['../pages/home.vue'], resolve),
meta: {
title: 'home'
}}

这是异步加载组件,当你访问 / ,才会加载 home.vue。

对于vue的路由配置文件(routers.js)

  • 用import引入的话,当项目打包时路由里的所有component都会打包在一个js中,造成进入首页时,需要加载的内容过多,时间相对比较长。
  • 当用require这种方式引入的时候,会将你的component分别打包成不同的js,加载的时候也是按需加载,只用访问这个路由网址时才会加载这个js。

你可以打包的时候看看目录结构就明白了。 

  • require: 运行时调用,理论上可以运用在代码的任何地方,
    import:编译时调用,必须放在文件开头

router中实现懒加载

vue的单页面(SPA)项目,必然涉及路由按需的问题

路由中配置异步组件

export default new Router({
routes: [
{
mode: 'history',
path: '/my',
name: 'my',
component: resolve =>require(['../page/my/my.vue'], resolve),//懒加载
},
]
})


实例中配置异步组件

components: {
historyTab: resolve => {require(['../../component/historyTab/historyTab.vue'], resolve)},//懒加载
//historyTab: () => import('../../component/historyTab/historyTab.vue')
},


全局注册异步组件

Vue.component('mideaHeader', () => {
System.import('./component/header/header.vue')
})


关于webpack异步加载的问题

  • 多次进出同一个异步加载页面是否会造成多次加载组件?在多个地方使用同一个异步组件时是否造成多次加载组件?
    否,首次需要用到组件时浏览器会发送请求加载组件,加载完将会缓存起来,以供之后再次用到该组件时调用
  • 如果在两个异步加载的页面中分别同步与异步加载同一个组件时是否会造成资源重用?
    会, 将会造成资源重用, 根据打包后输出的结果来看, a页面中会嵌入historyTab组件的代码, b页面中的historyTab组件还是采用异步加载的方式, 另外打包chunk;在协同开发的时候全部人都使用异步加载组件
  • 异步加载页面中载嵌入异步加载的组件时对页面是否会有渲染延时影响?
    会, 异步加载的组件将会比页面中其他元素滞后出现, 页面会有瞬间闪跳影响;因为在首次加载组件的时候会有加载时间, 出现页面滞后, 所以需要合理的进行页面结构设计, 避免首次出现跳闪现象;


只要文章:

VUE2组件懒加载浅析 ​​https://www.cnblogs.com/zhanyishu/p/6587571.html​

解析 Webpack中import、require、按需加载的执行过程 ​​https://segmentfault.com/a/1190000013630936​

揭秘webpack按需加载原理 ​​https://zhuanlan.zhihu.com/p/159216534​

vue项目实现按需加载的3种方式:vue异步组件、es提案的import()、webpack的require.ensure() https://segmentfault.com/a/1190000011519350

​https://webpack.js.org/guides/code-splitting/​


转载​​本站​​文章《​​webpack性能优化(1):分隔/分包/异步加载+组件与路由懒加载​​》,
请注明出处:​​https://www.zhoulujun.cn/html/tools/Bundler/webpackTheory/8384.html​

标签:异步,js,webpack,组件,import,加载
From: https://blog.51cto.com/zhoulujun/6129738

相关文章

  • webpack性能优化(2):splitChunks用法详解
    之前写的《​​webpack性能优化(0):webpack性能优化概况-优化构建速度​​​》、《​​webpack性能优化(1):分隔/分包/异步加载+组件与路由懒加载​​》如果使用vue-cli,默认......
  • vue2升级vue3:vue-i18n国际化异步按需加载
    vue2异步加载之前说过,vue3还是之前的方法,只是把 i18n.setLocaleMessage改为i18n.global.setLocaleMessage但是本文还是详细说一遍:为什么需要异步加载语言包主要还是缩......
  • webpack原理(2):ES6 module在Webpack中如何Tree-shaking构建
    Tree-shaking最早由打包工具Rollup 提出DCE作用于模块内(webpack的DCE通过UglifyJS完成),而Tree-shaking则是在打包的时候通过模块之间的信息打包必须的代码。We......
  • webpack原理(3):Tapable源码分析及钩子函数作用分析
    webpack本质上是一种事件流的机制,它的工作流程就是将各个插件串联起来,而实现这一切的核心就是Tapable,webpack中最核心的负责编译的Compiler和负责创建bundles的Compilation......
  • React 实现 动态加载组件
    React实现动态加载组件import{Button}from'antd'importReact,{useState,lazy,Suspense}from'react'//这个地方动态加载组件constItem=lazy(()=>i......
  • webpack原理(1):Webpack热更新实现原理代码分析
    热更新,主要就是把前端工程文件变更,即时编译,然后通知到浏览器端,刷新代码。服务单与客户端通信方式有:ajax轮询,EventSource、websockt。客户端刷新一般分为两种:整体页......
  • java类加载器有哪些
    java类加载器有:1、引导类加载器;2、拓展类加载器;3、系统类加载器;4、用户自定义类加载器。其中,引导类加载器(BoostrapClassLoader),又叫启动类加载器,由原生代码(如C语言)编写,不......
  • java类加载器有哪些
    java类加载器有:1、引导类加载器;2、拓展类加载器;3、系统类加载器;4、用户自定义类加载器。其中,引导类加载器(BoostrapClassLoader),又叫启动类加载器,由原生代码(如C语言)编写,不......
  • 请你详细说说类加载流程,类加载机制及自定义类加载器
    当程序使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载、链接、初始化三个步骤对该类进行类加载。加载类加载指的是将类的class文件读入内存,并为之创建一个java.......
  • 类加载器(Java)
    类加载器类加载的过程类加载器的功能将.class文件【物理文件:在硬盘中】加载到Java虚拟机的内存中【搬用工】。类加载的时机情况分析://1,当创建Fu对象的时候【Fu.class......