Angular 首屏加载优化

来源:互联网 发布:linux 查看路由 编辑:程序博客网 时间:2024/06/05 03:27

Angular 应用主要包含组件和它们的HTML模板。 在浏览器可以渲染应用之前,组件和模板必须要被Angular编译器转换为可以执行的JavaScript。最简单的方式就是将所有代码加载到浏览器中,包括我们自己写的组件的 Angular 编译器,然后在浏览器中编译,这种编译方式就是 JIT(Just-in-Time).

JIT 编译与比较大的性能问题。由于需要在浏览器中执行这个编译过程,因此视图需要花更长时间才能渲染出来。而且编译所需要的 Angular 编译器和许多应用并不需要的库也会发送到浏览器,这导致应用体积变大,浏览器加载速度也变慢。


AOT 编译

AOT(Ahead of Time) 编译方式会首先在本地将应用编译完成,因此可以节省在浏览器上的首次编译时间,而且编译完后的应用不再需要 Angular 编译器了,因此体积也大大缩小了。

使用 AOT 编译可以在 官方文档 看到。

当然最简单的方式是使用 angular-cli

下面看两种编译方式的体积大小以及应用加载速度

首先是体积大小,下面主要观察 vendor.bundle.js 文件的大小,该文件中打包了应用所依赖的 node_module 中的库。

JIT 模式下 vendor.bundle.js 的体积为 3.2M

jit-network

js加载时间大概为 1.1s

jit-performance

AOT 模式下 vendor.bundle.js 仅为 609K,当然不仅仅是减少了编译器的体积,还有摇树优化 (Rollup) 的功劳.

aot-network

js加载时间大概为0.4s

aot-performance


bundle-analyzer

虽然使用 AOT 编译之后体积缩小了很多,但是还是有优化的空间。使用 webpack-bundle-analyzer 可视化工具可以分析 webpack 打包后的文件中所有依赖文件所占的体积。

使用 npm 安装

npm install webpack-bundle-analyzer

并在 ng build 时输出统计数据

ng build --prod --stats-json

此时在输出文件夹中会多一个 stats.json 文件,里面包含了打包后 js 的组成信息,接下来使用 webpack-bundle-analyzer 分析,

webpack-bundle-analyzer dist/stats.json

可以得到如下图中类似的结果

bundle-analyze

可以看到在 node_module 中处理 angular 核心文件,还有 rxjs 也占了很大一部分体积。但其实 rxjs 包含了很多很多库函数,而我们的应用中一般只会用到其中的一部分。如果去掉我们未使用的文件,那应该会减少一部分体检。

事实上 rxjs 也提供了按需导入的方法,如果使用下面方法,会将 rxjs 中的所有库函数都导入进来

import Rx from 'rxjs/Rx';

将导入方法改为

import { Observable } from 'rxjs/Observable';import 'rxjs/add/observable/of';import 'rxjs/add/observable/empty';import 'rxjs/add/operator/map';import 'rxjs/add/operator/take';

按需导入库函数,再使用webpack-bundle-analyzer

bundle-analyze-opt

可以看到rxjs所占的体积变小了。整个 bundle 的体积也从 609K 降到了 463K 。

事实上 Angular 官方说体积最小可以达到 250K 左右,当然我这里因为还导入了其他的库,例如 marked.js 和 highlight.js。所以体积会更大一点。


惰性加载

当我们自己的应用中功能越来越多的时候,应用的体积也会越来越大。我们可以通过异步加载特性模块来减少主模块的体积。

惰性加载 (lazy-load) 方法可以参考文档中路由导航部分

惰性加载有以下优点:

我们可以只在用户请求时才加载某些特性区。

对于那些只访问应用程序某些区域的用户,这样能加快加载速度。

我们可以持续扩充惰性加载特性区的功能,而不用增加初始加载的包体积。

引入惰性加载后, AOT 编译也会多出相应的 js 文件。原来的 main.bundle.js 的体积则会相应地减小。


服务器端渲染

AOT 模式下需要加载的 JS 文件体积已经大大减少了,加载速度也变快了。

而使用服务器端渲染可以再提升首屏加载速度,而且对于 SEO 优化也是有利的。

服务器端渲染方法可以看 Angular Universal 这一章,虽然文档中还有一些坑(详细看我的前一篇文章)。

服务器渲染后需要下载的文件如下图,因为此时渲染过程已经在服务器端完成,所以浏览器只要下载 html 文件就可以了。

ssr-nerwork

加载速度如下图,可以看到相比前面的家族过程,Scripting 时间大大缩短了,因为不再需要运行 angular 代码了。

ssr-performance

需要注意的是

虽然服务器端渲染即使不加入 AOT 产生的 js 代码也可以在浏览器端看到页面,但这样的页面是静态的,不再具有 Angular 单页面应用带来的优点了。

所以事实上还是需要引入 AOT 产生的 js 代码,但是这里引入 js 代码并不会影响页面的加载。