使用延迟加载提升SPA性能

18-09-14 banq
                   

如果您是Web开发人员,很可能您正在使用Webpack作为模块捆绑器,并且可能您不知道延迟加载是什么。

什么是延迟加载?

你也许会想:“延迟并不是快,可能正好相反”,你在语义上没有错,但还有另一种方法,让我们看看Webpack的延迟加载定义是什么:

lazy或“按需”加载是优化网站或应用程序的好方法,这种做法主要涉及在逻辑断点处拆分代码,然后在用户完成需要或将需要新代码块的操作后再去加载它。

换句话说,你可以任何你想要的方式(即组件)拆分代码,浏览器只会加载应用程序运行所需的代码。听起来真棒!

我为什么需要这个?

这是一个简单的问题。提升性能!使用延迟加载时,只会加载所需的代码,初始加载速度会更快(因为只加载了更少的代码),并且整体速度将更快地按需加载。

我也喜欢在应用延迟加载时如何捆绑代码,没有它,你可能会有一个HTML文件,一个CSS和一个巨大的JS。

我怎么能做到这一点?

首先,你需要Webpack以及Babel和一些插件。

npm i -D dynamic-import-webpack syntax-dynamic-import

现在我们安装了所有东西,我们需要将它们添加到 我们的Babel配置文件.babelrc中。

{
  "plugins": [
    ...
    "dynamic-import-webpack",
    "syntax-dynamic-import"
  ],
  "presets": [
    ["env", {
      "targets": [
        "last 2 versions", "safari >= 7", "not ie < 9"
      ]
    }]
  ]
}
<p>

当然,这只是运行应用程序所需的Babel配置,可随意添加适合您需要的插件/preset。

你可能认为你需要以不同的方式进行编码,事实是你并不需要这样做。唯一会改变的是导入代码的方式。

给我看一些代码!

React和Vue是令人惊叹的框架,无论你使用哪一个,都有一种简单的方法来决定如何分割共享代码。组件!基于组件的代码拆分是使用这些框架的最佳策略。

使用react-loadable响应异步路由:

import React from 'react';
// We can use react-loadable to cover the most possibles outcomes of the code splitting
import Loadable from 'react-loadable';

// My Loader component
import Loader from '@components/Loader';

// Create the async route
const AsyncRoute = Loadable({
  loader: () => import('./index'),
  loading() {
    return <Loader />;
  }
});

// This is the component the React Router will use
const MyRoute = props => <AsyncRoute {...props} />;

export default MyRoute;
<p>

在上面的代码中,我们使用react-loadable实现异步路由工作(你也可以将它用于非必要路由的组件),并添加一些功能,比如在请求组件时显示加载器和超时管理。

Vue异步组件:

import Vue from 'vue'

import Navbar from '../../components/Navbar'

const AsyncComponent = () => import('../../components/AsyncComponent')

const vm = new Vue({
  el: '#app',
  // ... all attributes necessary for your instance
  components: { Navbar, AsyncComponent }
})
<p>

对于Vue,可以仅使用动态导入功能请求组件,并将其注册到实例,如上所示。这仅适用于组件,但对于路由是相同的,只需将组件添加为路由器配置中的路由组件即可。

无论如何,我们不能忘记Angular,因为我们也可以只更改配置:

import { RouterModule, Routes, PreloadAllModules } from @angular/router;

// You can say to Angular the route is async with the hash at the end of the import
export const ROUTES: Routes = [
  { path: '', pathMatch: 'full', redirectTo: 'dashboard' },
  { path: 'dashboard', loadChildren: '../dashboard/dashboard.module#DashboardModule' },
  { path: 'settings', loadChildren: '../settings/settings.module#SettingsModule' },
  { path: 'reports', loadChildren: '../reports/reports.module#ReportsModule' }
];

@NgModule({
  // ...
  imports: [
    RouteModule.forRoot(ROUTES, { preloadingStrategy: PreloadAllModules })
  ],
  // ...
})
export class AppModule {}
<p>

在运行我们项目的构建之后,我们现在可以看到创建了不同的文件,如果您没有使用延迟加载,则之前这些文件不会存在。

现在,我们已经将应用程序的异步路由与主要代码块分开,我们现在以我们想要的方式运行我们的代码块,那么这将如何发挥作用?在我们加载视图时,可以在浏览器控制台中检查网络视图,能够发现延迟加载的组件。

在这里展示了如何分离异步路由和组件,这样,可以最大限度地减少应用程序的大小,并通过此代码拆分技术带来很多性能改进。

原文