前端性能优化 - 使用内容分发网络CDN

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

1、为什么要用CDN加速服务

优点:

  • JS体积变小,使用CDN的第三方资源的JS代码,将不再打包到本地服务的JS包中。减小本地JS包体积,提高加载速度。
  • 给网页加载提速

缺点:

  • 请求变多
  • 万一CDN资源路径有变动需要更改,建议自行搭建CDN库。

2、哪些需要使用CDN

在项目根目录下运行

npm run build --report
复制代码

打包完成后,会打开一个页面,展示各个依赖包的大小,查看哪些第三方依赖包的体积大,就干掉它,从CDN上获取。

3、推荐BootCDN

www.bootcdn.cn/

4、确认包和版本

确认需要使用CDN加载的资源,在package-lock.json文件中,找到对应的版本号。

在BootCDN网站找到对应的资源路径。

注意:

找不到echarts-gl的CDN资源路径啊啊啊……

5、修改index.html文件

link添加在头部,script添加在尾部

<html>
  <head>
    <link href="https://cdn.bootcss.com/element-ui/2.4.4/theme-chalk/index.css" rel="stylesheet">
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
    <script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
    <script src="https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script>
    <script src="https://cdn.bootcss.com/three.js/100/three.min.js"></script>
    <script src="https://cdn.bootcss.com/echarts/4.1.0/echarts.min.js"></script>
    <script src="https://cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>
    <script src="https://cdn.bootcss.com/element-ui/2.4.4/index.js"></script>
    <script src="https://cdn.bootcss.com/babel-polyfill/6.26.0/polyfill.min.js"></script>
  </body>
</html>
复制代码

6、修改webpack.base.conf.js文件

在module.exports下添加externals,可以忽略不需要打包的库。

externals: {
    'vue': 'Vue',
    'vue-router': 'VueRouter',
    'vuex': 'Vuex',
    'three': 'THREE',
    'echarts': 'echarts',
    'axios': 'axios',
    'element-ui': 'ElementUI',
    'babel-polyfill': '_babelPolyfill'
},
复制代码

说明:

属性名称vue表明该模块vue中import Vue from 'vue'应排除在外。为了替换此模块,该值Vue将用于检索全局Vue变量。

注意:

此处引入vue-router时,配置使用如下会报错Router未定义。

错误代码如下:

externals: {
    'vue-router': 'Router'
},
 
 export default new Router({
  linkActiveClass: 'on',
  mode: 'history',
  routes: routerArray
})
复制代码

因为此处的全局变量名并不是自行定义的,而是通过查看第三方资源包中对外暴露的变量名,查看node_modules\vue-router\dist下的vue-router.js文件可以看到,global.VueRouter的定义,所以此处必须声明全局变量名为VueRouter。

正确代码如下:

externals: {
    'vue-router': 'VueRouter'
},
 
 export default new VueRouter({
  linkActiveClass: 'on',
  mode: 'history',
  routes: routerArray
})
复制代码

babel-polyfill的配置全局变量_babelPolyfill,同样是查看源码可得。

7、注释掉其他地方包的引入

// import Vue from 'vue'
// import VueRouter from 'vue-router'
// import Vuex from 'vuex'
// import * as THREE from 'three'
// import echarts from 'echarts'
// import axios from 'axios'
// import ElementUI from 'element-ui'
// import 'element-ui/lib/theme-chalk/index.css'
// import 'babel-polyfill'

// Vue.use(VueRouter)
// Vue.use(Vuex)
// Vue.use(ElementUI)
复制代码

8、完成引用后打包报错

完成引用后,打包报错Vue未定义,但是启动运行正常。

因为其实定义了全局变量,但是eslint并不识别全局变量,所以需要在.eslintrc.js配置文件中添加

globals: {
    'Vue': true,
    'VueRouter': true,
    'Vuex': true,
    'THREE': true,
    'echarts': true,
    'axios': true,
    '_babelPolyfill': true
}
复制代码

声明一下这些是全局变量,再次打包即可。

9、使用预获取

只需在链接属性上增加 rel="prefetch",rel="dns-prefetch",或者 rel="preload" 标记。

preload:

代码会被优先加载,并且会占用http并发数,从而也导致页面加载时间变长,特别是首屏时间会变长。

本页面接下来大概率要使用的资源重要资源。

prefetch:

的代码被安排在后面加载,这样才达到了优化效果。

下个页面很可能会去访问的非重要的资源。

然后修改代码如下:

<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script>
<script rel="preload" src="https://cdn.bootcss.com/three.js/100/three.min.js"></script>
<script rel="prefetch" src="https://cdn.bootcss.com/echarts/4.1.0/echarts.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>
<script src="https://cdn.bootcss.com/element-ui/2.4.4/index.js"></script>
复制代码

以为被preload修饰的three会优先加载,而被prefetch修饰的echarts会延后加载。

但是!!

本地也好,服务器也好,配置了完全没有变化,严格按照顺序加载的……

猜你喜欢

转载自juejin.im/post/7110454782199857188