frontendmasters Web Performance
2018-11-09 本文已影响0人
云峰yf
Web Performance with Webpack
Top Performance Issues
- 应用程序加载需要多长时间?还是交互有多快?
- 初始下载时必须下载的 Javascript 数量、以同样的方式获得 CSS 的数量、所发送的并发网络请求数量。
Performance Goals
- JS 200KB 以内
- CSS 100KB 以内
- HTTP2 的使用
- 代码的覆盖范围
Code Coverage
- chrome 调试面板 Shift + Cmd + P
- 首屏体验并不需要那么多代码
Code Splitting
- Google Web Toolkit 先驱
- webpack 零配置代码分割,将在构建步骤中创建这些惰性包。
- 在构建时,单独的 JavaScript 块只会异步加载。
Types of Code Splitting
- 动态 import 语法,浏览器还在提案中,但 webpack 已经实现
- 动态和静态代码拆分
- webpack 中没有任何内容纯粹是动态的。不同的只是构建时间。
- 懒加载才是正确的路子
Code Splitting Demonstration
- 代码拆分过程实际上是调用该模块并将其加载到此处
- webpack 在你使用动态 import 会返回一个 promise
Webpack Code Splitting Under the Hood
- 首先有一个 webpackJsonpCallback 函数,拿到一些数据,这些数据将是一个数组。而且它将通过我们称之为 chunkIds,或者是模块。
- 之后有一个模块缓存和一个 chunk 缓存,它会为已安装的块设置初始 ID。
-
__webpack_require__.e
实现了懒加载转换,实际设置了一个 JSONP 请求去请求 chunk,可能是一个数组,所以需要 Promise.all - 有一个名为 webpackJsonp 的单个全局变量,默认为数组,它是块缓存的实际注册其他块的地方。
- 因此,每当我们进行懒加载时,我们只是访问已经异步分离为单独文件的模块。
Load a Heavy Module Asynchronously
- 对重型库使用 eval 作为源映射,它实际上被分离到每个单独的文件中。
- 减少初始代码加载量
Code Splitting in Vue, React, & Frameworks
- vue 一行代码就实现
- react react-loadable
- Angular 组件级别坑爹,路由级别还行
- Preact 提了一嘴
Code Splitting Named Exports
- 命名或默认导出失去了 tree-shaking 异步 bundle 的能力
- 例子中从 lodash 访问一个函数,直接从路径中去访问
Vendor Bundles are an Anti Pattern
- webpack4 抛弃 commonChunk 的原因,也是认为这是反模式
- vendor 会增加解析 js 代码的成本
- 异步 bundle 也许是个更好的解决办法
Dynamic Code Splitting
- 将一个变量赋给一个返回动态导入的函数,从而动态加载某些东西,这就是动态代码拆分
- 但肖恩的态度是避免这种方式:ContextModule 决定了这些模块仍然是静态的。
- 所以 webpack 会发出一个警告,当你尝试只使用一个变量时它就不会起作用。
Dynamic Code Splitting Walkthrough
- 写了一个例子 0501 分支
- 实际上并不需要任何其他延迟加载的块
- 使用这种动态代码拆分的关键是你必须传递部分路径等信息才能知道
Introducing Magic Comments
- 它专门用于动态导入语句,在动态导入的模块路径之前添加注释
- 当我们使用代码拆分作为一种技术时,添加 bundle 包时没有创建名称,所以注意可以命名或标记其中一个懒加载的 bundle
const getFooter = () => import(/* webpackChunkName: "footer" */ "./footer");
Webpack Modes
- 使用 webpackMode 来控制代码拆分的发生方式,默认是 lazy
- lazy-once 在开发模式下可以提高构建速度
const setButtonStyle = (color) => import(/* webpackMode: "lazy-once" */`./button-styles/${color}.js`);
- 使用 DefinePlugin 区分环境,webpack 会为此变量注入一个宏替换。
Webpack Prefetch & Preload
- 4.8 增加的功能
- Webpack 借鉴了浏览器的 preload 和 perfetch
- 对于每个需要延迟加载的块,我们将创建一个 link 元素,然后加上 preload 属性。添加到 script 里去。
const getLodash = () => import(/* webpackPreload: true */"lodash-es");
- 基本上删除了等待网络的所有成本
Wrapping Up Code Splitting
- 做一个组件库时允许用户使用动态导入来加载所需的部分,最好能动态导入
Webpack Config Organization
webpack 配置碎片化
Building Your Library with Webpack
- 使用 UMD 不如直接上 ES
- 建议不要使用 Webpack 打包的的 bundle,即使它是库,也失去了摇树,作用域提升或任何的优化
- 实在不行用 babel 呗