Download - Tenjin - the fastest template engine in the world

Transcript
Page 1: Tenjin - the fastest template engine in the world

The Fastest Template Engine in the World

Makoto Kuwatahttp://www.kuwata-lab.com/

Tenjin

YAPC::ASIA 20081

Page 2: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Agenda

‣ Introduction

‣ Features

‣ Preprocessing

‣ Conclusion

2

Page 3: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Introduction

YAPC::ASIA 20083

Page 4: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Tenjin - a template engine‣ Very fast•About x5 faster than Template-Toolkit

‣ Full-featured•Layout, partial, capturing, ...

‣ Easy to use•You can get all power of Perl

‣ Multi-language•Perl, Python, Ruby, PHP, JavaScript

4

Page 5: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Example (html template)

<table> <?pl my $i = 0; ?> <?pl for my $item (@$items) { ?> <?pl $i++; ?> <tr> <td>[==$i=]</td> <td>[=$item=]</td> </tr> <?pl } ?> </table>

Perl statements

Perl expression

Perl expression(with html escape)

5

Page 6: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Example (converted script)

my @_buf = (); push(@_buf, q`<table>`, ); my $i = 0;for my $item (@$items) { $i++;push(@_buf, q` <tr> <td>`, $i, q`</td> <td>`, escape($item), q`</td> </tr>`, ); }push(@_buf, q`</table>`, ); join('', @_buf);

Returns joined String

Escape function is changeable

Temporary list

6

Page 7: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Example (main program)

## create engineuse Tenjin;$Tenjin::USE_STRICT=1; # optionalmy $engine = new Tenjin::Engine();

## render template with context datamy $context = { 'items' => ['<AAA>','B&B','"CCC"'] };my $output = $engine->render('ex.plhtml', $context);print $output;

Choosable to use strict or not

7

Page 8: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Example (output)<table> <tr> <td>1</td> <td>&lt;AAA&gt;</td> </tr> <tr> <td>2</td> <td>B&amp;B</td> </tr> <tr> <td>3</td> <td>&quot;CCC&quot;</td> </tr> </table>

Spaces around '<?pl .. ?>' are trimmed

[=expression=] is html escaped

8

Page 9: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Benchmark

Tenjin 10.4 5.7Template::Toolkit (XS) 103.6 26.3

HTM::Template 46.7 30.2Velocity 1.5 (Java) 20.8 8.4

Template Engine Test#1 Test#2

(sec)• Generates a 400-line HTML page 10,000 times• Test#1 generates template objects for each time (like CGI)• Test#2 uses the same template object for each time (like modperl)• Environment: MacOS X 10.4, Intel CoreDuo 1.83GHz

9

Page 10: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Benchmark

0

500

1,000

1,500

2,000

Tenjin TT H::T Velocity

Test#1 Test#2Pages/sec

10

Page 11: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Why so fast?

‣ Tenjin uses Perl as the template lang

•Perl is fast, rich, and easy to learn (because you already know it!)

‣ Other template engines have their own template languages

•Slow, poor, and you have to learn them

11

Page 12: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Impact to app speed (1)

after

before

0 25 50 75 100

M&C V

• Assume that the view-layer costs 25%.• Making view-layer 5 times faster results in a 25% speed increase.

25% faster!

75 25

75 5

12

Page 13: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Impact to app speed (2)

after

before

0 25 50 75 100

M&C V

• Assume the view-layer costs 60%.• Making the view-layer 6 times faster results in a 100% speed increase.

100% faster!

40 60

40 10

13

Page 14: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Features

YAPC::ASIA 200814

Page 15: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Features‣ Nestable layout

templates

‣ Include partial templates

‣ Capture a part of output

‣ Override a part of layout template

‣ Script cache into file & memory

‣ Template arguments

‣ Retrieve only code from template

‣ Syntax checking

15

Page 16: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Nestable layout template

<html> <body>[==$_content=] </body></html>

<div>[==$_content=]</div>

Parent layout Child layout Content

<p>Hello [=$user=]!</p>

• Nestable to any depth• Able to specify parent name in child

(useful to change the layout for a specific page)

16

Page 17: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Include partial template

<?pl $_context->{val}='Create'; ?><form action="create"><?pl include('form.plhtml'); ?></form>

create.plhtml

<?pl $_context->{val}='Update'; ?><form action="update"><?pl include('form.plhtml'); ?></form>

update.plhtml<input><select><textarea>

form.plhtml

17

Page 18: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Capture & overwrite

<?pl if (!captured_as('head')) { ?><h1>[=$title=]</h1><?pl } ?>

Layout

<?pl start_capture('head'); ?><h1 class="h1">[=$title=]</h1><?pl stop_capture(); ?>

Content

Capturing

Overwritten if captured in child template

18

Page 19: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Script cache

Template

Script(Perl,Ruby,JS,...)

Closure, Proc

Cache script into file(minimize cost of conversion)

Cache script into memory(as fast as function/method)

19

Page 20: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Template arguments

<?xml version="1.0" ?><?pl #@ARGS title, items ?><h1>[=$title=]</h1>

my @_buf=(); push(@_buf, ...);my $title = $_context->{title}; my $items = $_context->{items}; push(@_buf, ...);

Script

Template

20

Page 21: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Retrieve code

<table><?pl my $i = 0; ?><?pl for my $item in (@$items) { ?><?pl $i += 1; ?> <tr> <td>[==$i=]</td> <td>[=$item=]</td> </tr><?pl } ?></table>

$ cat file.plhtml

21

Page 22: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Retrieve code

my $i = 0; for my $item in (@$items) { $i += 1;

$i; escape($item);

}

$ pltenjin -bS file.plhtml

Retrieve only Perl code

22

Page 23: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Retrieve code

my $i = 0; for my $item in (@$items) { $i += 1;

}

$ pltenjin -bX file.plhtml

Retrieve only statements

23

Page 24: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Retrieve code

1: 2: my $i = 0; 3: for my $item in (@$items) { 4: $i += 1; 5: 6: 7: 8: 9: }10:

$ pltenjin -bXN file.plhtml

Add line numbers

24

Page 25: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Retrieve code

1: 2: my $i = 0; 3: for my $item in (@$items) { 4: $i += 1;

9: }

$ pltenjin -bXU file.plhtml

Compress empty lines

25

Page 26: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Preprocessing

YAPC::ASIA 200826

Page 27: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

What is Preprocessing?

Template

Script(Perl,Ruby,JS,...)

Output(html)

convert

render

Logics are executedwhen rendering

Execute some logicswhen conversion(preprocessing)

27

Page 28: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Stages

<p>[=$DOMAIN=]</p> <p>[*=$DOMAIN=*]</p>

preprocess

convert

<p>example.com</p>

push(@_buf, q`<p>`, $DOMAIN, q`</p>`, );

render

<p>example.com</p>

convert

push(@_buf, q`<p>example.com</p>`, );

preprocessing disabled preprocessing enabled

render

<p>example.com</p>

28

Page 29: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Merits & Demerits

‣ Merits

• Makes view-layer much faster

• Removes costs of I18N/L10N, helper functions, and so on.

‣ Demerits

• Complex

• Hard to debug (line number will be changed)

• Expensive learning cost

29

Page 30: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Notation

‣ <?PL ...statements... ?>

‣ [*== ...expression... =*]

‣ [*= ...expr (with html escape)... =*]

‣ _p("expression"), _P("expression")•returns "[=expression=]", "[==expression=]"

30

Page 31: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

I18N & L10NTemplate

Preprocessed

[=i18n('Hello')=] [=$name=]![*=i18n('Hello')=*] [=$name=]!

[=i18n('Hello')=] [=$name=]!こんにちは [=$name=]!

push(@_buf, i18n('Hello'), ' ', $name, '!こんにちは ', $name, '!', ); ...

Converted Script

Remove I18N overhead

preprocess

convert

31

Page 32: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Helper functions[*= link_to(_P('$item->{name}'), { action=>'show', id=>_p('$item->{id}') }) =*]

<a href="/items/show/[==$item->{id}=]"> [=$item->{name}=]</a>

Eliminates cost of helper funcions

_p('x') <=> [=x=], _P('x') <=> [==x=]

Template

Preprocessedpreprocess

32

Page 33: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Loop expansionTemplate

Preprocessed

<select><?PL my $i = 0; ?><?PL for my $m (@$months) { ?> <option value="[[==++$i=]]">[[=$m=]]</option><?PL } ?></select>

<select> <option value="1">January</option> <option value="2">February</option> <option value="3">March</option> ...</select> Expanded BEFORE rendering

preprocessExecuted at conversion statge

33

Page 34: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Mixed preprocessing(1)Template

<select><?pl my %h = ($params->{month} => ' selected'); ?><?PL my $i = 0; ?><?PL for my $m (@$months) { ?> <option value="[*==++$i=*]"[==$h{[*==$i=*]}=]>[*=$m=*]</option><?PL } ?></select> Mixed preprocessing

34

Page 35: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Mixed preprocessing(2)Preprocessed

<select><?pl my %h = ($params->{month} => ' selected'); ?> <option value="1"[==$h{1}=]>January</option> <option value="2"[==$h{2}=]>February</option> <option value="3"[==$h{3}=]>March</option> ...</select>

Non-preprocessing code is leaved

35

Page 36: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Conclusion

YAPC::ASIA 200836

Page 37: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Conclusion (1)

‣ Tenjin - a fast template engine•Very fast & lightweight

•Full-featured

•Easy to use

•Preprocessing

•Available in multi-language

•http://www.kuwata-lab.com/tenjin/

37

Page 38: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Conclusion (2)

‣ Template-original lang is bad idea•Slow, poor, complicated

•High cost to learn

‣ Perl itself is the best template lang

•Fast, rich, simple

•You already know it very well!

38

Page 39: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Any questions?

39

Page 40: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

One more minute...

40

Page 41: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Kwartz - Designer Friendly Template System

<?xml ver="1.0" ?><html><body><table> <tr id="mark:list1"> <td id="mark:item1">foo</td> </tr></table></body></html>

#list1 { logic: { for my $item (@$items) { _stag; # start tag _cont; # content _etag; # end tag } }}

#item1 { value: $item; # print value}

template file presentation logic file

Plain Old HTML CSS-like Syntax

Interested?Go http://www.kuwata-lab.com/kwartz/

41

Page 42: Tenjin - the fastest template engine in the world

copyright(c) 2008 kuwata-lab.com all rights reserved.

Thank You

42