1.0.12 • Published 8 months ago

loadshow v1.0.12

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
8 months ago

loadshow

loadshowは、Webページの読み込みプロセスを動画に記録するオープンソースのCLIツールです。

  • Webページの読み込みスピードの比較は感覚と記憶に頼りがち
  • PageSpeed Insightsなどの数値による評価は専門家以外にわかりにくい

このような問題意識から、Webページの読み込みスピードをわかりやすく表現し、直感的に比較する方法として開発しました。

読み込みスピードの改善結果の前後や、競合サイトとの比較などに活用ください。

はじめよう

必要なソフトウェア

  • Node.js >= 20
  • Chrome または Chromium
  • ffmpeg

インストール

npm i -g loadshow

動画の記録

recordサブコマンドでWebページの読み込み過程を動画に記録します。URLと成果物を格納するディレクトリを指定します。

loadshow record https://apple.com/ ./loadshow.mp4

上記のコマンドは、https://apple.com/の読み込み過程を記録した./loadshow.mp4を作成します。

apple.com.mp4

動画の比較

juxtaposeサブコマンドで、複数の動画を左右に並べた比較動画を作成できます。

loadshow juxtapose -o compare.mp4 apple.com.mp4 microsoft.com.mp4

上記のコマンドは、apple.com.mp4microsoft.com.mp4を左右に配置し、-oオプションに指定したcompare.mp4として出力します。

compare.mp4

TIPS

環境変数

次の項目を環境変数で指定できます。

  • LOG_LEVEL ログレベル (fatal | warn | error | info | debug | fatal) デフォルト値 info
  • CHROME_PATH Chromeのパス (例 /Applications/Google Chrome.app/Contents/MacOS/Google Chrome)
  • FFMPEG_PATH ffmpegのパス (例 /opt/homebrew/bin/ffmpeg) デフォルト値 ffmpeg (Windowsの場合 ffmpeg.exe)
  • LC_ALL or LC_MESSAGES or LANG 情報バナーのロケール (例 ja-JP)
  • TZ 情報バナーのタイムゾーン (例 Asia/Tokyo)
  • BARE_PUPPETEER 実験的なモード。puppeteerにバンドルされるChromeを使用 (例: 1)
  • LOG_OBJECTS ログに付帯されたオブジェクトを表示する。

動画の仕様とカスタマイズ

動画の仕様は次のように構造化されたオブジェクトで規定されています。それぞれのデフォルト値とともに示します。

frameFormat: 'png' # 中間画像フォーマット (pngまたはjpeg。jpegの方がやや軽量)
frameQuality: 85 # 中間画像フォーマットがjpegの場合の品質値
hasBanner: true # 情報バナーの表示
hasProgressBar: true # プログレスバーの表示
layout:
  canvasWidth: 512 # 動画エリアの幅
  canvasHeight: 640 # 動画エリアの高さ
  columns: 3 # カラム数
  gap: 20 # カラム間の幅
  padding: 20 # 動画エリアの余白
  borderWidth: 1 # 罫線の幅
  indent: 20 # 第二カラム移行の頭下げ
  outdent: 20 # 第一カラムの下方の余白
  progressHeight: 16 # プログレスバーの幅
recording:
  network: # ネットワーク設定
    latencyMs: 20 # レイテンシー (単位 ms)
    downloadThroughputMbps: 10 # ダウンロードスループット (単位 Mbps)
    uploadThroughputMbps: 10 # アップロードスループット (単位 Mbps)
  cpuThrottling: 4 # CPUスロットリング (スマホ相当にするため4 = 性能1/4)
  headers: # HTTPリクエストヘッダ
  viewportWidth: 375 # ビューポート幅
  timeoutMs: 30000 # タイムアウト (単位 ms)
  preferSystemChrome: false # Puppeteerバンドルのブラウザではなくインストール済みChromeを優先 ※
  puppeteer: # puppeteerの設定 `PuppeteerLaunchOptions`
    headless: true,
    args: # 文字列
      - '--hide-scrollbars'
banner: # 情報バナー
  templateFilePath: "" # HTMLテンプレート (ファイル指定)
  htmlTemplate: "" # HTMLテンプレート (テキスト指定)
  vars: # HTMLテンプレートに渡す変数 (オブジェクト)
    # var1: "値1"
composition:
  colorTheme:
    background: '#eee' # 動画エリアの背景
    border: '#ccc' # 罫線
    progressBackground: '#fff' # プログレスバーの背景
    progressForeground: '#0a0' # プログレスバー
    progressText: '#fff' # プログレスバーの文字
    progressTimeText: '#333' # 経過時間の文字
rendering:
  outroMs: 1000 # 読み込み完了後の静止時間 (単位 ms)
  ffmpegArgs: # ffmpegへの追加オプション (文字列配列)
    # - "..."

# recording.preferSystemChromeは環境変数BARE_PUPPETEER=1の場合のみ使用

これらの値を必要に応じて一部上書きして、作成される動画をカスタマイズできます。値を上書きする方法はふたつあります。

# -u オプションによる上書き (複数可)
loadshow record -u "layout.canvasWidth=500" -u "frameFormat: jpeg" https://apple.com/ ./loadshow.mp4

# YAMLファイルでまとめて変更する場合
loadshow record -s spec.yml https://apple.com/ ./loadshow.mp4

spec.ymlには、以下の例のように上書きしたい属性のみ記述します。

frameFormat: jpeg
layout:
  canvasWidth: 500

使用するブラウザ

インストール済みのChromeを自動で検索します。

環境変数CHROME_PATHの指定がある場合、優先で適用します。

以下はOSごとのシステムChromeの代表的なパスです。

  • MacOS /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
  • Windows C:\Program Files\Google\Chrome\Application\chrome.exe
  • Linux /usr/bin/google-chrome

puppeteerのブラウザは使用しないのか?

puppeteerをインストールするとChromiumブラウザが~/.cacheディレクトリ以下にインストールされます。

本来はこちらを使いたいところですが、環境によって動画の表示崩れが発生するため、Chromeの事前インストールをを必要としています。

環境変数BARE_PUPPETEERに値(1など)を設定すると、実験的にpuppeteerがバンドルしたブラウザを使用します。

情報バナーのカスタマイズ - 表示内容

動画の上部に表示される情報バナーは、HTMLテンプレート(handlebars)の変数を書き換えることによりカスタマイズできます。

変数自体がテンプレートとして振る舞うので、{{ }}などの記号を記述することで他の変数を参照できます。

# システムから渡される変数
width: 動画の幅
url: 記録しているURL
htmlTitle: HTMLタイトル
timestampMs: 記録を行った日時のタイムスタンプ(単位 ms)
resourceSizeBytes: リソースサイズ
onLoadTimeMs: 読み込み時間(OnLoad 単位 ms)

# 組み込みヘルパー
datetime: ロケールに合わせた日時タイムスタンプの整形
mb: リソースサイズをMB単位に整形
msToSec: msを秒に整形
i18n: 一部の用語を翻訳

仕様オプションbanner.vars以下の値を変更することでカスタマイズできます。

banner:
  vars:
    mainTitle: "{{htmlTitle}}"
    subTitle: "{{url}}"
    credit: "loadshow"
    createdAt: "{{datetime timestampMs}}"
    resourceSizeLabel: "Resource Size"
    resourceSizeValue: "{{mb resourceSizeBytes}}"
    onLoadTimeLabel: "OnLoad Time"
    onLoadTimeValue: "{{msToSec onLoadTimeMs}}"

例えばloadshowというクレジット表記を変更するには、次のようにコマンドを実行します。

loadshow record -u "banner.vars.credit=My Loadshow!" https://apple.com/ ./loadshow.mp4

情報バナーのカスタマイズ - テンプレートの変更

仕様オプションbanner.templateFilePathにHTMLテンプレートのパスを指定することで、テンプレート自体を変更できます。

あるいはbanner.htmlTemplateにHTMLテンプレートを直接指定することもできます。この利用方法はYAMLファイルによる仕様の指定を想定しています。

詳しくはsrc/banner.tsを参照してください。

苦手なページ

内部的には縦長のウィンドウを作成し、動画の記録を行っています。そのため全面背景のようにウィンドウの高さを基準にしたCSSを利用しているページでは、表示が崩れる場合があります。

API

プログラムの一部として呼び出すには以下のように記述します。

import Fs from 'fs'
import { Dependency, runLoadshow, defaultLoadshowSpec, mergeLoadshowSpec } from 'loadshow'

async function main() {
  // 外部依存
  const dependency = new Dependency()
  // Pino loggerをカスタマイズ / 削除可能
  // dependency.logger = ... / delete dependency.logger

  // 動画の仕様カスタマイズ
  const spec = mergeLoadshowSpec(defaultLoadshowSpec(), {
    layout: {
      canvasWidth: 500,
    },
    frameFormat: 'jpeg'
  })

  // 仕様・URL・動画パス・成果物ディレクトリを入力とする
  Fs.mkdirSync('./loadshow', { recursive: true })
  const input = {
    ...spec,
    url: 'https://github.com/',
    videoFilePath: './loadshow.mp4'
    artifactsDirPath: './loadshow',
  }

  // loadshowの実行
  const output = runLoadshow(spec, dependency)

  // 結果の参照
  console.log(output)
}

main()

ライセンス

Apache License 2.0 の下で公開します。

技術サポートを希望の方は問い合わせください。

開発

セットアップ

git clone <url>
cd <dir>
yarn

MacOS Arm64の場合、モジュールsharpの関係で次のコマンドが必要な模様。

yarn --ignore-engines

テスト

yarn test

テストカバレッジは進捗予定。

簡易デバッグ

src/adhoc.tsを改変して以下のプログラムを実行。

yarn adhoc

残課題

  • テストとかかなり適当。
  • puppeteerにバンドルされるブラウザの積極利用。
    • Chromeの事前インストールを不要にしたい。
    • 環境変数BARE_PUPPETEERに値を設定することで試験可能。
1.0.12

8 months ago

1.0.11

8 months ago

1.0.10

8 months ago

1.0.9

9 months ago

1.0.8

9 months ago

1.0.7

9 months ago

1.0.6

9 months ago

1.0.5

9 months ago

1.0.4

9 months ago

1.0.3

9 months ago

1.0.2

9 months ago

1.0.1

9 months ago

1.0.0

9 months ago