터보링크(Turbolinks) 이해하기

동작기전

레일스 애플리케이션의 응답 속도를 높이기 위한 노력의 일환으로 등장한 것이 바로 터보링크(Turbolinks)다. 터보링크는 이름에서도 짐작할 수 있듯이 웹페이지에 있는 링크를 클릭했을 때 현재 페이지를 유지한 채, 브라우저에서 전체 웹페이지를 재컴파일하지 않고 BODY 태그와 헤드 부분의 ‘TITLE’ 값만 불러오도록 함으로써 전체적인 응답속도를 향상시키도록 한다.

터보링크의 출현

터보링크는 레일스 4 Gemfile에 디폴트로 포함되었다.

터보링크의 동작을 보기 위해서 아래와 같이 샘플 프로젝트 생성하자.

$ rails new blog

홈페이지를 만들기 위해서 home 컨트로러와 index 액션을 컨트롤러 제너레이터로 생성하자.

$ rails g controller home index

루트 라우트(홈페이지)를 아래와 지정하자.

root "home#index"

로컬 서버를 실행한 후 브라우저에서 홈페이지가 제대로 보이는지 확인하자.

http://localhost:3000

titlecontent 속성을 가지는 Post 리소스를 scaffold 제너레이터를 이용하여 생성하고 rake db:migrate을 실행하자.

$ rails g scaffold Post title content:text
$ rake db:migrate

이로써 posts라는 데이터베이스 테이블이 생성될 것이다.
다음은 루트 페이지(app/views/posts/index.html.erb) 하단에 아래와 같이 posts#index 액션을 호출하는 링크를 추가하자.

<hr />
<%= link_to "Posts", posts_path %>

이제 다시 루트 페이지로 접속하면 아래와 같이 보일 것이다.

이제, app/assets/javascripts/posts.coffee 파일을 열고 아래와 같이 추가하자. 이것은 모든 페이지에서 문서 로드가 완료되면 “Document loaded!”라는 메시지를 보이는 경고창이 나타나도록 해 준다.

$ ->
  alert "Document loaded!"

브라우저에서 홈페이지를 리로드하면 아래와 같이 경고창이 보이게 될 것이다.

하단에 추가한 Posts 링크를 클릭해 보자. 이번에는 경고창이 나타나지 않을 것이다.

그 이유를 알아보자.

레일스 4.1버전 부터는 프로젝트 생성시 디폴트로 터보링크 젬이 추가되어, 모든 페이지의 링크가 터보링크 기능을 가지게 된다. 따라서 홈페이지 하단의 Posts 링크도 터보링크로 동작하게 된다.

따라서, 이 링크를 클릭시 posts#index 액션이 호출되어 뷰 템플릿 렌더링으로 생성된 웹페이지에서 헤더의 titlebody 태그의 내용만이 유저 브라우저의 현재 페이지로 업데이트되고 자바스크립트는 호출되지 않게 되는 것이다.

그렇다면 모든 링크를 호출시에 경고창을 보이도록 하려며 어떻게 해야 할까?

이러한 문제를 해결하기 위해서는 document에 이벤트를 작성해 준다. 즉, 문서 페이지의 내용이 변경시(터보링크를 클릭하여 현재 페이지의 titlebody가 업데이트될 때) 동작하는 자바스크립트를 작성해 주면 된다.

아래의 CoffeeScript 내용을 보자.

$(document).on 'page:change', (event) ->
  alert "Page changed!"

이제부터는 모든 터보 링크를 클릭시에 “Paged changed!” 경고창을 나타날 것이다.

터보링크가 document에서 발생시키는 이벤트의 종류는 아래의 링크를 참고하면 된다.
https://github.com/rails/turbolinks#events

참고로, 아래는 문서 전체를 렌더링할 때 실행되는 자바스크립트 코드를 작성하는 기본 문법을 소개한다.

$(document).ready( function() {
    console.log("hi");
  }
);

단축형

$(function() {
  console.log("hi");
});

CoffeeScript

$ -> 
  console.log "hi"

터보링크를 사용하지 않고 프로젝트 생성하기

$ rails g blog --skip-turbolinks

기존의 레일스 프로젝트로부터 터보링크 제거하기

레일스 4에서 이미 프로젝트 생성한 후 터보링크를 제거하기 위해서는 아래와 같은 단계를 거치면 된다. (참고 : http://blog.steveklabnik.com/posts/2013-06-25-removing-turbolinks-from-rails-4)

  1. Gemfile에서 gem 'turbolinks' 코드라인을 제거한다.
  2. app/assets/javascripts/application.js 파일에서 //= require turbolinks 코드라인을 제거한다.
  3. app/views/layouts/application.html.erb 파일에서 "data-turbolinks-track" => true 키값쌍 두 곳을 제거한다.

잠시 터보링크 기능을 중단하기

나중에 사용할 목적으로 터보링크 기능을 중단할 수 있는데, 아래와 같이 body 태그에 "data-no-turbolink" 옵션을 추가하면 된다. (참고: http://blog.flightswithfriends.com/post/53943440505/how-to-disable-turbolinks-in-rails-4)

jquery.turbolinks 젬 사용

위에서 언급한 터보링크 문제점을 해결하기 위한 조치사항이 귀찮은 경우에는 [jquery.turbolinks](https://github.com/kossnocorp/jquery.turbolinks) 젬을 추가하면 터보링크를 접속할 경우 자바스크립트로 바인딩된 부분이 작동하지 않는 문제점을 쉽게 해결할 수 있다.

우선 Gemfile을 열고 아래와 같이 젬을 추가하고 번들 인스톨한다.

gem 'jquery.turbolinks'

그리고 app/assets/javascripts/application.js 파일을 열고 아래와 같이 jquery.turbolinks.js 파일을 추가(require)한다. 이 때 require 순서가 중요하기 때문에 반드시 아래의 순서대로 추가해야 한다. jquery.js 바로 다음에 jquery.turbolinks.js를 추가하고 turbolinks.js는 마지막에 추가해야 한다.

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//
// ... your other scripts here ...
//
//= require turbolinks

자세한 내용은 “Faster page loads with Turbolinks”를 참고하면 많은 도움이 될 것이다. 여기에는 터보링크의 로딩 상태를 표시하는 방법이 소개되어 있다.

터보링크 로딩 표시하기

임의 자바스크립 파일에 아래와 같은 코드를 추가한다.

$(document).on('page:fetch', function() {
  $('.loading-indicator').show();
});

$(document).on('page:change', function() {
  $('.loading-indicator').hide();
});

또는 CoffeeScript로는

$(document).on 'page:fetch', ->
  $('.loading-indicator').show()
  return
$(document).on 'page:change', ->
  $('.loading-indicator').hide()
  return

그리고 레이아웃 파일의 적당한 곳에 아래와 같이 로딩 표시를 위한 div 태그를 추가한다.(app/views/layouts/application.html.erb)

<!DOCTYPE html>
<html>
<head>
  <title>BlogNoSkipTurbolinks</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body>

  <div class='loading-indicator'>로딩중...</div>

  <%= yield %>

</body>
</html>

이제 브라우저에서 터보링크를 클릭하거나 리로딩하면 페이지 상단에 터보링크가 작동함을 알려주는 “로딩중…”이라는 표시가 보일 것이다.

글쓴이: 최효성

외과전문의,웹프로그래밍,컴퓨터 일러스트레이션 / Surgeon, Medical Illustration, Web Programmer

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중