摘要:原文来自我的代码拆分与动态导入当项目越做越大时,体积过大导致加载速度过慢,性能问题直接影响用户体验。这时我们会考虑将代码拆分。
原文来自我的github: https://github.com/Vibing/blog
代码拆分与动态导入当项目越做越大时,体积过大导致加载速度过慢,性能问题直接影响用户体验。
这时我们会考虑将代码拆分。
拆分,顾名思义就是将一个大的东西拆分成N个小的东西,用公式表示就是:Sum = n * Sub
代码拆分基于动态导入
什么是动态导入?就是我需要什么,你给我什么,我不需要的时候,你别给我,我嫌重。
动态导入可以将模块分离成一个多带带的文件 在需要的时候加载进来。
对于动态导入,webpack 提供了两个类似的技术。
第一种,也是优先选择的方式是,使用符合 ECMAScript 提案 的 import() 语法。
第二种,则是使用 webpack 特定的 require.ensure。
从webpack 2以后,一般使用第一种。
async-loadable由于import()方法返回的是Promise对象,我们为了能方便的返回组件,
这里推荐使用async-loadable插件
例子代码:
import loadable from "async-loadable"; import Loading from "./my-loading-component"; const LoadableComponent = loadable({ loader: () => import("./my-component"), loading: status =>, }); export default class App extends React.Component { render() { return ; } }
代码里有熟悉的 import() 方法。async-loadable 使用 webpack 的动态导入,调用loadable方法可以方便的返回要使用的组件。
下面我将以我本人的项目经历,来讲解代码拆分(code splitting)
代码拆分前当初还是小白的我,一开始哪知道有代码拆分这个技术啊,就一个人负责一个小项目,一开始项目不大,跑起来也是嗖嗖的,这里先贴一下路由代码:
import Home from "./home"; import Page1 from "./page1"; import Page2 from "./page2";
这里没有使用动态导入,而是直接将所有页面静态引入进来,然后赋到对应路由上。
这么做的坏处就是:打包时,整个项目所有的页面都会打包到一个文件中,随着页面增多,这个文件也越来越大,最后我看了一下,达到了近25M(我吓得打开度娘...)。
如果用一张图来表示的话,这张图在适合不过了:
哈哈,整个一坨有没有。所有路由在这一坨红色里,看着真特么憋屈啊
基于路由的代码拆分打开度娘的我脸色渐渐有了好转,通过搜索,看到了webpack有个code splitting功能(代码拆分),
前面说过,代码拆分其实就是使用动态导入的技术实现的,那么我们就使用动态导入来优化一把之前的路由:
import Loadable from "async-loadable"; import Loading from "./my-loading-component"; const Home = Loadable({ loader: () => import(`./home`), loading: Loading }); const Page1 = Loadable({ loader: () => import(`./page1`), loading: Loading }); const Paeg2 = Loadable({ loader: () => import(`./page2`), loading: Loading });} /> } /> } />
我们不再使用 import module from "url" 来静态引入模块,而是使用 loadComponent 来动态导入,它返回的是Loadable的结果,也就是我们想要的组件,我们把再把组件给对应的路由,这就完成了基于路由的代码拆分。
使用以后,鄙人怀着激动的心情开始打包项目,当我看到控制台的打包日志时,我的表情是这样的:
咳咳,这种好事情当然要分享一下啦,你要的结果:
可以看到,webpack打包时已经将之前的一个臃肿文件按路由拆分成了三个文件,当我们点击一个路由时,会动态加载对应的文件。
比如我点击home页面的路由时:
我再点击page1时:
嗯,是按照路由来拆分的代码,完美~
这样看来,我们需要将之前的那张图改成这样的:
看着项目加载速度变快了,心里真特么高兴
基于模块拆分其实基于路由的代码拆分已经可以满足绝大多数项目了,再大的项目也能满足。
但随着项目做的多了,慢慢的发现了一个问题:代码浪费。
比如我要做一个Tab切换的功能,像酱紫的:
对应的代码大概是酱紫的:
import { Tabs } from "antd"; import TabOne from "./component/tab1"; import TabTwo from "./component/tab2"; import TabThree from "./component/tab3"; const TabPane = Tabs.TabPane; export default class Home extends Component { render() { return (); } }
Tab切换,每个前端小伙伴都做过,其实说白了,就是显示隐藏的效果。
但是在这个页面中,已经把每个Tab里的代码都加载进来了,如果用户只看第一个Tab,其他Tab不点击,就造成了代码浪费。
如何解决这个问题呢?还是那句话:我需要什么,你给我什么,我不需要的时候,你别给我,我嫌重。
我们使用动态导入的方式改造一下代码:
import { Tabs } from "antd"; import Loadable from "async-loadable"; import TabOne from "./component/tab1"; import Loading from "./component/loading"; const TabPane = Tabs.TabPane; const loadComponent = path => Loadable({ loader: () => import(`${path}`), loading: Loading }); const Tab2 = loadComponent("./component/tab2.tsx"); const Tab3 = loadComponent("./component/tab3.tsx"); export default class Home extends Component { render() { return (); } }
同样 我们不再使用import module from "url"的方式,而是使用 loadComponent 方法动态导入。
由于TabOne是第一个默认显示的,所以没必要动态导入。
现在我们来点击Tab 2看看效果:
非常棒,正是我们想要的。
再点击Tab 3 :
简直完美!
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/95356.html
摘要:按照的要求我需要将的坐标拆分为多行。到这里相当于将列中所有文本拆成了一个巨大的表,表中每个单元格有一个值。有些行拆分后的元素比较少,没有值可以填充的单元格补充会把整个表逐行堆叠成一列。彩蛋我在列拆分为多行的基础上,还将拆分成了两个变量。 背景 手头的项目要求用 Tableau 创建一个 story,数据集是摩拜上海城区用户使用数据。其中有一个维度的数据处理起来有点棘手。 数据格式 sh...
摘要:拆分了录屏代码,监控插件压缩至,另外我们还原了部分,帮助用户更方便地。请大家及时更新哈拆分录屏代码从版本开始,我们拆分了录屏代码。自从年双十一正式上线,累计处理了亿错误事件,付费客户有金山软件百姓网等众多品牌企业。 摘要: BUG监控插件压缩至18K。 showImg(https://segmentfault.com/img/bVbpIPC?w=900&h=383); 1.7.1拆分了...
摘要:划分标准根据稿,不同的展示模块分为不同的组件。比如顶部底部导航列表等容器组件业务组件与数据源后台本地存储进行数据传输操作不止是划分标准根据业务功能划分。最常见的是列表组件。 为什么要拆分组件 提高可读性、可维护性 如果不拆分 代码量大,所有内容集中在一起 相同组件无法复用 业务开发分工不明确,开发人员要关心非业务的代码 改代码时,可能会影响其他业务,牵一发动全身(耦合) 任何一个操作...
阅读 2647·2021-11-25 09:43
阅读 2450·2021-09-22 15:29
阅读 966·2021-09-22 15:17
阅读 3593·2021-09-03 10:36
阅读 2203·2019-08-30 13:54
阅读 1724·2019-08-30 11:23
阅读 1148·2019-08-29 16:58
阅读 1274·2019-08-29 16:14