likes
comments
collection
share

前端开发中常见的性能优化手段

作者站长头像
站长
· 阅读数 36

渲染优化:虚拟列表优化

老生常谈的话题,一般在视口内维护一个虚拟列表(仅渲染十几条条数据左右),监听视口位置变化,从而对视口内的虚拟列表进行控制。

在 React 中可采用以下库:

构建层优化

只介绍 Webpack 构建工具,其他构建工具也是大同小异按照此思路去配置就可以。

减少打包时间

  1. 避免不必要的选择,配置include/exclude减少Loader对文件的搜索范围。
export default {
    module:{
        rules:[
            {
               exclude: /node_modules/, // node_modules 体积过于庞大,检索成本过高
               include: /src/, // 根据自身情况去选择 代码一般都写在src目录下 
               test: /\.js$/, 
               use: "babel-loader"
            }
        ]
    }
}
  1. 编译时只编译修改过的文件,配置cache缓存 loader 对文件的编译副本
// 大部分Loader/Plugin都会提供一个可使用编译缓存的选项,通常包含cache字眼。
// 以babel-loader和eslint-webpack-plugin为例。

import EslintPlugin from "eslint-webpack-plugin"; 
export default { 
    module: { 
        rules: [{ 
            test: /\.js$/, 
            use: [{ 
                loader: "babel-loader", 
                options: { cacheDirectory: true } 
            }] 
        }] 
   }, 
   plugins: [ new EslintPlugin({ cache: true }) ]   
};

  1. 定向指定必须文件路径,配置resolve提高文件的搜索速度,或者某些第三方库以常规形式引入可能报错或者希望程序自动索引特定类型文件都可以通过该方式解决。
// alias映射模块路径,extensions表明文件后缀,noParse过滤无依赖文件。通常配置alias和extensions就足够。
export default {
    resolve: {
        alias: {
            "@": AbsPath("src"), // src目录快捷方式
            swiper: "swiper/js/swiper.min.js"
        }, // 模块导入快捷方式
        extensions: [".js", ".ts", ".jsx", ".tsx", ".json", ".vue"] // import路径时文件可省略后缀名
    }
};
import Os from "os";

export default {
    module: {
        rules: [{
            test: /\.js$/,
            use: [{
                loader: "thread-loader",
                options: { workers: Os.cpus().length }
            }, {
                loader: "babel-loader",
                options: { cacheDirectory: true }
            }]
        }]
    }
};
  1. 分割代码减少重复代码出现的频率,分割各个模块代码,提取相同部分代码,splitChunks官网详细配置 这里列举一下平常用的配置
export default {
    // ...
    optimization: {
        runtimeChunk: { name: "manifest" }, // 抽离WebpackRuntime函数
        splitChunks: {
            cacheGroups: {
                common: {
                    minChunks: 2,
                    name: "common",
                    priority: 5,
                    reuseExistingChunk: true, // 重用已存在代码块
                    test: AbsPath("src")
                },
                vendor: {
                    chunks: "initial", // 代码分割类型
                    name: "vendor", // 代码块名称
                    priority: 10, // 优先级
                    test: /node_modules/ // 校验文件正则表达式
                }
            }, // 缓存组
            chunks: "all" // 代码分割类型:all全部模块,async异步模块,initial入口模块
        } // 代码块分割
    }
};
  1. 移除重复代码和未使用代码,在webpack里只需将打包环境设置成生产环境就能生效。
export default {
    mode: "production"
};
  1. 通过垫片服务根据UA返回当前浏览器代码垫片,好处是无需将繁重的代码垫片打包进去。每次构建都配置@babel/preset-envcore-js根据某些需求将Polyfill打包进来,这无疑又为代码体积增加了贡献。

@babel/preset-env提供的useBuiltIns可按需导入Polyfill

  • false:无视target.browsers将所有Polyfill加载进来
  • entry:根据target.browsers将部分Polyfill加载进来(仅引入有浏览器不支持的Polyfill,需在入口文件import "core-js/stable")
  • usage:根据target.browsers和检测代码里ES6的使用情况将部分Polyfill加载进来(无需在入口文件import "core-js/stable")

在此提供两个动态垫片服务,可在不同浏览器里点击以下链接看看输出不同的Polyfill。相信IExplore还是最多Polyfill的,它自豪地说:我就是我,不一样的烟火

import HtmlTagsPlugin from "html-webpack-tags-plugin";

export default {
    plugins: [
        new HtmlTagsPlugin({
            append: false, // 在生成资源后插入
            publicPath: false, // 使用公共路径
            tags: ["https://polyfill.alicdn.com/polyfill.min.js"] // 资源路径
        })
    ]
};
  1. 按需加载,减轻首屏渲染的负担,合理利用路由懒加载,组件库按需加载,延迟加载第三方包
转载自:https://juejin.cn/post/7264936572645769251
评论
请登录