동작기전 레일스
애플리케이션의 응답 속도를 높이기 위한 노력의 일환으로 등장한 것이 바로 터보링크(Turbolinks)다.
터보링크는 이름에서도 짐작할 수 있듯이 웹페이지에 있는 링크를 클릭했을 때 현재 페이지를 유지한 채, 브라우저에서 전체 웹페이지를 재컴파일하지 않고 BODY
태그와 헤드 부분의 ‘TITLE’ 값만 불러오도록 함으로써 전체적인 응답속도를 향상시키도록 한다.
터보링크의 출현
터보링크는 레일스 4 Gemfile에 디폴트로 포함되었다.
터보링크의 동작을 보기 위해서 아래와 같이 샘플 프로젝트 생성하자.
$ rails new blog
홈페이지를 만들기 위해서 home
컨트로러와 index
액션을 컨트롤러 제너레이터로 생성하자.
$ rails g controller home index
루트 라우트(홈페이지)를 아래와 지정하자.
root "home#index"
로컬 서버를 실행한 후 브라우저에서 홈페이지가 제대로 보이는지 확인하자.
http://localhost:3000
title
과 content
속성을 가지는 Post
리소스를 scaffold
제너레이터를 이용하여 생성하고 rake db:migrate
을 실행하자.
$ rails g scaffold Post title content:text
$ rake db:migrate
이로써 posts
라는 데이터베이스 테이블이 생성될 것이다.
다음은 루트 페이지(app/views/posts/index.html.erb
) 하단에 아래와 같이 posts#index
액션을 호출하는 링크를 추가하자.
이제 다시 루트 페이지로 접속하면 아래와 같이 보일 것이다.
이제, app/assets/javascripts/posts.coffee
파일을 열고 아래와 같이 추가하자. 이것은 모든 페이지에서 문서 로드가 완료되면 “Document loaded!”라는 메시지를 보이는 경고창이 나타나도록 해 준다.
$ -> alert "Document loaded!"
브라우저에서 홈페이지를 리로드하면 아래와 같이 경고창이 보이게 될 것이다.
하단에 추가한 Posts
링크를 클릭해 보자. 이번에는 경고창이 나타나지 않을 것이다. 그 이유를 알아보자. 레일스 4.1버전 부터는 프로젝트 생성시 디폴트로 터보링크 젬이 추가되어, 모든 페이지의 링크가 터보링크 기능을 가지게 된다. 따라서 홈페이지 하단의 Posts
링크도 터보링크로 동작하게 된다. 결과적으로, 이 링크를 클릭하면 posts#index
액션이 호출되어 뷰 템플릿 렌더링으로 생성된 웹페이지에서 헤더의 title
과 body
태그의 내용만이 유저 브라우저의 현재 페이지로 업데이트되고 자바스크립트는 호출되지 않게 되는 것이다. 그렇다면 모든 링크를 호출시에 경고창을 보이도록 하려면 어떻게 해야 할까? 이러한 문제를 해결하기 위해서는 document
에 이벤트를 작성해 주어야 한다.
즉, 문서 페이지의 내용이 변경시(터보링크를 클릭하여 현재 페이지의 title
과 body
가 업데이트될 때) 동작하는 자바스크립트를 작성해 주면 된다. 아래의 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)
- Gemfile에서
gem 'turbolinks'
코드라인을 제거한다. app/assets/javascripts/application.js
파일에서//= require turbolinks
코드라인을 제거한다.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
젬을 추가하면 터보링크를 접속할 경우 자바스크립트로 바인딩된 부분이 작동하지 않는 문제점을 쉽게 해결할 수 있다. 우선 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)
<body>
···
<div class='loading-indicator'>로딩중...</div>
···
</body>
이제 브라우저에서 터보링크를 클릭하거나 리로딩하면 페이지 상단에 터보링크가 작동함을 알려주는 “로딩중…”이라는 표시가 보일 것이다.