Slide 1

Slide 1 text

3BJMTΞϓϦ։ൃ؀ڥͷߴ଎Խ !LLVCVO $PPLQBE5FDI$POG

Slide 2

Slide 2 text

ࣗݾ঺հ • ࠃ෼ਸࢤ • GitHub, Twitter: @k0kubun • ٕज़෦։ൃج൫άϧʔϓ • ։ൃج൫ͷӡ༻ • ։ൃޮ཰ͷ޲্

Slide 3

Slide 3 text

ΞδΣϯμ • ͳͥ։ൃ؀ڥͷߴ଎Խ͕ඞཁ͔ • ߴ଎ԽͷͨΊʹԿΛ͔ͨ͠ • RailsΞϓϦͷDOMContentLoaded • ΞηοτϓϦίϯύΠϧ

Slide 4

Slide 4 text

ͳͥ։ൃ؀ڥͷߴ଎Խ͕ඞཁ͔ ͳͥ։ൃ؀ڥͷߴ଎Խ͕ඞཁ͔ ߴ଎ԽͷͨΊʹԿΛ͔ͨ͠ 3BJMTΞϓϦͷ%0.$POUFOU-PBEFE ΞηοτϓϦίϯύΠϧ

Slide 5

Slide 5 text

ΫοΫύουͷշదͳ։ൃ؀ڥ • ػೳ։ൃ • ߴ଎ͳϓϩτλΠϐϯά Chanko (@eudoxa, @r7kamura)

Slide 6

Slide 6 text

ΫοΫύουͷշదͳ։ൃ؀ڥ • ػೳ։ൃ • ߴ଎ͳϓϩτλΠϐϯά Chanko • ຊ൪͔ΒϨϓϦ͞ΕΔ։ൃ༻DB (@eudoxa, @r7kamura) (@adorechic, @sorah)

Slide 7

Slide 7 text

ΫοΫύουͷշదͳ։ൃ؀ڥ • ػೳ։ൃ • ߴ଎ͳϓϩτλΠϐϯά Chanko • ຊ൪͔ΒϨϓϦ͞ΕΔ։ൃ༻DB • ςετ࣮ߦ • ෼ࢄRSpec࣮ߦ RRRSpec (@eudoxa, @r7kamura) (@adorechic, @sorah) (@draftcode, @eagletmt)

Slide 8

Slide 8 text

ΫοΫύουͷշదͳ։ൃ؀ڥ • ػೳ։ൃ • ߴ଎ͳϓϩτλΠϐϯά Chanko • ຊ൪͔ΒϨϓϦ͞ΕΔ։ൃ༻DB • ςετ࣮ߦ • ෼ࢄRSpec࣮ߦ RRRSpec • σϓϩΠ • ߴ଎ͳσϓϩΠπʔϧ Mamiya (@eudoxa, @r7kamura) (@adorechic, @sorah) (@draftcode, @eagletmt) (@sorah)

Slide 9

Slide 9 text

ΞϧόΠτ࣌୅ͷࢲͷؾ࣋ͪ Q. ΫοΫύου͸։ൃ͠΍͍͔͢ʁ

Slide 10

Slide 10 text

ΞϧόΠτ࣌୅ͷࢲͷؾ࣋ͪ Q. ΫοΫύου͸։ൃ͠΍͍͔͢ʁ A. ػೳ։ൃͷͨΊͷ࢓૊Έ͕੔͍ͬͯͯɺ ςετ΋σϓϩΠ΋ߴ଎Ͱ։ൃ͠΍͍͢ …͚Ͳ։ൃ؀ڥ͕஗͍

Slide 11

Slide 11 text

3BJMTΞϓϦͷ%0.$POUFOU-PBEFE • Կ͔มߋͯ͠Ϧϩʔυ͢Δͱ16.2ඵ଴ͨ͞ΕΔ ʢϨγϐݕࡧϖʔδͷDOMContentLoadedʣ

Slide 12

Slide 12 text

3BJMTΞϓϦͷ%0.$POUFOU-PBEFE • ผʹมߋՃ͑ͯͳͯ͘΋10.3ඵ଴ͨ͞ΕΔ

Slide 13

Slide 13 text

DPPLQBEDPNͷΞηοτϓϦίϯύΠϧ $ time rake assets:precompile 1436.01 real 1092.28 user 338.06 sys • ΞηοτϓϦίϯύΠϧʹ23෼56ඵ͔͔Δ • 2.5 GHz Inel Core i7, SSD Ͱͷܭଌ

Slide 14

Slide 14 text

ΞηοτϓϦίϯύΠϧ͕஗͍ͱԿ͕ࠔΔ͔ • CI͕஗͘ͳΔ • CIͰຊ൪σϓϩΠ༻ͷΞηοτΛࣄલʹίϯύΠϧ͍ͯ͠ ΔͨΊ • εςʔδϯά؀ڥ΁ͷσϓϩΠ͕஗͘ͳΔ • ຊ൪؀ڥҎ֎΁ͷσϓϩΠͰ͸σϓϩΠ࣌ʹίϯύΠϧ͠ ͍ͯΔͨΊ

Slide 15

Slide 15 text

ͳͥ։ൃ؀ڥͷߴ଎Խ͕ඞཁ͔ • ։ൃ؀ڥ͕஗ͯ͘։ൃ͠ʹ͍͘ͱɺૉૣ͘Ձ஋Λ ಧ͚Δ͜ͱ͕Ͱ͖ͳ͍͔Β

Slide 16

Slide 16 text

3BJMTΞϓϦͷ%0.$POUFOU-PBEFE ͳͥ։ൃ؀ڥͷߴ଎Խ ߴ଎ԽͷͨΊʹԿΛ͔ͨ͠ 3BJMTΞϓϦͷ%0.$POUFOU-PBEFE .Z42- 4PMS ($ "TTFU ΞηοτϓϦίϯύΠϧ ߴ଎ԽͷͨΊʹԿΛ͔ͨ͠

Slide 17

Slide 17 text

3BJMTΞϓϦߴ଎ԽͰ৮ΕΔτϐοΫ • 1. MySQL • 2. Solr • 3. GC • 4. Asset

Slide 18

Slide 18 text

3BJMTΞϓϦߴ଎Խ.Z42- • ActiveRecordͷDBΞμϓλʔͷϨΠϠʔͰSELECTΫΤϦͷ ݁ՌΛMemcachedʹΩϟογϡ • INSERT, DELETE, UPDATE͕૸ͬͨΒJOIN΋ߟྀͯ͠Ωϟ ογϡΛΫϦΞ • εΩʔϚ΍σʔλΛ௚઀มߋ͠ͳ͕Β։ൃ͢Δ৔߹͸ແޮʹ ͢Δ ࢪࡦ: cookpad/reuse_query_results (@eudoxa)

Slide 19

Slide 19 text

3BJMTΞϓϦߴ଎Խ.Z42- ։ൃ؀ڥʹ͓͚ΔݕࡧϖʔδͷDOMContentLoaded 10,300ms 9,520ms ࢪࡦ: cookpad/reuse_query_results (@eudoxa)

Slide 20

Slide 20 text

3BJMTΞϓϦߴ଎Խ4PMS • SunspotʹΑΔSolr΁ͷΫΤϦͷ݁ՌΛΩϟογϡ͢Δ • ݩʑݕࡧΠϯσοΫε͸όονॲཧ͞Ε͍ͯͯߋ৽ස౓͕ߴ͘ ͳ͍ͷͰɺΩϟογϡΛഁغ͠ͳ͍ • SunspotपΓͷ։ൃΛ͢Δ৔߹͸ແޮʹ͢Δ ࢪࡦ: Cache sunspot result (@adorechic)

Slide 21

Slide 21 text

3BJMTΞϓϦߴ଎Խ4PMS ࢪࡦ: Cache sunspot result (@adorechic) ։ൃ؀ڥʹ͓͚ΔݕࡧϖʔδͷDOMContentLoaded 9,520ms 8,990ms

Slide 22

Slide 22 text

3BJMTΞϓϦߴ଎Խ($ • ϦΫΤετॲཧதʹGC͕΄ͱΜͲ૸Βͳ͍Α͏ʹ͢Δ • WEBrickʹϞϯΩʔύον͢ΔͷΛආ͚ૄ݁߹ʹ͢ΔͨΊɺ Rack middleware ͰεΠον͢Δ • Ruby 2.0.0Λ࢖͍ͬͯͨ౰࣌͸ޮՌ͕͕͋ͬͨɺ2.2Ͱ͸ࠩ ͕খ͘͞ͳ͍ͬͯͨ • ࠷৽ͷRuby࢖͏ͷେࣄ ࢪࡦ: GC.disable

Slide 23

Slide 23 text

3BJMTΞϓϦߴ଎Խ($ 3BDL)BOEMFS 8&#SJDL 3BDLBQQMJDBUJPO 3BJMT 3BDLNJEEMFXBSFT 3FRVFTU 3FTQPOTF ($EJTBCMF ($FOBCMF ($ࢭΊΔ3BDLNJEEMFXBSF ࢪࡦ: GC.disable

Slide 24

Slide 24 text

3BJMTΞϓϦߴ଎Խ($ ࢪࡦ: GC.disable ։ൃ؀ڥʹ͓͚ΔݕࡧϖʔδͷDOMContentLoaded 8,990ms 6,310ms

Slide 25

Slide 25 text

3BJMTΞϓϦߴ଎Խ"TTFU • config.assets.digest = true ʹ͢Δ͚ͩ (Railsඪ४) • Cache-Control: no-cache → public, max-age=31536000 • ͨͩ͠ Sprockets 2 ͩͱ 304 ࣌ʹ no-cache ʹͳΔ • ࠷৽ͷgemΛ࢖͍ඪ४ͷઃఆʹै͓ͬͯ͘ͱupstream͔Β ྑ͍ԸܙΛड͚ΒΕΔ ࢪࡦ1: ΞηοτͷϦΫΤετΛϒϥ΢βͰΩϟογϡ

Slide 26

Slide 26 text

3BJMTΞϓϦߴ଎Խ"TTFU ࢪࡦ1: ΞηοτͷϦΫΤετΛϒϥ΢βͰΩϟογϡ ։ൃ؀ڥʹ͓͚ΔݕࡧϖʔδͷDOMContentLoaded 6,310ms 4,910ms

Slide 27

Slide 27 text

3BJMTΞϓϦߴ଎Խ"TTFU • Ͳͷϖʔδ΋ڞ௨ͰಡΈࠐΜͰΔେ͖ͳౕ͚ͩ੾Δ • stylesheet_link_tag '...', debug: false • javascript_include_tag '...', debug: false • require਺ͱಉ͡਺͚ͩ͋Δscriptλά͕1ͭʹͳΔ • debug: false ʹ͢ΔͱϓϦίϯύΠϧର৅ʹೖ͍ͬͯΔ͔ͳͲ ͷ֬ೝΛͯ͘͠Εͳ͘ͳΔͷͰɺςετͰ֬ೝ͢ΔΑ͏ʹͨ͠ ࢪࡦ2: sprockets-railsͷσόοάػೳΛ੾Δ

Slide 28

Slide 28 text

3BJMTΞϓϦߴ଎Խ"TTFU ࢪࡦ2: sprockets-railsͷσόοάػೳΛ੾Δ

Slide 29

Slide 29 text

3BJMTΞϓϦߴ଎Խ"TTFU ࢪࡦ2: sprockets-railsͷσόοάػೳΛ੾Δ ։ൃ؀ڥʹ͓͚ΔݕࡧϖʔδͷDOMContentLoaded 4,910ms 3,790ms

Slide 30

Slide 30 text

3BJMTΞϓϦߴ଎Խݱঢ় ·ͩ·ͩ஗͍ͷͰվળ͕ඞཁ ։ൃ؀ڥʹ͓͚ΔݕࡧϖʔδͷDOMContentLoaded 10,300ms 3,790ms

Slide 31

Slide 31 text

ΞηοτϓϦίϯύΠϧ ͳͥ։ൃ؀ڥͷߴ଎Խ ߴ଎ԽͷͨΊʹԿΛ͔ͨ͠ 3BJMTΞϓϦͷ%0.$POUFOU-PBEFE ΞηοτϓϦίϯύΠϧ ฒྻίϯύΠϧ ࠩ෼ίϯύΠϧ MJCTBTTͷಋೖ ຅ΞΠσΞ ߴ଎ԽͷͨΊʹԿΛ͔ͨ͠

Slide 32

Slide 32 text

Ͳ͕͜஗͍͔ • ֤֦ுࢠʹର͔͔͍ͯͬͯ͠Δ࣌ؒͷ߹ܭΛܭଌ • .css: 71.0% • .js: 22.6% • 1ճͷίϯύΠϧͰԿʹ࣌ؒΛ࢖͍ͬͯΔ͔ • 70%: sass.gem ΍ execjs.gem (nodejs runtime) • 30%: શΞηοτڞ௨ͷॲཧ (Sprockets)

Slide 33

Slide 33 text

ΞηοτϓϦίϯύΠϧߴ଎ԽͷτϐοΫ • 1. ฒྻίϯύΠϧ • 2. ࠩ෼ίϯύΠϧ • 3. libsassͷಋೖ • 4. ຅ΞΠσΞ

Slide 34

Slide 34 text

• Sprockets ΁ͷੲ͔Βͷಠࣗύον • parallel.gemͰϚϧνϓϩηείϯύΠϧ • Ωϟογϡ͕ฒྻॲཧʹ଱͑Δ͔ߟ͑Δඞཁ͋Γ • gemԽͯ͠ΔͷΛ࢖͍͍ͨ৔߹ • sprockets-derailleur.gem ͱ͍͏ͷ͕͋Δ (ผ෺) ฒྻίϯύΠϧ (@os0x, @mrkn, @eagletmt, @k0kubun)

Slide 35

Slide 35 text

ฒྻίϯύΠϧ 23෼56ඵ 9෼0ඵ ΞηοτϓϦίϯύΠϧʹ͔͔Δ࣌ؒ

Slide 36

Slide 36 text

• લճطʹίϯύΠϧࡁΈͷ΋ͷΛ࠶ར༻͢Δ • ௨ৗ௨ΓϑΝΠϧΩϟογϡΛ༗ޮʹͨ͠ • ಠࣗύονͷӨڹͰલճίϯύΠϧ࣌ͷΩϟογϡΛ࢖͏ͱ յΕΔͷͰ࢖Θͳ͘ͳ͍ͬͯͨ • ৽͍͠SprocketsΛݟΔݶΓΩϟογϡͷget/set࣌ʹflock(2) Λ࢖͑͹ಈ͖ͦ͏ͩͬͨͷͰͦ͏ͨ͠ ࠩ෼ίϯύΠϧ

Slide 37

Slide 37 text

ࠩ෼ίϯύΠϧ લճ͔Βࠩ෼͕ͳ͍৔߹ 9෼0ඵ 1෼12ඵ ΞηοτϓϦίϯύΠϧʹ͔͔Δ࣌ؒ

Slide 38

Slide 38 text

• libsass: sassͷC++࣮૷ • sassc-ruby, sassc-rails͔Β࢖͑Δ • Sprockets 4Ͱඪ४αϙʔτ • ΄΅sass 3.4ޓ׵ͳͷͰsass 3.4ʹҠߦͰ͖ͯclang͔gcc 4.6 Ҏ্͕࢖͑Ε͹ಈ͘ MJCTBTTͷಋೖ

Slide 39

Slide 39 text

MJCTBTTͷಋೖ Ωϟογϡͳ͠ͷॳճͷΈ 9෼0ඵ 5෼58ඵ ΞηοτϓϦίϯύΠϧʹ͔͔Δ࣌ؒ

Slide 40

Slide 40 text

຅ΞΠσΞ • Ωϟογϡͳ͠Ͱ଎͘͢ΔΞΠσΞ͸·ͩ͋ͬͨ • Sprockets 2 ʹ໭͢ (5෼58ඵ → 3෼14ඵ) • Rails 5͕Sprockets 3Ҏ্ཁٻ͖ͯͨ͠ΒࠔΔ • therubyracerΛ࢖͏ (3෼14ඵ → 1෼58ඵ) • Ϗϧυ΍֦ுࣗମ͕ෆ҆ఆͰӡ༻ίετ͕ߴ͍

Slide 41

Slide 41 text

ΞηοτϓϦίϯύΠϧ࣌ؒͷվળ݁Ռ 23෼56ඵ 1෼12ඵ ΞηοτϓϦίϯύΠϧʹ͔͔Δ࣌ؒ ࠷୹ 5෼58ඵ ࠷௕

Slide 42

Slide 42 text

݁࿦ • σϑΥϧτͷઃఆʹ௥ै͠ɺRuby΍gem͸࠷৽ͷ΋ͷΛ࢖ͬͯ ͍Ε͹ී௨͸ࠔΒͳ͍ • ୭͔͕ࠔͬͯupstreamΛ௚͢͠ɺࣗ෼΋ͦ͏͢΂͖ • ͦΕͰ΋Ͳ͏ʹ΋ͳΒͳ͍࣌͸ɺຊ౰ʹඞཁͳ৔ॴʹݶΓࣃΛ ৯͍͠͹ͬͯಛผͳઃఆ΍gemΛಋೖ͢Δ