Vite编译速度优化-分析

216 阅读1分钟

自定义 Plugin,得到主要编译过程的时间间隔数据

import fsPromise from 'fs/promises';
import path from 'path';
import { Plugin } from 'rollup';

export default function myPlugin(): Plugin {
    const start = Date.now();

    const getDis = (s = start) => {
        return Date.now() - s;
    };

    const list: Array<{
        dis: number;
        hook: string;
    }> = [];

    const resolveIdList: Array<{
        dis: number;
        id: string;
        time: number;
    }> = [];
    const loadList: Array<{
        dis: number;
        id: string;
        time: number;
    }> = [];

    const transformList: Array<{
        dis: number;
        id: string;
        time: number;
    }> = [];

    const moduleParsedList: Array<{
        dis: number;
        id: string;
        time: number;
    }> = [];

    return {
        name: 'my-plugin', // 必须的,将会在 warning 和 error 中显示

        buildStart() {
            list.push({
                dis: getDis(),
                hook: 'buildStart',
            });
        },

        buildEnd() {
            list.push({
                dis: getDis(),
                hook: 'buildEnd',
            });
        },

        renderStart() {
            list.push({
                dis: getDis(),
                hook: 'renderStart',
            });
        },

        writeBundle() {
            list.push({
                dis: getDis(),
                hook: 'writeBundle',
            });

            fsPromise.writeFile(path.resolve(__dirname, './list.txt'), list.map(t => JSON.stringify(t)).join('\n'));
            fsPromise.writeFile(
                path.resolve(__dirname, './resolveIdList.txt'),
                resolveIdList.map(t => JSON.stringify(t)).join('\n')
            );
            fsPromise.writeFile(
                path.resolve(__dirname, './loadList.txt'),
                loadList.map(t => JSON.stringify(t)).join('\n')
            );
            fsPromise.writeFile(
                path.resolve(__dirname, './transformList.txt'),
                transformList.map(t => JSON.stringify(t)).join('\n')
            );
            fsPromise.writeFile(
                path.resolve(__dirname, './moduleParsedList.txt'),
                moduleParsedList.map(t => JSON.stringify(t)).join('\n')
            );
        },

        resolveId: {
            order: 'pre',
            handler(id: string) {
                resolveIdList.push({
                    dis: getDis(),
                    id,
                    time: Date.now(),
                });
            },
        },

        load: {
            order: 'pre',
            handler(id: string) {
                loadList.push({
                    dis: getDis(resolveIdList.find(item => item.id === id)?.time),
                    id,
                    time: Date.now(),
                });
            },
        },

        transform: {
            order: 'pre',
            handler(code: string, id: string) {
                // console.log(code);
                transformList.push({
                    dis: getDis(loadList.find(item => item.id === id)?.time),
                    id,
                    time: Date.now(),
                });
            },
        },
        moduleParsed: {
            order: 'pre',
            handler(moduleInfo) {
                const { id } = moduleInfo;
                moduleParsedList.push({
                    dis: getDis(transformList.find(item => item.id === id)?.time),
                    id,
                    time: Date.now(),
                });
            },
        },
    };
}

写个小脚本,把上个过程得到的数据整理下:

const fsPromise = require('fs/promises');

const NodeModulesKey = '/node_modules/';

async function run() {
    const data = await fsPromise.readFile('./transformList.txt');
    const str = data.toString();
    const arr = str
        .trim()
        .split('\n')
        .map(s => s.replace('\u0000', ''));

    const arr2 = arr.map(str => JSON.parse(str));
    const map = new Map();
    let totalDis = 0;
    arr2.forEach(({ dis, id }) => {
        const name = (() => {
            if (id.includes(NodeModulesKey)) {
                return id.split(NodeModulesKey)[1].split('/')[0];
            }

            return id;
        })();

        const desc = map.get(name) || {
            dis: 0,
            count: 0,
        };

        totalDis += dis;
        desc.dis += dis;
        desc.count++;
        map.set(name, desc);
    });

    const resArr = [];

    map.forEach((desc, name) => {
        const disScale = desc.dis / totalDis;
        const disRelatively = disScale * 423614; // buildEnd time
        resArr.push({
            name,
            ...desc,
            disScale,
            disRelatively,
        });
    });

    resArr.sort((a, b) => b.dis - a.dis);
    const resString = resArr.map(item => JSON.stringify(item)).join('\n');

    await fsPromise.writeFile('./transform-count.txt', resString);
}

run();