框架篇-Vue面试题5-怎么提高首屏渲染以及性能优化

2020-10-28 17:09:47 浏览数 (1)

前言

每逢面试,首屏渲染性能优化是一个常见的话题,下面就自己知道的,记录一下

分析打包出来的文件

安装webpack-bundle-analyzer这个插件,然后使用npm run build --report输出项目打包情况,直观的比较哪个bundle文件的大小,有针对性的进行模块化拆分

路由懒加载

router.js文件中,原来的静态引用方式,如

代码语言:javascript复制
import ShowBlogs from '@/components/ShowBlogs';

routes: [(path: 'Blogs'), (name: 'ShowBlogs'), (component: ShowBlogs)];

经过路由懒加载更改为,如下方式

代码语言:javascript复制
routes:[
   path: 'Blogs',
   name: 'ShowBlogs',
   component: () => import('./components/ShowBlogs.vue')
  ]

如果是在 vuecli 3中,我们还需要多做一步工作 因为 vuecli 3默认开启 prefetch(预先加载模块),提前获取用户未来可能会访问的内容 在首屏会把这十几个路由文件,都一口气下载了

所以我们要关闭这个功能,在 vue.config.js中设置

代码语言:javascript复制
// vue.config.js
module.exports = {
  chainWebpack: (config) => {
    // 移除prefetch插件
    config.plguins.delete('prefetch');

    // 或者
    // 修改它的选项
    config.plugin('prefetch').tap((options) => {
      options[0].fileBlacklist = options[0].fileBlacklist || [];
      options[0].fileBlacklist.push(/myasyncRoute(.) ?.js$/);
      return options;
    });
  },
};

一些 UI 框架按需加载,不要整个的引入

这里以饿了么 ui 为例:

原本的引进方式引进了整个包

代码语言:javascript复制
import ElementUI from 'element-ui';
Vue.use(ElementUI);

如果只用了按钮,表单,分页,表格,提示等更改为

代码语言:javascript复制
import {
  Button,
  Input,
  Pagination,
  Table,
  TableColumn,
  MessageBox,
} from 'element-ui';
Vue.use(Button);
Vue.use(Input);
Vue.use(Pagination);
Vue.prototype.$alert = MessageBox.alert;

注意 MessageBox注册方法的区别,虽然用到了alert,但并不需要引入 Alert组件

.babelrc / babel.config.js文件中添加(vue-cli 3要先安装 babel-plugin-component)

代码语言:javascript复制
plugins: [
  [
    'component',
    {
      libraryName: 'element-ui',
      styleLibraryName: 'theme-chalk',
    },
  ],
];

gzip 压缩

安装 compression-webpack-plugin

代码语言:javascript复制
cnpm i compression-webpack-plugin -D

vue.congig.js中引入并修改 webpack配置

代码语言:javascript复制
const CompressionPlugin = require('compression-webpack-plugin')

configureWebpack: (config) => {
        if (process.env.NODE_ENV === 'production') {
            // 为生产环境修改配置...
            config.mode = 'production'
            return {
                plugins: [new CompressionPlugin({
                    test: /.js$|.html$|.css/, //匹配文件名
                    threshold: 10240, //对超过10k的数据进行压缩
                    deleteOriginalAssets: false //是否删除原文件
                })]
            }
        }

注意:在服务器也要做相应的配置,如果发送请求的浏览器支持 gzip,就发送给它gzip格式的文件 如果服务器是用express框架搭建的 只要安装一下 compression就能使用,其他也类似

代码语言:javascript复制
const compression = require('compression');
app.use(compression()); // 要放在所有其他中间件注册之前
  • 首屏内容可以做静态缓存(hash 强缓存的一个方案。比如hash cache control: max-age=1年)
  • 首屏内联 css 渲染
  • 图片懒加载(可以通过给img标签上添加loading=lazy)来开启懒加载模式
  • 使用字体图标代替小图片
  • 图片尺寸大小控制适当
  • 利用好script标签的asyncdefer这两个属性,功能独立且不要求马上执行的js文件,可以加入async属性,如果是优先级低且没有依赖的js,可以加入defer属性
  • 前端做一些接口的缓存:缓存的位置有两个: 一个是内存,即赋值给运行时的变量,另一个是localStorage,比如签到日历(展示用户是否签到),可以缓存这样的接口到localStorage,有效期是当天,或者有个列表页,我们总是缓存上次的列表内容到本地,下次加载时,我们先从本地读取缓存,并同时发起请求到服务器获取最新列表
  • 页面使用骨架屏(元素进行占位)
  • 使用ssr渲染:服务器性能一般都很好,那么可以在服务器先把vdom计算完后,在输出给前端
  • 引入http2.0,http2.0对比http1.1最主要的是提升是传输性能,在接口小而多的时候更加明显
  • 选择先进的图片格式:使用webP的图片格式来代替现有的jpegpng,当页面图片较多时,这点作用非常明显
  • 利用好http压缩:即使是最普通的gzip,也能把文件大小压缩不小

如果您有疑问,欢迎下方留言,一起学习交流~

0 人点赞