Railsアプリ開発環境の高速化
by
Takashi Kokubun
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
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 • ΞηοτϓϦίϯύΠϧʹ2356ඵ͔͔Δ • 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 8SJDL 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
ฒྻίϯύΠϧ 2356ඵ 90ඵ ΞηοτϓϦίϯύΠϧʹ͔͔Δ࣌ؒ
Slide 36
Slide 36 text
• લճطʹίϯύΠϧࡁΈͷͷΛ࠶ར༻͢Δ • ௨ৗ௨ΓϑΝΠϧΩϟογϡΛ༗ޮʹͨ͠ • ಠࣗύονͷӨڹͰલճίϯύΠϧ࣌ͷΩϟογϡΛ͏ͱ յΕΔͷͰΘͳ͘ͳ͍ͬͯͨ • ৽͍͠SprocketsΛݟΔݶΓΩϟογϡͷget/set࣌ʹflock(2) Λ͑ಈ͖ͦ͏ͩͬͨͷͰͦ͏ͨ͠ ࠩίϯύΠϧ
Slide 37
Slide 37 text
ࠩίϯύΠϧ લճ͔Β͕ࠩͳ͍߹ 90ඵ 112ඵ ΞηοτϓϦίϯύΠϧʹ͔͔Δ࣌ؒ
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ͷಋೖ Ωϟογϡͳ͠ͷॳճͷΈ 90ඵ 558ඵ ΞηοτϓϦίϯύΠϧʹ͔͔Δ࣌ؒ
Slide 40
Slide 40 text
ΞΠσΞ • Ωϟογϡͳ͠Ͱ͘͢ΔΞΠσΞ·ͩ͋ͬͨ • Sprockets 2 ʹ͢ (558ඵ → 314ඵ) • Rails 5͕Sprockets 3Ҏ্ཁٻ͖ͯͨ͠ΒࠔΔ • therubyracerΛ͏ (314ඵ → 158ඵ) • Ϗϧυ֦ுࣗମ͕ෆ҆ఆͰӡ༻ίετ͕ߴ͍
Slide 41
Slide 41 text
ΞηοτϓϦίϯύΠϧ࣌ؒͷվળ݁Ռ 2356ඵ 112ඵ ΞηοτϓϦίϯύΠϧʹ͔͔Δ࣌ؒ ࠷ 558ඵ ࠷
Slide 42
Slide 42 text
݁ • σϑΥϧτͷઃఆʹै͠ɺRubygem࠷৽ͷͷΛͬͯ ͍Εී௨ࠔΒͳ͍ • ୭͔͕ࠔͬͯupstreamΛ͢͠ɺࣗͦ͏͖͢ • ͦΕͰͲ͏ʹͳΒͳ͍࣌ɺຊʹඞཁͳॴʹݶΓࣃΛ ৯͍ͬͯ͠ಛผͳઃఆgemΛಋೖ͢Δ