性能分析(一)前戲:用 rollup 打包一個 js-sdk

在開啓這個篇章以前,我決定先開一篇來說一下rollup,畢竟幹活嘛,前戲要足。javascript

作一個抉擇,rollup vs webpack

webpack 於 2012 年由 Tobias Koppers 創立,旨在解決現有工具沒法解決的難題:構建複雜的單頁應用程序(SPA)。特別是兩個功能對後期產生了很大的影響:java

  1. Code-splitting,經過代碼拆分,能夠將您的應用程序拆分爲可管理的塊,這些塊能夠按需加載。這意味着您的用戶得到交互式站點的速度要比等待整個應用程序下載和解析的速度快得多。node

  2. Static assets,能夠將靜態資產(例如圖像和 CSS)導入到您的應用中,並僅將其視爲依賴關係圖中的另外一個節點。webpack

rollup 的創立確實由於另外的緣由,利用 ES2015 模塊的巧妙設計,儘量高效地構建 JavaScript 庫的統一可分發版本。web

讓咱們逐個功能看看對比二者之間的不一樣chrome

如下內容來自 webpack 官網: webpack.js.org/comparisonjson

功能 webpack rollup
按需加載 Yes No
AMD define Yes rollup-plugin-amd
AMD require Yes No(我的使用發現是支持)
AMD require 按需加載 Yes No
CommonJS exports Yes commonjs-plugin
CommonJS require Yes commonjs-plugin
CommonJS require.resolve Yes No
Concat in require require("./fi" + "le") Yes No
Debugging support SourceUrl, SourceMaps SourceUrl, SourceMaps
Dependencies 19MB / 127 packages ?MB / 3 packages
ES2015 import/export Yes Yes
Plugins Yes Yes

大概放出來這麼多,其餘的你們能夠去連接地址去看看。後端

從這個對比,咱們能夠看出,webpack簡直是完勝,甚至rollup感受很丟人,什麼都不行,你活在這個世上還有什麼意義?api

存在即合理 —— 黑格爾微信

讓咱們拿出來一行有趣的對比:

功能 webpack rollup
Dependencies 19MB / 127 packages ?MB / 3 packages

19MB?意味着什麼?意味着一個用戶若是以 1m/s 的速度,須要 19s 才能下載完這個 js。很可怕不是嗎?這個時候,你忽然想到,我能夠壓縮啊,是的,咱們能夠利用uglify或者Terser進行壓縮,可是,仍然,咱們不可避免的,19M 就算利用了壓縮,也僅能夠壓縮在 6M 左右,若是再利用分chunk的形式,咱們能夠將主包下降到 2M 左右,可是這仍然是一個可怕的數字,空白的項目,都是這個大小,更況且咱們會引入其餘的包呢?

反之rollup注意到了這點,因此咱們用 rollup 打包的空白項目,僅有幾 kb。

Use webpack for apps, and Rollup for libraries

沒錯,webpack確實很強大,可是也是有應用範圍的,應用是他的立錐之地,若是是一個 libraries,則可使用rollup

2. 使用而且打包一個js-sdk

首先,咱們定一個需求: 咱們要收集用戶的性能數據。

打開掘金的推薦頁面https://juejin.im/timeline/recommended,在 chrome 的控制檯咱們能夠輸入以下代碼,獲得數據如圖 1 所示:

console.log(performance.getEntries());
複製代碼

準備數據

咱們如今的需求是收集這條數據以前的數據上報到後端進行數據分析。

// lib/PerformanceEntries.js
export default class {
  constructor() {
    this.entries = this._handleEntries();
  }

  _handleEntries() {
    const entries = window.performance.getEntries();
    const fptIndex = entries.findIndex(entry => entry.entryType === 'paint');
    return entries.slice(0, fptIndex);
  }

  getEntries() {
    return this.entries;
  }
}
複製代碼

解下來咱們須要把這個數據上報上去

import PerformanceEntries from './lib/PerformanceEntries';

(async () => {
  const performanceEntries = new PerformanceEntries();
  const entries = performanceEntries.getEntries();
  try {
    const res = await fetch('https://server.save.data/api/v1/entries', {
      method: 'POST',
      body: JSON.stringify(entries),
    });
    // some code...
  } catch {}
})();
複製代碼

寫一個rollup.config.js

import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
import { terser } from 'rollup-plugin-terser';

import { version } from './package.json';

export default {
  input: 'index.js',                              // 入口文件
  output: {
    file: 'dist/performance.{version}.js',        // 打包以後的文件名以及存放位置
    format: 'umd',                                // 以什麼模式打包,支持umd,cmd,esm...
    name: 'ihap',                                 // 導出文件的名字
    exports: 'named',
  },
  plugins: {
    babel({
      exclude: ['node_modules'],                  // 忽略 node_modules
      runtimeHelpers: true,                       // 開啓體積優化
    }),
    commonjs(),
    resolve({
      mainField: ['jsnext', 'main'],
      browser: true,
    }),
    terser(),
  },
}
複製代碼

babelrc仍是不可少

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "esmodules": true
        }
      }
    ]
  ],
  "plugins": [
    "@babel/plugin-external-helpers",
    "@babel/plugin-transform-runtime",
    ["@babel/plugin-proposal-class-properties", { "loose": true }]
  ]
}
複製代碼

執行,看看結果

ok,沒有什麼問題,咱們執行一下rollup -c

看一下咱們打包以後的文件大小

僅有772b,仍是很喜人的。

那麼問題來了,能夠用嘛?好的,咱們稍微寫一個簡單的node,而後執行一下。

看,咱們的結果發出去了。

本集總結&下集預告

如何用rollup打包一個很小的文件,咱們已經學會了,下一張,咱們就要針對如何進行性能分析來研究了。好的,你們下次見,我是 ihap 技術黑洞的肥少,喜歡個人話,記得關注點贊收藏,愛個人能夠微信支持我給我讚揚啊!

相關文章
相關標籤/搜索