• 进一步优化SPA的首屏打开速度(模块化与懒载入) by 嗡


    前言

    单页应用的优点在于一次载入全部页面资源,利用本地计算能力渲染页面。提高页面切换速度与用户体验。但缺点在于全部页面资源将被一次性下载完,此时封装出来的静态资源包体积较大,使得第一次打开SPA页面时候须要的载入时间较长。

    在上一篇文章Angular2 单页应用一些优化总结 中提到的利用压缩、混淆、开启gzip传输后,我们成功将3.5兆的资源包压缩到350k。可是假设SPA应用的页面数进一步添加,100个甚至1000个页面的时候,还是无法避免巨大的首页资源包载入的问题。

    所以350k的资源包是否还有进一步优化的空间呢?答案是肯定的。

    从SPA的特性能够看出,用户在第一次打开页面时,实际上是把整个站点的全部页面都一起下载下来了,可是非常多情况下,用户可能并不会訪问到全部页面。或者短时间内仅在1~2个页面之间跳转。

    所以假设能够在第一次仅下载一部分页面,然后在用户须要的时候继续下载其他页面资源的话,就能进一步压缩首页资源包的体积。

    下面对优化步骤进行解说。

    模块化

    模块化的优点

    模块化是后期优化的首要步骤。默认的Angular2 spa的项目结构为:应用主程序(main.ts)、根模块(app.module.ts)、根组件(app.component)。然后才是其他的组件components。事实上说白了就是一个拥有好多组件的单模块应用而已。

    通过模块化划分。我们能够将应用依照不同功能或者作用划分为不同模块。这样也使得应用结构更加清晰。比方电商类应用:产品模块、订单模块、用户模块、购物车模块等。

    模块的建立方法

    step 1 : 创建模块

    在app路径下建立一个modules目录单独保存模块比較好一些。通过angular-cli的命令构建模块ng g module testmodule 就可以。程序会自己主动建立一个testmodule目录,里边有一个testmodule.module.ts

    step 2 : 创建组件

    在testmodule目录上建立components目录,同一时候创建组件ng g component testcomponent 里边包括标准的组件文件(ts, html, css, spec)文件。

    step 3 : 创建模块路由

    该路由作为模块内部组件路由使用。而不是根路由。创建方法和根路由同样。

    须要注意的是模块路由的路径是相对于该模块路径的地址
    比方:根路径为/app/testmodule/component1 时,模块内定义的路径应该为component1

    同一时候将原RouterModule.forRoot(Routes) 改为RouterModule.forChild(Routes)

    将原应用的诸多组件依照上面的方法分为不同模块后,就能够进行下一步懒载入了。

    懒载入

    懒载入路由

    在根路由中。将原url与component的关联改为url与loadChild关联就可以。

    比方

    //*********原方案
    //app.routing.ts
    const routes: Routes = [
        {path:'component1', component:Component1}
    ]
    
    //********新方案
    // new app.routing.ts
    const routes: Routes = [
        {path:'testmodule', loadChild:'app/modules/testmodule/testmodule.module#TestModule'}
    ]
    // testmodule.routing.ts
    cost moduleRoutes: Routes = [
        {path:'component1',component1:Component1}
    ]

    这样对于/app/testmodule/component1 地址,应用首先会载入testmodule,然后,由testmodule模块载入component1组件,完毕页面载入。

    模块载入策略

    上文的loadChild 起到了载入模块的作用,仅在用户点击模块下的链接时。程序才開始下载模块相应的js文件,然后再渲染出来。若希望用户在还未点击页面的时候,就从后台预先载入该模块的js。能够进行例如以下改动:

    // app.routing.ts
    //原代码
    @NgModule({
        imports:[RouterModule.forRoot(routes)]
        exports:[RouterModule]
    })
    //改为
    @NgModule({
        imports:[RouterModule.forRoot(routes), {preloadingStrategy:PreloadAllModules}]
        exports:[RouterModule]
    })

    这样程序会在首页资源载入完毕后,在后台自己主动下载其余模块的资源。这样,用户在进入其他模块页面的时候。不须要等待js资源的下载,同一时候首页打开速度仍然和仅载入首页模块一样快。

    须要注意的一点

    在根模块的imports声明中,不能引入懒载入模块,否则,会被打包工具打入首页包中,这样懒载入就没有效果了。

    效果对照

    (非专线网络。请忽略网络实际载入时间~~~~)

    模块区分以及懒载入优化前

    图中main.js文件保存了全部页面的代码。体积达到134k之大。整个首页js资源总共350k左右。
    这里写图片描写叙述

    模块区分以及懒载入优化后

    因为我在首页仍然保留了4个页面。所以首页包仍然有76.3k,单页缩小了近一半。同一时候能够看到多出来的x.chunk.js文件,这些就是懒载入的模块(我使用了PreloadAllModules策略,因此会将全部模块下载下来)。


    优化前后。页面点击效果全然一样。


    这里写图片描写叙述

  • 相关阅读:
    解决ubuntu下pip安装报错问题:ERROR: Cannot uninstall 'XXXXXXX'. It is a distutils installed project...
    【IMU】【卡尔曼滤波】惯性导航误差微分方程与状态转移方程
    AspNetCore 路由 <3.0>
    AspNetCore 认证 <1.0>
    AspNetCore 鉴权 <2.0>
    apollo学习2:docker集群部署
    C#中HashSet<T>、SortedSet<T>和Hashtable的使用以及所有集合类型的概述
    Spring自带的Objects等工具类(减少繁琐代码)
    五分钟,手撸一个简单的Spring容器
    jdk1.8: Consumer函数
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7295841.html
Copyright © 2020-2023  润新知