想要更好的阅读体验,请直接移步我的个人网站: www.pilishen.com/posts/using…
从Laravel Mix (4.0.16)起,开始默认支持动态引入了(dynamic imports)。动态引入是一种资源文件分割(code-splitting)技术,可以让我们将js组件、第三方库及其他模块分割到单独的文件里。比如一个项目里,你用到了好些个js组件,有很多的vuejs或react组件,那么你最终打包的app.js或bundle.js文件就会很大,超过1M+是常有的事儿。这个时候,势必就会降低你的网站加载速度,尤其当用户处于一个慢的连接条件下时。
资源文件分割(code-splitting),可以将原本一个大文件,切分成很多小的文件,这样每个就可能只有几十几百K,而不是多少M了,这样就能极大改善加载速度。由于都切分开了,你就可以一开始只加载最想要的那块js文件,只加载页面上用到的,那些暂时用不到的,或者在其他页面才用到的,可以在背后自动去下载,就不影响一开始的页面渲染时间了。
配置动态引入
{id="Configuring"}
首先你得升级Laravel Mix到4.0.16
以上的版本,才能使用动态引入。
通过.babelrc
文件来配置
然后呢,在你的项目根目录创建一个.babelrc
文件,当然如果你已经有这个文件了,就在以前基础上更改即可。在这个文件里,将@babel/plugin-syntax-dynamic-import
加到“plugins”
这个array里面,这样呢就会启用laravel mix里已经带的自动引入插件。
{
"plugins": [
"@babel/plugin-syntax-dynamic-import"
]
}
通过webpack.mix.js
文件来配置
当然了,如果你不想创建上面的.babelrc
文件,你对babel及其配置并不熟悉,你也可以在mix配置文件,也即webpack.mix.js
里做配置,可以加上下面的代码:
mix.babelConfig({
plugins: ['@babel/plugin-syntax-dynamic-import'],
});
这样你就不用创建或更改.babelrc
文件了
实际使用动态引入
{id="Using"}
原来我们引入一个js组件,经常是这样的:
// 标准的,或静态的引入
import Component from './components/ExampleComponent.vue';
现在,如果我们想着动态地引入一个组件,也即只有当这个组件在页面用到的时候,才去引入和加载,那么可以这样来写:
// 动态引入
const Component =
() => import('./components/ExampleComponent.vue');
默认的,Webpack会将这些动态引入的组件切块,切成单独的文件,以0.js, 1.js
这样的形式来命名。
Laravel Mix的在命名上,可以使用每个切块的名字,跟上这块内容的hash值,然后跟上.js
扩展。如果你想着具体设定每个分块文件的名字,那么在动态引入的时候,可以在组件路径前面,加上下面这样的一段注释
const Component =
() => import(/* webpackChunkName: "dynamically-imported-component" */ './components/ExampleComponent.vue');
可以看到这里,在vue组件具体路径前面,有一段/* webpackChunkName: "dynamically-imported-component" */
的注释,这就告诉webpack,我想要这块文件用这么个名字。那么这样,最终产生的文件名就是dynamically-imported-component.[hash].js
在Vue-Router里使用动态引入
{id="router"}
如果你项目里用到了Vue-Router,那么也就可以用动态引入,来将每个页面切分成单独的文件,可以像下面这样做:
const routes = [
{
name: 'dashboard',
path: '/dashboard',
component:
() => import(/* webpackChunkName: "dashboard" */ './pages/Dashboard.vue'),
},
];
高级用法:脚本预加载
{id="prefetching"}
这样已经能够提升你不少页面的加载速度了,但是我们还不满足。现在假设有两个页面,分别是A页面和B页面,A页面是一个很轻量的、没啥组件的页面,而B页面假设用到了我们分离出来的一个my-component.js
。
那么这个时候,如果一个用户访问了页面A,然后他又点击了页面B,这个时候他就得等待my-component.js
这个文件去下载和处理——也即我们加速了页面A的加载,但是却降低了B页面的时间。因为之前不分离js文件的时候,当访问了A时,app.js文件就已经完全下载了,再访问B页面时就不需要请求了,就一般从浏览器缓存直接加载了。
如果怎么样,我们能让浏览器更智能一些就好了,比如说访问了A页面,我们就能预计他会访问B页面,这时浏览器可以在加载完A页面的脚本和资源以后,在合适的时候后台自己预先抓取B页面要用到的脚本,这样当访问B页面时,相关文件已经准备好了。
当然了,这肯定不只是个想法了,其实现在的浏览器都已经支持这样的做法了,使用传统的<link>
标签,我们其实就可以声明对某个文件的预加载,相当于在浏览器空闲的时候去背后获取。
<link
rel="prefetch"
href="/js/my-component.js"
as="script"
>
这样了以后,当访问了A页面,速度依然很快,当脚本都加载完了,浏览器就自动去获取my-component.js
文件了,当我们再访问到B页面时,也就不需要临时再加载什么文件了,已经都提前获取并放到缓存里了。
结论
{id="concolusion"}
这么好的一项功能,赶紧升级一下Mix,然后用到你的项目里吧,相信能提升不少你的网站加载速度。
本文是我们系列课程《Laravel&Vue深度整合实战第二版》的扩展文章,还记得课程里我们用到了Element-Ui,也即饿了么开发的vue ui组件,期间我们只是用了Element-Ui的几个模块,就导致我们的app.js文件瞬间膨胀到1M以上,在实际中,如果你严重依赖很多UI组件,那么你的打包文件好几M也都是很正常的。原来呢,我们得自行在webpack里进行各种设置,要么只是输出我们实际用到的UI模块,要么就自行实现今天说的文件分割效果,这对不怎么熟悉webpack的同学来说,挺恐怖的。那么现在,Mix默认简单地支持了资源文件分割效果,就大大解决了我们这方面的顾虑,让你在很多页面的效果体验上就可以更大胆、更有空间地做些事情了。
末了,欢迎到我的站点https://www.pilishen.com/来做客哦,也欢迎加入我们的公开群【公开课@pilishen.com】:109256050,等你哦~