Developer's Blog

【Sleipnir 3】Ruby でブラウザの起動時間を測定する

Sleipnir 3 RC
こんにちは、Sleipnir 開発担当の西田です。

先日 Sleipnir 3 RC 版をリリースしましたが、その後も特に高速化に力を入れて改良を続けてきました。高速化には測定が欠かせませんので、各種ツールを活用して様々な測定を行った上で、プログラムを修正しています。

そこで今回は起動時間を測定するために作成した Ruby スクリプト、startup.rb を紹介したいと思います!


startup.rb は、下図のような流れで起動時間を測定しています:
sleipnir3-startup-rb.png
ブラウザを起動してからページの読み込みが完了するまでの時間を計測しています。ユーザーが感じる起動時間と正確に一致するものではないと思いますが、1つの指標として利用できます。
startup.rb のソースコードは次の通りです:

require 'Win32API'
require 'webrick'

FIND_WINDOW = Win32API.new('user32', 'FindWindow', %w(p p), 'l')
SEND_NOTIFY_MESSAGE = Win32API.new('user32', 'SendNotifyMessage', %w(l i i i), 'l')
WM_CLOSE      = 0x0010
WM_QUIT       = 0x0012
WM_SYSCOMMAND = 0x0112
SC_CLOSE      = 0xF060

INTERVALS = [5] * 4

# 測定するブラウザのブラウザ名、実行パス、ウィンドウクラス名、ウィンドウのキャプション
BROWSER_DATA =
  [
    ['Sleipnir297' , '"D:\temp\sleipnir\sleipnir297\bin\Sleipnir.exe"', 'SleipnirMainWindow', nil],
    ['Sleipnir3RC1', '"D:\temp\sleipnir\sleipnir3rc1\bin\Sleipnir.exe"', 'MainWindow', 'Sleipnir'],
    ['Sleipnir3RC5', '"D:\temp\sleipnir\sleipnir3rc5\bin\Sleipnir.exe"', 'MainWindow', 'Sleipnir'],
]

#現在時刻の整数(ms)を得る
def get_current_millsec
  now = Time.now
  ms = now.hour
  ms = ms * 60 + now.min
  ms = ms * 60 + now.sec
  ms = ms * 1000 + now.usec / 1000
  ms
end

# 閉じるボタンを押す
def send_close_to_matching_window(classname, caption)
  # 2回送る
  2.times do
    hwnd = FIND_WINDOW.call(classname, caption)
    SEND_NOTIFY_MESSAGE.call(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0)
  end
end

que = Queue.new

#HTTPサーバー開始

srv = WEBrick::HTTPServer.new({ :DocumentRoot =>gt; './', :BindAddress => '127.0.0.1', :Port => 8080})
srv.mount('/', WEBrick::HTTPServlet::FileHandler, 'index.html')
srv.mount_proc('/onload') do |req, res|
  ms = req.query['ms'].to_i
  que.push ms
  res.body = ms.to_s
end
trap(:INT){ srv.shutdown }
thread_srv = Thread.new do
  srv.start
end

#ブラウザの起動時間測定開始

BROWSER_DATA.each do |name, path, classname, caption|
  print "#{name}: #{path}\n  "
  elapses = INTERVALS.map do |e|
    sleep e
    ms_before = get_current_millsec
    spawn path
    ms = que.pop - ms_before
    print "#{ms},"
    sleep e
    send_close_to_matching_window(classname, caption)
    ms
  end

  puts "\n  average: #{elapses.inject(:+) / elapses.size}\n"
end

ブラウザで読み込ませる index.html は次のとおりです:

<!-- saved from url=(0014)about:internet -->
<html>
  <head>
    <title>
  </head>
  <body>
    <script type="text/javascript" language="javascript">
      window.onload = function() {
        dt = new Date();
        ms = dt.getHours();
        ms = ms * 60   + dt.getMinutes();
        ms = ms * 60   + dt.getSeconds();
        ms = ms * 1000 + dt.getMilliseconds();

        try {
            var http = new ActiveXObject("Microsoft.XMLHTTP");
        } catch(e) {
            var http = new XMLHttpRequest();
        }
        http.onreadystatechange = function() {
            if (http.readyState == 4 && http.status == 200) {
              document.body.innerHTML = "ok: " + http.responseText
            }
        }
        http.open("GET", "onload?ms=" + ms);
        http.send(null);
      }
    </script>
    loading...
  </body>
</html>

WEBrick を使うと、とても簡単に HTTP サーバーを実装することができます。実際、サーバーに関するコードはたったの 11 行です!
また Ruby は Windows 環境のためのライブラリも用意されており、 FindWindow や SendNotifyMessage といった Windows API も呼び出すことができるので、*nix 環境だけでなく Windows 環境でも幅広く活用することができます。

では、startup.rb の使用方法を説明します。まず計測したいブラウザで起動直後に http://localhost:8080/ が読み込まれるようにします。次に上記の startup.rb と index.html を同じフォルダに置き、startup.rb の BROWSER_DATA に計測したいブラウザの情報を設定します。そして startup.rb を Ruby インタプリタで実行し、測定を開始します。

startup.rb を使って測定した Sleipnir の起動時間は次の通りです:

タブ1個で起動 タブ20個復元して起動
Sleipnir 2.9.7 1137[ms] 1792[ms]
Sleipnir 3 RC 830[ms] 1249[ms]
Sleipnir 3 RC 最新テスト版 681[ms] 691[ms]

Sleipnir 3 RC 最新テスト版の起動時間が最も早く、復元するタブが増えても起動時間にほとんど影響しないところが特徴的ですね!

それでは、これからも フェンリル / Sleipnir をよろしくお願いします。

Twitterフェンリルのオフィシャルアカウントをフォローする

Copyright © 2019 Fenrir Inc. All rights reserved.