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

webpack性能优化(1):分隔/分包/异步加载+组件与路由懒加载的更多相关文章

  1. vue3 + vite实现异步组件和路由懒加载

    在 Vue2 中,异步组件和路由懒加载处理使用 import 就可以很轻松实现.但是在Vue 3.x 中异步组件的使用与 Vue 2.x 完全不同了.本文就详细讲讲vue3中异步组件和路由懒加载的实现 ...

  2. 【巷子】---vue路由懒加载---【vue】

    一.懒加载 也叫延迟加载或者按需加载,即在需要的时候进行加载,   二.为什么要使用懒加载 像vue这种单页面应用,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要 ...

  3. vue路由懒加载及组件懒加载

    一.为什么要使用路由懒加载 为给客户更好的客户体验,首屏组件加载速度更快一些,解决白屏问题. 二.定义 懒加载简单来说就是延迟加载或按需加载,即在需要的时候的时候进行加载. 三.使用 常用的懒加载方式 ...

  4. VUE的路由懒加载及组件懒加载

    一,为什么要使用路由懒加载 为给客户更好的客户体验,首屏组件加载速度更快一些,解决白屏问题 二,懒加载简单来说就是延迟加载或按需加载,即在需要的时候的时候进行加载 三,常用的懒加载方式有两种:即使用v ...

  5. vue-router路由懒加载

    正常配置 import Vue from 'vue' import Router from 'vue-router' import Login from '@/components/pages/log ...

  6. webpack 性能优化 dll 分包

    webpack 性能优化 dll 分包 html-webpack-externals-plugin DLLPlugin https://www.webpackjs.com/configuration/ ...

  7. webpack性能优化——DLL

    Webpack性能优化的方式有很多种,本文之所以将 dll 单独讲解,是因为 dll 是一种最简单粗暴并且极其有效的优化方式. 在通常的打包过程中,你所引用的诸如:jquery.bootstrap.r ...

  8. vue项目性能优化(路由懒加载、gzip加速、cdn加速)

    前端工程性能优化一说意义深远悠长,本章主要介绍除了一些基础优化外如何实行路由懒加载.Gzip加速.CDN加速,让网页飞的快一些. 基础优化 老生常谈的一些: 不要在模板中写复杂的表达式 慎用watch ...

  9. vue-cli3项目首页加载速度优化(cdn加速,路由懒加载,gzip压缩)

    今天打算上线vue的单页面项目,上线后,首页加载速度巨慢! 原因是项目上线后,网速不够快,加载js,css等资源很慢, 打开打包好的文件发现chunk-vendors.xxxxxxx.js的包很大,达 ...

  10. 在webpack中使用Code Splitting--代码分割来实现vue中的懒加载

    当Vue应用程序越来越大,使用Webpack的代码分割来懒加载组件,路由或者Vuex模块, 只有在需要时候才加载代码. 我们可以在Vue应用程序中在三个不同层级应用懒加载和代码分割: 组件,也称为异步 ...

随机推荐

  1. Windows虚拟机环境下Linux设置固定IP地址

    Linux 设置固定IP地址 安装环境是VMware Workstation Pro 15 安装完linux之后需要做的第一件事就是配置网络,有了网络我们可以下载插件,使用xshell工具连接等等 i ...

  2. git报错fatal: unable to access 'https://github.com/hxx.git/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443

    今天拉git代码报错 弄好了,下面是解决方法: 在网上查了很多办法都没有解决,有的方法是https连接模式改成ssh模式,或者是修改代理,比如: git config --global http.pr ...

  3. go 中的循环依赖

    什么是循环依赖 Go 中的循环依赖是指两个或多个包之间相互引用,形成了一个循环依赖关系.这种情况下,包 A 依赖包 B,同时包 B 也依赖包 A,导致两个包之间无法明确地确定编译顺序,从而可能引发编译 ...

  4. GitHub 术语解释

    为了大家进一步了解和使用 GitHub,在本文中,我们一起来看看 GitHub 的常用术语,也可以说是基本概念: Repository:简称Repo,可以理解为"仓库",我们的项目 ...

  5. C# 12 Blazor入门教程

    Blazor简介 Blazor 是由Microsoft开发的一款基于.NET的开源交互式Web UI框架.Blazor使开发人员能够使用C#和HTML建立全堆栈的单页应用程序,并避免使用JavaScr ...

  6. Codeforces Round #696 (Div. 2) (A~C题解)

    写在前边 链接:Codeforces Round #696 (Div. 2) A. Puzzle From the Future 链接:A题链接 题目大意: 给定一个\(a\),\(b\),\(d = ...

  7. Android Sutdio 编入System API 等隐藏API 方法

    1. 将 classes.jar 放入 app/libs 文件夹下 右键点击 jar 包,点击 Add as Library 2. 项目级 Gradle 文件新增以下配置 gradle.project ...

  8. C++ MiniZip实现目录压缩与解压

    Zlib是一个开源的数据压缩库,提供了一种通用的数据压缩和解压缩算法.它最初由Jean-Loup Gailly和Mark Adler开发,旨在成为一个高效.轻量级的压缩库,其被广泛应用于许多领域,包括 ...

  9. 用友NCC&WMS&泛微 系统对接案例分享

    用户故事 产品版本:NCC2105 故事是这么开始的,用友全国伙伴社区的社区成员,对我们的多系统集成架构很感兴趣,经常跟我讨论相关系统集成层面的问题:随着企业的发展,由于信息产业的技术含量高,信息系统 ...

  10. 关于fstream对象的open方法报错183的问题

    当使用fstream,ifstream,ofstream,这几种对象打开文件, 但文件已经存在的时候, 调用GetLastError()函数,会返回错误代码183, 这个代码代表该文件已经存在,是正常 ...