参考视频 文章:
http://www.woc12138.com/article/45
https://segmentfault.com/a/1190000006178770
https://mp.weixin.qq.com/s?__...
https://www.jianshu.com/nb/45770544
webpack
简介
webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler)。
在webpack 看来, 前端的所有资源文件(js/json/css/img/less/...)都会作为模块处理。
它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)。
5个核心
Entry入口:指示 webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图,trunk。
Output输出:指示 webpack 打包后的资源 bundles 输出到哪里去,以及如何命名。
翻译:让 webpack 能够去处理那些非 JS 的文件,比如样式文件、图片文件(webpack 自身只理解JS)
Plugins插件:对象,
可以用于执行范围更广的任务。插件的范围包括从打包优化和压缩,一直到重新定义环境中的变量等,相当于钩子函数。
Mode模式:指示 webpack 使用相应模式的配置,development开发模式和production生产模式。
loader:函数,在构建过程中,文件转换器,文件转换的工作;a.less=>a.css
webpack的安装
webpack 打包原理
先递归识别依赖,构建依赖图谱
把代码转换成 AST 抽象语法树
在 AST 中去处理代码
将 AST 抽象语法树变成浏览器可以识别的代码并输出
https://github.com/bestCindy/mini-webpack/blob/main/README.md
webpack打包过程
识别入口文件
通过逐层识别模块依赖。(Commonjs、amd或者es6的import,webpack都会对其进行分析。来获取代码的依赖)
webpack做的就是分析代码。转换代码,编译代码,输出代码
最终形成打包后的代码
https://segmentfault.com/a/1190000020266246
(一)将代码转换成 AST 抽象语法树
利用 babel-parser 转换
代码在 convertToAST.js 文件中
(二)找到依赖关系
利用 traverse 遍历 AST 抽象语法树
找到文件的依赖关系
代码在 convertToDependency.js 里面
(三)将抽象语法树转换成浏览器可以运行的代码
代码在 convertToCode.js 里面
(四) 遍历 dependencies 找到所有的依赖获取依赖图谱
代码在 makeDependenciesGraph.js 里面
(五)生成代码
代码在 generateCode.js 里面
webpack编译过程
https://www.jianshu.com/p/99ecc9209bfb
https://www.jianshu.com/p/01e9b0414553
webpack生命周期
准备工作
@babel/parser: 分析我们通过 fs.readFileSync 读取的文件内容,返回 AST (抽象语法树)
@babel/traverse: 可以遍历 AST, 拿到必要的数据
@babel/core: babel 核心模块,其有个transformFromAst方法,可以将 AST 转化为浏览器可以运行的代码
@babel/preset-env: 将代码转化成 ES5 代码
ast抽象语法树:
https://juejin.cn/post/6844903727451602951
词法分析:将每项拆开。
语法分析:根据逻辑关系把token流合起来
Vue-loader 插件VueLoaderPlugin
vue2中的build 和config 文件夹用来配置webpack
loader plugin优化
是什么 有什么区别
手写loader
babel
Babel 是什么:是一个 JavaScript 编译器
Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
能做什么:
语法转换
通过 Polyfill 方式在目标环境中添加缺失的特性 (通过 @babel/polyfill 模块)
源码转换 (codemods)
babel-loader
babel-loader:加载babel的
babel-loader在执行的时候,可能会产生一些运行期间重复的公共文件,造成代码体积冗余,同时也会减慢编译效率。
https://huangxsu.com/2018/08/12/webpack-optimization/
限制范围:
限制 loader 只处理特定的目录, babel-loader,include
noParse (该模块中不应该含有 import,require,define)
加快解析(resolve)速度,extensions不要加太多,常出现的放在前面
babel-polyfill垫片
tree shaking
作用: webpack2增加tree-shaking,tree shaking 摇晃 a module引入了Bmodule,将用不到的代码摇掉 不适用的代码 不打包进去
原理:消除无用的js代码,编译器可以判断某些代码不影响输出,是DCE的一种新的实现
在前端使用UglifyJS,核心是ES6 module嵌套引用关系
tree-shaking的消除原理利用ES6模块特性
ES6 modules去除掉多余代码
commonjs按需加载
webpack5
rollup babel+webpack打包
UglifyJS:代码压缩优化工具,是 tree shaking 删除代码的核心
Uglify没有完善的程序流分析
rollup有程序流分析
babel导致产生副作用代码
webpack:不支持导出ES模式
rollup:打包工具库 组件库 支持ES模块 问题:生态不行
manifestPlugin:判断文件入口
webpack的 plugin机制
拆包
不要改全局的东西
vue2 rollup
先打包后编译
Dllplugin
scope hoisting
实现原理: 分析出模块之间的依赖关系,尽可能的把打散的模块合并到一个函数中去,但前提是不能造成代码冗余。因此只有那些被引用了一次的模块才能被合并。
code splitting拆分代码
code splitting作用: 拆分代码,优化相关配置
webpack优化,怎么做:
Entry Points:多入口分开打包
Prevent Duplication: 抽离第三方库vander,webpack去除重复引用是通过commonsChunkPlugin插件来实现
再抽离重复组件。
Dynamic Imports:动态加载
commonsChunkPlugin在webpack4不使用了。
minchunks
自动化分离vender
code splitting 和 chunks
chunk:打包后的东西
拆分然后再重新放在一起
旧版的问题:没法区分父子级,找到对应关系
所以新的chunk图引入一个新对象 chunkGroups,一个chunkGroups包含多个chunk
新插件 SplitChunksPlugin
设置cacheDirectory为true
HappyPack不更新了,thread-loader
HappyPack 可以让 Webpack 同一时间处理多个任务,发挥多核 CPU 的能力,将任务分解给多个子进程去并发的执行,子进程处理完后,再把结果发送给主进程。通过多进程模型,来加速代码构建。
thread-loader
webpack4官方推荐
webpack热更新
https://juejin.cn/post/6844904008432222215#heading-13
二、webpack的编译构建过程
实现原理
- webpack-dev-server启动本地服务
- 修改webpack.config.js的entry配置
- 监听webpack编译结束
- webpack监听文件变化
- 浏览器接收到热更新的通知
- HotModuleReplacementPlugin
- moudle.hot.check 开始热更新
- hotApply 热更新模块替换
①删除过期的模块,就是需要替换的模块
②将新的模块添加到 modules 中
③通过__webpack_require__执行相关模块的代码
webpack性能优化的方式
缓存:
1. 大部分babel-loader解决,在babel-loader中,可以通过设置 cacheDirectory 来开启缓存。 2. loader 不支持缓存,可以使用cache-loader
多核 / 多进程:
1. happypack 分解成多个子进程并发执行 2. 一般都会提供 parallel 这样的配置项供你开启多核编译
抽离
1. 一种是使用 webpack-dll-plugin 的方式,在首次构建时候就将这些静态依赖单独打包,后续只需要引用这个早就被打好的静态依赖包即可,有点类似“预编译”的概念;
问题:
另一种,也是业内常见的Externals的方式,我们将这些不需要打包的静态资源从构建逻辑中剔除出去,而使用 CDN 的方式,去引用它们。
拆分
1. docker,虚拟物理机
压缩代码
优化网站性能有哪些方法?
合并js,合并css,图片sprite,图片压缩
延迟加载内容:图片懒加载,数据懒加载
使用离线缓存,移动端可以把变动少的js,css存在本地
css,js放置位置
减少http请求
骨架屏
首页加载性能优化,提升页面性能:
减少包大小 :webpack打包优化,treeshaking uglify优化,按需加载。
加快http请求速度:cdn :雪碧图, 大图, 第三方插件连接
页面放置顺序:css,js
减少页面重排重绘
服务器端渲染,接口响应慢等问题
延伸:骨架屏 预渲染 懒加载
打包优化:使用缓存,多线程打包,减少文件搜索范围,
从输入URL到页面呈现?
DNS解析:
TCP连接
发送HTTP请求
服务器响应:
webpack优化: happypack,tree shaking
浏览器解析页面
CDN
https://juejin.cn/post/6844903906296725518
内容分发网络,全国各地都有这个配置。类似菜鸟的仓配网络。
解决分布 带宽 分布的问题。预先做好分发
CDN : 缓存和回源
使用CDN镜像
多个服务器
使用CDN缓存,
CDN网络
修改DNS解析
全局负载均衡
DNS解析,得到
CDN关键技术:
缓存算法
分发能力
负载均衡(nginx),智能调用
基于DNS
支持协议,图片加速
访问量大的网络需要CDN,
缺点:
请求 CDN专用的DNS服务器
根据用户IP地址,
服务器节点:
边缘节点:
CND网络组成:中心节点、边缘节点
中心节点:总仓
边缘节点:异地分发节点,由负载均衡设备,
搭建CDN相关技术:
内容发布
内容存储
内容路由: 路由重定向,DNS机制
内容管理:
访问cdn和不通过cdn访问
cname过程
回源:
找自己的服务器
除了静态资源 api是否可以缓存
第三方库使用cdn加载
资源过期如何判断 cdn是如何更新数据的
主动push 被动pull
从服务器主动往cdn推送数据
webpack 变量提升 缓存 强缓存 协商缓存
预加载 预渲染
DNS域名解析,DNS预解析
www.sunhao.win.根域
权威域.顶级域.根域
根域名 www.sunhao.win.根域 根域不显示
dns主要通过
udp
顶级域和顶级服务器
win所在的位置就是顶级域
国家顶级域名
通用顶级域名
xx
权威DNS和权威域名服务器
运营商DNS服务器和本地DNS服务器
递归查询:主机向本机服务器查询
迭代查询:
cname别名指向: 解析域名到域名
解决请求严重延时的现象,使用dns预解析。
des-prefetch,多页面重复DNS预解析会速度
浏览器缓存
DNS Prefetching 技术
DNS域名解析过程:
查找浏览器缓存
查找系统缓存
查找路由器缓存
查找ISP DNS缓存
递归搜索
DNS安全问题
DNS欺骗:更改IP地址
拒绝服务攻击
分布式拒绝服务攻击
缓冲区漏洞溢出攻击
DNS网络性能优化
减少DNS查找,避免重定向
- DNS预解析