前端优化篇

232 阅读4分钟

随着大前端的发展,前端开发逐渐组件化、模块化、工程化,给前端的开发优化带来极大益处。打包工具必不可少,前段时间将webpack4.0的学习笔记已发,这篇文章总结下在项目里做过的优化,其中含有部分关于webpack的优化。
写在前面,使用webpack-bundle-analyzer对项目进行模块分析,针对性进行优化。

webPack

1. external dependencies(外部依赖,采用CDN)

防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。

module.exports = {
    chainWebpack: (config) => {
        config.externals({
            quill: 'Quill',
            katex: 'katex',
            moment: 'moment',
            'element-ui': 'ELEMENT',
          });
    },
};

在生产环境的index.html引入CDN链接,本地开发时依然使用import形式即可

2. 使用splitChunks进行代码分割

使用splitChunks可以将一个文件分割成多个文件,可以减小代码体积,利用缓存来加速静态资源访问。每当一个文件有改动时,浏览器会重新下载该资源,然而第三方依赖却几乎很少变动,所以我们将依赖分离成单独的文件。

const opt = config.optimization;
    opt.runtimeChunk({ name: 'manifest' });
    opt.splitChunks(Object.assign({}, opt.get('splitChunks'), {
      // (缺省值5)按需加载时的最大并行请求数
      maxAsyncRequests: 16,
      // (默认值3)入口点上的最大并行请求数
      maxInitialRequests: 16,
      // (默认值:1)分割前共享模块的最小块数
      minChunks: 1,
      // (默认值:30000)块的最小大小
      minSize: 30000,
      // webpack 将使用块的起源和名称来生成名称: `vendors~main.js`,如项目与"~"冲突,则可通过此值修改,Eg: '-'
      automaticNameDelimiter: '~',
      // cacheGroups is an object where keys are the cache group names.
      name: true,
      cacheGroups: {
        default: false,
        vendors: {
          name: 'chunk-vendors',
          test: /[\\/]node_modules[\\/]/,
          minChunks: 1,
          priority: -10,
          chunks: 'initial',
          reuseExistingChunk: true,
        },
        commons: {
          name: 'chunk-commons',
          minChunks: 2,
          priority: -20,
          chunks: 'initial',
          reuseExistingChunk: true,
        },
        // 所有异步异步引入的第三方
        async: {
          name: 'chunk-async',
          minChunks: 2,
          priority: -30,
          chunks: 'async',
          reuseExistingChunk: true,
        },
      },
    }));

注:默认组的优先级为负数,以允许任何自定义缓存组具有更高的优先级

3. 按需加载路由

{
  path: '/content',
  component: Wrap,
  children: [
    {
      path: 'test',
      name: 'test',
      component: () => import(/* webpackChunkName: "contentTest" */ '../views/content/index.vue'),
    },
  ],
},

资源加载优化

4. 使用preload预加载

由于浏览器有缓存策略,在App端的多页面应用,我们希望在访问其中一个页面时,也可以把其他页面的资源提前加载,这样整个项目在端内的资源文件都有缓存,无论在下一次访问哪个页面时都能以最快速度加载。
可以利用webpack的自定义插件,将其他页面中具有ref='preload'&as='script'属性的link.url动态加载到本页面body中;

5. DNS预解析:dns-prefech

当浏览器访问一个域名的时候,需要解析一次DNS,获得对应域名的ip地址。典型的一次DNS解析一般需要20-120ms,提前解析接下来会用到的域名。 另外,同一域名下同时间并行请求下载资源的数量有限,与浏览器和http有关,可以分多个域名分别存放资源,增加同时间请求并发。

图片优化

6. 转成base64减少请求数

利用webpackloader对小于1kb的图片进行转化,减少请求数

7. 利用图片懒加载

npm install --save-dev vue-lazyload

<img v-lazy="src"></img>

8. webp

WebP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都相当优秀、稳定和统一。

这是经过压缩的图片,现在单独取出一张来测试使用前后的体积变化 原图片地址为:https://www.xxx.com/test_d34344545.jpg,(百度云),原体积为53.2KB

地址加上@f_webp之后,体积为33.7KB,减少近40%

例如一些作为头像的图片,一般前端使用的尺寸都很小,所以可以自定义图片的宽度和质量。 q_75,w_100 其中qquality,wwidth,尺寸直接下降了94%!!!

缓存

9. service-worker

Service WorkerPWA的核心技术,它能够为web应用提供离线缓存功能,使用流程可以简单总结为注册--安装--激活

第一次浏览页面时下载了资源,下次直接在serviceWorker