# 优化1M带宽的云服务器访问速度

一台1M带宽的云服务器, 理论下载最大速度是128kb/s
现如今,前端项目构建后的文件动辄就是几M大小,那用户来访问岂不是需要10s以上
天呐,哪会有用户这么好心的等你这么久,早就溜了
那么如何优化访问速度呐,且听我细细道来 先体验优化后的服务器(3s左右打开) (opens new window)

先对比下优化前后的首页访问速度
左边是优化前访问速度(已经超过20s)
右边是优化后的访问速度(奇迹般的能到2s)

# 解决方案

# 扩容

扩容?这辈子都不会扩容


# 优化构建

要突破1M带宽的限制,首先想到的是把构建包的体积降下来,其次是减少首屏加载的资源,再者可以通过CDN加速静态资源访问

# 1.如何减小构建包体积

项目中使用很多第三方库(react、react-router、antd等等),把这些库提取出来就可以减少构建包的体积
webpack中的externals配置可以在打包时忽略这些第三方包,这样就有效减少包体积

// webpack.config.js
module.exports = {
  // 通过externals配置,将react、react-dom、react-router、antd设置为打包时不参与构建
  externals: {
    // 左边key表示在import导入时的包名
    // 右边的值表示外部引入导出的变量名-这个要写正确了
    react: 'React',
    'react-dom': 'ReactDOM',
    'react-router': 'ReactRouter',
    antd: 'antd',
  }
};

那这些被导出的包该如何引用呐
在html文件中,使用script标签引入这些包就行

<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
        <link rel="stylesheet" href="bound.css">
        <link href="https://cdn.bootcss.com/animate.css/3.7.0/animate.min.css" rel="stylesheet">
        <link href="https://cdn.bootcss.com/antd/3.16.3/antd.min.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/react/16.8.6/umd/react.production.min.js"></script>
        <script src="https://cdn.bootcss.com/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
        <script src="https://cdn.bootcss.com/react-router/3.2.1/ReactRouter.min.js"></script>
        <script src="https://cdn.bootcss.com/antd/3.16.3/antd.min.js"></script>
    <head>
</html>

注意到上面的html模板中引用animate.min.css和antd.min.css
不止js有第三方包,css也有,那css也可以使用externals导出吗?
答案是:不能! 那这些第三方css库如何处理呐?
别慌,在使用antd,官方说使用babel-plugin-import这个插件可以达到按需加载的效果,例如若只使用Button这个组件,可以只引入Button相关的js代码和css代码,这样可以减少构建后文件大小
参考下这种按需加载的导入方式,来看下babel-plugin-import如何使用

// 这个插件的原理是找到libraryName对应的包名导入,将这一行代码重写一下  
// 例如:import 'animate.css' 会被转换成 import './empty.css'
// 将三方包指向一个空的css文件,那打包的后会打包这个空的css文件,也就不会增加包的体积

// .babelrc.js
module.exports = {
    plugins: [
        [
          'import',
          {
            libraryName: 'animate.css',
            customName: name => './empty.css',
          },
          'animate.css',
        ],
        [
          'import',
          {
            libraryName: 'antd/dist/antd.less',
            customName: name => './empty.css',
          },
          'antd/dist/antd.less',
        ],
    ],
}

# 2.如何减少首屏加载资源

减少首屏加载资源,就是把首屏不需要的资源延迟加载,以达到优化加载速度的目的。
一个站点可能会有多个路由,那么除了当前路由相关的资源需要加载,其他的路由的内容都应该被懒加载。
React提供了React.lazy方法来懒加载组件,React.lazy必须要被包裹在React.Suspense标签里。
要使用懒加载需要结合动态import()这个语法,使用babel的plugin-syntax-dynamic-import这个插件可以支持这个语法。

// 动态加载组件的一个写法
// 在路由引用一个组件时,使用这种方式把需要引用的组件包裹一下
/* loadable.js */
import React from 'react';
const Comp = React.lazy(() => import(/* webpackChunkName: 'preview' */ './index.js'));
export default () => <React.Suspense><Comp /></React.Suspense>;

# 3.通过CDN加速静态资源访问

我们知道通过CDN访问静态资源可以加速资源获取,那再去云服务商开个CDN服务? 不必这么麻烦,市面上有可免费使用CDN镜像,使用他们提供的就可以,又可以节省一部分开支。

# 免费好用的cdn加速服务

  • https://www.bootcdn.cn/
  • https://cdnjs.com/
  • https://cdn.baomitu.com/

最后来看下构建后的包的体积,先只关注bound.js
左边是未优化的构建结果js大小1.42M,那么首次加载就需要11s
右边是优化后的构建结果,js文件加起来总和才486k,首页的资源只有185k,那么理论加载速度只需要2s
这还只是对比的js的加载,再加上css的加载,性能提升更明显了

# 结语

本次优化使用的项目在 github (opens new window) 经过不懈的努力终于把网址首次加载速度降到3s
其实还有优化的地方,还要更多去探索,一起加油吧