You are here
Home > フロントエンド

turbolinksで画面の表示をスピードアップ (2) <script>

前回に続いて、turbolinksの話。

今回は、turbolinksをもとで、ページに含まれる<script>がどう実行されるか説明します。

前回と同様に以下の2つのファイルを用意します。

<html lang="ja">                                                                                                                                                                                                   
  <head>                                                                                                                                                                                                           
    <meta charset="utf-8">                                                                                                                                                                                         
    <title>Turbolinks</title>                                                                                                                                                                                      
    <script src="https://cdnjs.cloudflare.com/ajax/libs/turbolinks/5.0.3/turbolinks.js"></script>                                                                                                                  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>                                                                                                                      
    <script>                                                                                                                                                                                                       
    $(document).on('turbolinks:load', function() {                                                                                                                                                                 
      $("#button").click(function(){                                                                                                                                                                               
        $("#box").animate({left: '250px'});                                                                                                                                                                        
      });                                                                                                                                                                                                          
    });                                                                                                                                                                                                            
    </script>                                                                                                                                                                                                      
  </head>                                                                                                                                                                                                          
  <body>                                                                                                                                                                                                           
    <h1>Turbolinks</h1>                                                                                                                                                                                            
    <ul>                                                                                                                                                                                                           
      <li><a href="page1.html">ページ 1</a></li>                                                                                                                                                                   
    </ul>                                                                                                                                                                                                          
                                                                                                                                                                                                                   
    <button id="button">箱を動かす</button>                                                                                                                                                                        
    <div id="box" style="background:#98bf21;height:100px;width:100px;position:absolute;"></div>                                                                                                                    
  </body>                                                                                                                                                                                                          
</html>                                                                                                                                                                                                            

CDNでturbolinksとjqueryを読み込んでいるところ注意してください。

html lang="ja">                                                                                                                                                                                                   
  <head>                                                                                                                                                                                                           
    <meta charset="utf-8">                                                                                                                                                                                         
    <title>ページ 1</title>                                                                                                                                                                                        
    <script>                                                                                                                                                                                                       
    $(document).ready(function() {                                                                                                                                                                                 
      $("#button2").click(function(){                                                                                                                                                                              
        $("#box").animate({left: '10px'});                                                                                                                                                                         
      });                                                                                                                                                                                                          
    });                                                                                                                                                                                                            
    </script>                                                                                                                                                                                                      
                                                                                                                                                                                                                   
  </head>                                                                                                                                                                                                          
  <body>                                                                                                                                                                                                           
    <h1>ページ 1</h1>                                                                                                                                                                                              
    <p><a href="index.html">戻る</a></p>                                                                                                                                                                           
                                                                                                                                                                                                                   
    <button id="button">箱を動かす</button> <button id="button2">箱を戻す</button>                                                                                                                                 
    <div id="box" style="background:#98bf21;height:100px;width:100px;position:absolute;"></div>                                                                                                                    
  </body>                                                                                                                                                                                                          
</html>  

最初のページで、「箱を動かす」のボタンをクリックすると、箱が右へ移動します。

「ページ1」をクリックして、ページ1に行くと今度も同じく「箱を動かす」のボタンをクリックすると、箱が右へ移動します。このjqueryのコードがページ1(page1.html)になくても。

以下にアップしたので、そこで体験できます。

https://larajapan.lotsofbytes.com/turbolinks/2/index.html

ここで大事なのは、通常なら、

$(document).ready(function() {
..
});

とするところ、

$(document).on('turbolinks:load', function() { 
..
});

とします。window.onloadやjQueryのreadyは、index.htmlがロードしたときにのみ実行されますが、ページ1のリンクのクリックでページ1をajaxで読み込むときには実行されません。ゆえに、ページ1では「箱を動かす」ボタンをクリックしても箱は移動しません。

一方、turbolinks:loadを使用すると、リンク先のページにjavascriptのコードがなくとも、index.htmlのコードを実行します。

さらに、turbolinksは、リンク先のファイル(ここではpage1.html)に、現在のファイル(ここではindex.html)に存在しない、<script>のコードがあるなら、それもロードしてくれます。それゆえに、「箱を動かす」のボタンをクリックすると、箱が右へ移動するし、「箱を戻す」をクリックすると、箱は左に移動します。

最後に、今回の例はturbolinksの機能の説明のために、このようなjavascriptのコードとなること理解してください。実際にはpage1.htmlがブックマークされていて、次回のアクセスがそこから始まるなら現在のpage1.htmlのコードでは困ります。つまり、page1.html自体が更新されても同様な動作となる必要があります。

turbolinksで画面の表示をスピードアップ (1)

Laravelのフレームワークのおかげで、自分で作成した古いフレームワークもどきや、CodeIgniterの「もうサポートしません」(注1)フレームワークを脱出できて、以前よりしっかりした開発の領域に入ってきたと感じているこの頃。そして、ファサード、ネームスペース、クロージャ、トレイトなどを活用して、とてもモダン。しかし、最近人気が出てきたJavascriptのフレームワーク、Angular, React, Vuejsを使用したシングルページアプリ(SPA)がとても気になります。

Laravelは基本的にサーバーサイドで、Angularなどはクライアントサイドなので、共存は可能と言えばそうなのだけれど、せっかく時間かけてマスターしたLaravelのプログラムを書き直すとか、今度はどのJavascriptフレームワークをマスターすればよいのとか、ajaxばかりでプログラム複雑になるのでは、とか、過去には、CodeIgniterで苦い目にあったし、最近やっと大きいプロジェクトを3年かけてLaravelに書き直したばかりなので、ちょっとポジティブにはなれません。

そんな中で、知り合ったのが題名のturbolinks。このテクノロジーの謳い文句は、

Javascriptのフレームワークを使用して複雑にすることなしに、シングルページアプリ(SPA)のパフォーマンスが得られる!

なんか「何もしなくても痩せる!」というダイエットサプリメントのような感じですが、今の私にピッタリ。とりあえず、紹介しましょう。

まず、メカニズムですが、そう難しくはありません。ページ内に同じサイト内のリンク、つまり<a href= ..>があると、turbolinksはajaxでそのページを取ってきてその中の<body>のデータを現在のと取り換えます。<head>は同じなので、結果的には、

のように、タブのところに表示される「ページロード中」のぐるぐるがなくなります。さらに、<title>やURLも正しく変わります。

インストールはいたって簡単。

以下の2つのファイルを用意してください。最初のファイルだけに、turbolinks.jsが入っていることに注意してください。

<html lang="ja">                                                                                                                                                                                                   
  <head>                                                                                                                                                                                                           
    <meta charset="utf-8">                                                                                                                                                                                         
    <title>Turbolinks</title>                                                                                                                                                                                      
    <script src="https://cdnjs.cloudflare.com/ajax/libs/turbolinks/5.0.3/turbolinks.js"></script>                                                                                                                  
  </head>                                                                                                                                                                                                          
  <body>                                                                                                                                                                                                           
    <h1>Turbolinks</h1>                                                                                                                                                                                            
    <ul>                                                                                                                                                                                                           
      <li><a href="page1.html">ページ 1</a></li>                                                                                                                                                                       
    </ul>                                                                                                                                                                                                          
  </body>                                                                                                                                                                                                          
</html>                                                                                                                                                                                                            
<html lang="ja">                                                                                                                                                                                                   
  <head>                                                                                                                                                                                                           
    <meta charset="utf-8">                                                                                                                                                                                         
    <title>ページ 1</title>                                                                                                                                                                                        
  </head>                                                                                                                                                                                                          
  <body>                                                                                                                                                                                                           
    <h1>ページ 1</h1>                                                                                                                                                                                              
    <p><a href="index.html">戻る</a></p>                                                                                                                                                                               
  </body>                                                                                                                                                                                                          
</html>                                                                                                                                                                                                            

これらのファイルをサーバーにアップして、「ページ1」や「戻る」リンクをクリックしてください。タブの部分において、もうロード中のぐるぐるは見えませんね。「すっ」とページが変わる感じです。また、URLやタイトルも正しく更新されています。

しかし、ページ1においてブラウザの更新ボタンを押して画面を更新した後に、「戻る」のリンクをクリックするときは、ロード中のぐるぐるが見えます。これはpage1.htmlには、turbolinksがないからです。

以下のデモでも体験できます。

https://larajapan.lotsofbytes.com/turbolinks/index.html

ブラウザのインスペクトツールでも、ajaxが使用されていることがわかります。


index.htmlのturbolinksをコールしているscriptの行を削除して違いも見てください。

CDNではなく、turbolinksのファイルが欲しいなら、

$ wget https://github.com/turbolinks/turbolinks/archive/master.zip

で取得可能です。unzipしてから、dist/turbolinks.jsのファイルが取り出せます。

知っておくこととして、

ページの特定のリンクにおいてturbolinksを無効にしたいなら、data-turbolinks="false"を入れてください。

..
  <body>                                                                                                                                                                                                           
    <h1>Turbolinks</h1>                                                                                                                                                                                            
    <ul>                                                                                                                                                                                                           
      <li><a href="page1.html" data-turbolinks="false">ページ 1</li>                                                                                                                                                                       
    </ul>                                                                                                                                                                                                          
  </body>   
..

クリック先のページを読み直したいときとかに必要です。私の経験では、ページを変更してセッションに値を入れるときには、これが必要でした。期待した動作にならないとか問題があるときに試してみること必要です。それから、hrefのリンクのクリックはGETのアクションとなりますが、POSTのアクションには、turbolinksは関与しないので、フォームの投稿はスピードアップはしません。通常の画面の更新となります。

実際のプロジェクトで使用となると、他にも知る必要なことがいくつか(たくさんではない)あります。例えば、Google Analyticsは正しく反映されるのか、とか、Wordpressでも使用できるかとか。知識を整理して、将来により情報を共有します。

注1

CodeIgniterは私が初めて使用したPHP言語のフレームワークです。どこかのサイトで紹介されていて簡単そうなので使い始めました。日本語のデータ処理に問題があったので使える部分はほとんどコントローラの部分だけでしたが、いくつかのお客さんのプロジェクトの開発に使いました。当時は一番人気のフレームワークでしたが、その絶頂期の2013年にCodeIgniterを開発した会社がリソースがないことを理由に開発を辞める宣言をしました。そこで開発が止まり1年後にはカナダの専門学校がメンテナーとなり現在はそこでオープンソースとして管理されています。

ということで、CodeIgniterはまったく消え去ったわけではありませんが、Laravelを使い始めて振り返ると、CodeIgniter自体のフレームワークはその時点ですでに古く、現在のPHP言語のネームスペースに基づくcomposerのパッケージを基本として作成されたものでもなく、より複雑になるウェブアプリの開発にはそのままでは不可能です。

Top