angular惰性加载拓展剖析
最近把一个比较旧的业余项目重新升级了下,将主文件进行了剥离,增加了些惰性加载的配置,将过程中一些零散的知识点做个总结,同时尽量深入原理实现层面。
项目环境:
前端框架:angular2.0.0-beta.21
构建工具:webpack4.11.0
加载惰性模块:
跑了下环境,再次验证了每次回头看以前自己写的东东的时候都会不能忍这一潜在的法则,发现首屏的加载事件竟然超过了1s,于是果断切割主资源包,进行按需加载
如果使用angular-cli命令工具,该需求基本自动化实现,只需要在对应的路由下配置需要懒加载的模块即可,其他工作如模块的异步加载等,cli会进行自动处理,如下所示
const routes: Routes = [
{
path: 'customers',
loadChildren: './customers/customers.module#CustomersModule'
}
];
但是一直偏向于自己构建脚手架,不喜欢拿来即用,看了下angular-cli的源码,其实也是基于webpack构建(部分配置如下),只是没看到其中异步加载模块和output输出中模块语义化的实现过程。只能自己实现模块的异步加载,解决“can not find module...”报错。
{
resolve: {
extensions: ['.ts', '.js'],
symlinks: !buildOptions.preserveSymlinks,
modules: [appRoot, 'node_modules'],
alias
},
resolveLoader: {
modules: loaderNodeModules
},
context: projectRoot,
entry: entryPoints,
output: {
path: path.resolve(buildOptions.outputPath),
publicPath: buildOptions.deployUrl,
filename: `[name].bundle.js`,
chunkFilename: `[id]${hashFormat.chunk}.chunk.js`
},
module: {
rules: [
{ test: /\.html$/, loader: 'raw-loader' },
{
test: /\.(eot|svg|cur)$/,
loader: 'file-loader',
options: {
name: `[name]${hashFormat.file}.[ext]`,
limit: 10000
}
},
{
test: /\.(jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
loader: 'url-loader',
options: {
name: `[name]${hashFormat.file}.[ext]`,
limit: 10000
}
}
].concat(extraRules)
},
plugins: [
new webpack.NoEmitOnErrorsPlugin()
].concat(extraPlugins)
}
查阅webpack文档,找到一个内置的ensure方法可实现模块异步,使用如下
require.ensure(dependencies: String[], callback: function(require), errorCallback: function(error), chunkName: String)
dependencies:字符串构成的数组,声明 callback 回调函数中所需的所有模块。
callback:只要加载好全部依赖,webpack 就会执行此函数。require 函数的实现,作为参数传入此函数。当程序运行需要依赖时,可以使用 require() 来加载依赖。函数体可以使用此参数,来进一步执行 require() 模块
errorCallback:当 webpack 加载依赖失败时,会执行此函数。
chunkName:由 require.ensure() 创建出的 chunk 的名字。通过将同一个 chunkName 传递给不同的 require.ensure() 调用,我们可以将它们的代码合并到一个单独的 chunk 中,从而只产生一个浏览器必须加载的 bundle
将方法应用到路由模块,代码如下:
export const routes: Routes = [
{
path: 'course',
loadChildren: () => new Promise(resolve => {
(require as any).ensure(
[],
require => {
resolve(require('../course/module').CourseModule);
},
'haha'
);
})
}
];
该方法基于浏览器内置promise对象,如果需要兼容多种环境,最好增加polyfill库来填充promise环境
最后
如果不想在路由模块写异步方法,也可以引入一些封装好的插件实现,如es6-promise-loader、angular2-load-children-loader,但其实也没有本质的变化,只不过稍做封装而已,意义不大,具体usage可github查看
先搞这些,依赖包升级乃至换个环境重写等下次再有闲情哈!!
angular惰性加载拓展剖析的更多相关文章
- Angular惰性加载的特性模块
一:Angular-CLI建立应用 cmd命令:ng new lazy-app --routing (创建一个名叫 lazy-app 的应用,而 --routing 标识生成了一个名叫 app- ...
- Angular2 ng2 如何配置惰性加载
需要修改至少四个地方1. 将子组件进行模块化操作2.生成子组件module .子组件router3.配置主路由 信息 改为loadChild4.配置appModule 删除引入 以product组件 ...
- 关于angular5的惰性加载报错问题
之前为了测试一个模块优化问题,于是用angular-cli快速搭建了个ng5的脚手架demo,在应用惰性加载功能的时候发现浏览器报错如下: ERROR Error: Uncaught (in prom ...
- angular懒加载的一些坑
写在前面 最近在工作中接触到angular模块化打包加载的一些内容,感觉中间踩了一些坑,在此标记一下. 项目背景: 项目主要用到angularJs作为前端框架,项目之前发布的时候会把所有的前端脚本打包 ...
- 推荐一个 angular 图像加载插件
推荐一个简单的 Angular 图片加载插件:vgSrc,插件根据图片资源的不同加载状态,显示不同图片,亲测兼容IE-8. 使用 推荐使用 bower 加载: bash bower install v ...
- PDF在线阅读 FlexPaper 惰性加载 ;
关于PDF在线阅读问题,比较普遍的做法是转换成swf文件来浏览:由于项目需要,就用 flexpaper 来实现了下,功能比较简单:但是文件的惰性加载确实让笔者挠头了一把! 下面是笔者的方法: 采用流的 ...
- Angular - 预加载 Angular 模块
Angular - 预加载延迟模块 在使用路由延迟加载中,我们介绍了如何使用模块来拆分应用,在访问到这个模块的时候, Angular 加载这个模块.但这需要一点时间.在用户第一次点击的时候,会有一点延 ...
- 雷林鹏分享:jQuery EasyUI 树形菜单 - 树形网格惰性加载节点
jQuery EasyUI 树形菜单 - 树形网格惰性加载节点 有时我们已经得到充分的分层树形网格(TreeGrid)的数据. 我们还想让树形网格(TreeGrid)按层次惰性加载节点. 首先,只加载 ...
- angular 图片加载失败 情况处理? 如何在ionic中加载本地图片 ?
1.angular 图片加载失败 情况处理 在directive中定义组件,在ng-src错误时,调用err-src app.directive('errSrc',function(){ return ...
随机推荐
- 187. Repeated DNA Sequences(建立词典,遍历一遍 o(n))
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACG ...
- cc150 --链表分割
题目描述 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 给定一个链表的头指针 ListNode* pHead,请返回重新排列后的链表的头指针.注意:分割以后 ...
- testng使用DataProvider+Excel实现DDT
DDT,即数据驱动测试 Data Driver Test,我曾经记录了一篇关于python的DDT框架(Excel+DDT数据驱动实例),那么java中的DDT是怎么样的呢?在java中,可以用tes ...
- 《算法C语言实现》————三道题目
1.对于N = 10,100和1000,记录你的运行环境中分别运行一下程序所花费的时间.(用python) import datetime global a a = 0 def time_1(s): ...
- CAScrollLayer
CAScrollLayer 对于一个未转换的图层,它的bounds和它的frame是一样的,frame属性是由bounds属性自动计算而出的,所以更改任意一个值都会更新其他值. 但是如果你只想显示一个 ...
- Linux命令: 替换字符串
敲命令按以下顺序 ①vim filename ②e ③i ④ESC 1 :s/str1/str2 把当前行的第一个str1替换成str2 2 :s/str1/str2/g 把当 ...
- MySQL数据库----数据锁
数据锁 需求: 有一个账户,两个人在同一时间要对此账户操作,A要对账户充值100块,B要从账户中取出100块.操作前都要先看一下账户的 余额然后再操作. -- 窗口1 用户进行充值 -- 充值前 先查 ...
- P2322 [HNOI2006]最短母串问题
P2322 [HNOI2006]最短母串问题 AC自动机+bfs 题目要求:在AC自动机建的Trie图上找到一条最短链,包含所有带结尾标记的点 因为n<12,所以我们可以用二进制保存状态:某个带 ...
- django 项目中使用多数据库 multiple databases
假如在一个django项目中使用到了不只一个数据库, 其实这在大一点的工程中很常见,比如主从库 那么会涉及到如下一些东西 1, 定义 在settings中的DATABASE中定义会使用到的数据,比如除 ...
- Android实践项目汇报(总结)-修改
天气客户端开发报告 1系统需求分析 1.1功能性需求分析 天气预报客户端,最基本就是为用户提供准确的天气预报信息.天气查询结果有两种:一种是当天天气信息,信息结果比较详细,除温度.天气状况外还可以提示 ...