Slide 1

Slide 1 text

Chrome ͷ marquee ཁૉ͕ ༏लͩͬͨ࿩ 2018-03-29 / Meguro.es #14 @wadackel

Slide 2

Slide 2 text

ࣗݾ঺հ @wadackel / Θͩ ͭΑ͠ tsuyoshiwada https://blog.wadackel.me • Go Ͱ CHANGELOG δΣωϨʔλ࡞ͬͨΓ • Storybook ͱ Puppeteer ͰεΫϦʔϯγϣοτࡱͬͨΓ • CyberAgent, Inc. Ͱಇ͍͍ͯͨΓ͠·͢

Slide 3

Slide 3 text

·ͣ࢝Ίʹ͓அΓͰ͕͢…

Slide 4

Slide 4 text

marquee ཁૉ͸طʹ ഇࢭ͞Ε͍ͯΔͨΊ ࢖Θͳ͍Α͏ʹ͠·͠ΐ͏ օ͞Μ͝ଘ஌ͷ௨Γ 00000002 ਓੜ ౓໨ͷ-5 8FMDPNF৺͔Β׻ܴ

Slide 5

Slide 5 text

marquee ཁૉͷ͓͞Β͍ HTML ্ͰςΩετ͕εΫϩʔϧ͢ΔྖҬΛ ࡞Δɻࢦఆͨ͠ଐੑʹԠͯ͡ɺςΩετ͕Ξ χϝʔγϣϯ͠ͳ͕ΒϨϯμϦϯά͞ΕΔɻ ʮ͍ͭ͜……ಈͧ͘ʂʯ

Slide 6

Slide 6 text

͔͜͜Β͕ຊ୊ɻ marquee in Chrome ͷ Ͳ͕͜༏लͳͷ ʁ

Slide 7

Slide 7 text

Chrome ͱ Firefox Ͱ marquee ͷಈ࡞Λൺֱͯ͠Έ·͠ΐ͏ https://developer.mozilla.org/ja/docs/Web/HTML/Element/marquee MDN web docs ͷ DEMO

Slide 8

Slide 8 text

Firefox ͸ʮΧΫΧΫʯ ͱ ςΩετ͕εΫϩʔϧ͞ΕΔ

Slide 9

Slide 9 text

Chrome ͸Կނ͔ ʮψϧψϧʯ ͱಈ͘

Slide 10

Slide 10 text

͜Ε೗Կʹʁ

Slide 11

Slide 11 text

Ͳ͏ͤ Chrome ͷ ϨϯμϦϯάΤϯδϯ͕༏लͱ͔ ͦΜͳ࿩Ͱ͠ΐʁ

Slide 12

Slide 12 text

ͱɺࡶͳղऍͰࡁ·ͣ͞ʹ ϒϥ΢βͷιʔείʔυΛ ௥ͬͯΈΔ

Slide 13

Slide 13 text

·ͣ͸ Firefox ͷ ϨΠΞ΢τΤϯδϯͰ͋Δ Gecko ͔Β

Slide 14

Slide 14 text

Ξχϝʔγϣϯ͕։࢝͞Εͯ ͍ΔͩΖ͏෦෼ ࢀߟNP[JMMBHFDLPMBZPVUTUZMFYCMNBSRVFFYCMNBSRVFFYNM

Slide 15

Slide 15 text

Ξχϝʔγϣϯ͕։࢝͞Εͯ ͍ΔͩΖ͏෦෼ ࢀߟNP[JMMBHFDLPMBZPVUTUZMFYCMNBSRVFFYCMNBSRVFFYNM setTimeout() Λ࢖ͬͯ _doMove() Λݺͼग़ͯ͠Δ

Slide 16

Slide 16 text

_doMove() Λ௥ͬͯΈΔ ࢀߟNP[JMMBHFDLPMBZPVUTUZMFYCMNBSRVFFYCMNBSRVFFYNM

Slide 17

Slide 17 text

_doMove() Λ௥ͬͯΈΔ ࢀߟNP[JMMBHFDLPMBZPVUTUZMFYCMNBSRVFFYCMNBSRVFFYNM ཁૉͷ scrollTop, scrollLeft ʹ ࢉग़ͨ͠࠲ඪ஋Λࢦఆ͍ͯ͠Δ

Slide 18

Slide 18 text

ૉ௚ͳ࣮૷͕ͩʮΧΫΧΫʯ ͢Δͷ΋ೲಘͷ಺༰ • setTimeout() ͰϧʔϓΛൃੜͤͯ͞Ξχϝʔγϣϯͤͯ͞Δ - ϧʔϓͱϒϥ΢βͷ࠶ඳըλΠϛϯά͕Ұக͠ͳ͍ • ֤ϧʔϓͰͷ࠲ඪΛٻΊͯ scrollTop, scrollLeft ʹ୅ೖ͠Ҡಈ͍ͤͯ͞Δ - ϨΠΞ΢τͷ࠶ܭࢉ͕ൃੜ͢Δ ※ಈ࡞͕ JS Ͱ࣮૷͞Ε͍ͯͨͷ͕ɺݸਓతʹ͸ҙ֎ͩͬͨ

Slide 19

Slide 19 text

Ͱ͸ຊ໋

Slide 20

Slide 20 text

Chrome վΊ Chromium ͷ ࣮૷Λ೷͘

Slide 21

Slide 21 text

Ξχϝʔγϣϯ͕։࢝͞Εͯ ͍ΔͩΖ͏ίʔυ෦෼ void HTMLMarqueeElement::start() { if (continue_callback_request_id_) return; RequestAnimationFrameCallback* callback = new RequestAnimationFrameCallback(this); continue_callback_request_id_ = GetDocument().RequestAnimationFrame(callback); } ࢀߟDISPNJVNUIJSE@QBSUZ8FC,JU4PVSDFDPSFIUNM)5.-.BSRVFF&MFNFOUDQQ

Slide 22

Slide 22 text

Ξχϝʔγϣϯ͕։࢝͞Εͯ ͍ΔͩΖ͏ίʔυ෦෼ void HTMLMarqueeElement::start() { if (continue_callback_request_id_) return; RequestAnimationFrameCallback* callback = new RequestAnimationFrameCallback(this); continue_callback_request_id_ = GetDocument().RequestAnimationFrame(callback); } ࢀߟDISPNJVNUIJSE@QBSUZ8FC,JU4PVSDFDPSFIUNM)5.-.BSRVFF&MFNFOUDQQ requestAnimationFrame Λ ࢖ͬͯΔͬΆ͍!!

Slide 23

Slide 23 text

֤ඳըϑϨʔϜͷॲཧΛ ௥ͬͯΈΔ void HTMLMarqueeElement::ContinueAnimation() { // ... લॲཧ (௕͍ͷͰলུ) AnimationParameters parameters = GetAnimationParameters(); int scroll_delay = scrollDelay(); int scroll_amount = scrollAmount(); // ... ࣮ࡍʹ࠲ඪΛద༻ͨ͠Γͯ͠Δ (௕͍ͷͰলུ) } ࢀߟDISPNJVNUIJSE@QBSUZ8FC,JU4PVSDFDPSFIUNM)5.-.BSRVFF&MFNFOUDQQ

Slide 24

Slide 24 text

֤ඳըϑϨʔϜͷॲཧΛ ௥ͬͯΈΔ void HTMLMarqueeElement::ContinueAnimation() { // ... લॲཧ (௕͍ͷͰলུ) AnimationParameters parameters = GetAnimationParameters(); int scroll_delay = scrollDelay(); int scroll_amount = scrollAmount(); // ... ࣮ࡍʹ࠲ඪΛద༻ͨ͠Γͯ͠Δ (௕͍ͷͰলུ) } ࢀߟDISPNJVNUIJSE@QBSUZ8FC,JU4PVSDFDPSFIUNM)5.-.BSRVFF&MFNFOUDQQ Կ΍ΒΞχϝʔγϣϯ༻ͷ ύϥϝʔλΛ࡞͍ͬͯΔ

Slide 25

Slide 25 text

AnimationParameters ͷ ੜ੒ʹഭΔ HTMLMarqueeElement::GetAnimationParameters() { AnimationParameters parameters; Metrics metrics = GetMetrics(); // ... ௕͍ͨΊলུ!! parameters.transform_begin = CreateTransform(-metrics.content_width); parameters.transform_end = CreateTransform(metrics.marquee_width); // ... ௕͍ͨΊলུ!! } ࢀߟDISPNJVNUIJSE@QBSUZ8FC,JU4PVSDFDPSFIUNM)5.-.BSRVFF&MFNFOUDQQ

Slide 26

Slide 26 text

AnimationParameters ͷ ੜ੒ʹഭΔ HTMLMarqueeElement::GetAnimationParameters() { AnimationParameters parameters; Metrics metrics = GetMetrics(); // ... ௕͍ͨΊলུ!! parameters.transform_begin = CreateTransform(-metrics.content_width); parameters.transform_end = CreateTransform(metrics.marquee_width); // ... ௕͍ͨΊলུ!! } ࢀߟDISPNJVNUIJSE@QBSUZ8FC,JU4PVSDFDPSFIUNM)5.-.BSRVFF&MFNFOUDQQ Transform?? Λ࡞͍ͬͯΔΆ͍

Slide 27

Slide 27 text

͞Βʹ͞Βʹ CreateTransform ʹഭΔ AtomicString HTMLMarqueeElement::CreateTransform(double value) const { char axis = IsHorizontal() ? 'X' : 'Y'; return String::Format("translate%c(", axis) + String::NumberToStringECMAScript(value) + "px)"; } ࢀߟDISPNJVNUIJSE@QBSUZ8FC,JU4PVSDFDPSFIUNM)5.-.BSRVFF&MFNFOUDQQ

Slide 28

Slide 28 text

͞Βʹ͞Βʹ CreateTransform ʹഭΔ AtomicString HTMLMarqueeElement::CreateTransform(double value) const { char axis = IsHorizontal() ? 'X' : 'Y'; return String::Format("translate%c(", axis) + String::NumberToStringECMAScript(value) + "px)"; } ࢀߟDISPNJVNUIJSE@QBSUZ8FC,JU4PVSDFDPSFIUNM)5.-.BSRVFF&MFNFOUDQQ CSS ϓϩύςΟͰ͋Δ Transform ͷ஋Λੜ੒ͯͨ͠

Slide 29

Slide 29 text

ͦͷଞɺ ιʔείʔυΛݟͯ ؾ͍ͮͨ఺͕…

Slide 30

Slide 30 text

ཁૉͷੜ੒ॲཧ void HTMLMarqueeElement::DidAddUserAgentShadowRoot(ShadowRoot& shadow_root) { auto* style = HTMLStyleElement::Create(GetDocument(), CreateElementFlags()); style->setTextContent( ":host { display: inline-block; overflow: hidden;" "text-align: initial; white-space: nowrap; }" ":host([direction=\"up\"]), :host([direction=\"down\"]) { overflow: " "initial; overflow-y: hidden; white-space: initial; }" ":host > div { will-change: transform; }"); shadow_root.AppendChild(style); Element* mover = HTMLDivElement::Create(GetDocument()); shadow_root.AppendChild(mover); mover->AppendChild( HTMLSlotElement::CreateUserAgentDefaultSlot(GetDocument())); mover_ = mover; } ࢀߟDISPNJVNUIJSE@QBSUZ8FC,JU4PVSDFDPSFIUNM)5.-.BSRVFF&MFNFOUDQQ

Slide 31

Slide 31 text

ShadowRoot ΍Β Slot ཁૉ΍Β ݟ֮͑ͷ͋Δهड़͕୔ࢁʂ

Slide 32

Slide 32 text

ੜ੒͞ΕΔཁૉͷΠϝʔδ #shadow-root :host { display: inline-block; overflow: hidden; text-align: initial; white-space: nowrap; } :host([direction="up"]), :host([direction="down"]) { overflow: initial; overflow-y: hidden; white-space: initial; } :host > div { will-change: transform; }

Slide 33

Slide 33 text

ࢥ͍͖ͬΓ Web Components

Slide 34

Slide 34 text

Chromium ͷ marquee ࣮૷ ͸૝૾ΑΓ΋Ϟμϯͩͬͨ… • ಺෦࣮૷͸ Web Components ͩͬͨ…!! • requestAnimationFrame ʹΑΔ࠶ඳըλΠϛϯάͷ࠷దԽ - ϧʔϓͱϒϥ΢βͷ࠶ඳըλΠϛϯά͕Ұக • ֤ϧʔϓͰͷ࠲ඪ͸ CSS ͷ transform ϓϩύςΟͰ؅ཧ͞Ε͍ͯͨ - ϨΠΞ΢τͷ࠶ܭࢉ͕ى͖ͳ͍ ✨

Slide 35

Slide 35 text

·ͱΊ

Slide 36

Slide 36 text

͍ʹ͑͠ͷཁૉ͸ࢥ͍ͷ΄͔ Ϟμϯͳٕज़Ͱಈ࡞͍ͯͨ͠ • ShadowDOM ʹΑΔελΠϧͷӅṭ • requestAnimationFrame ʹΑΔΞχϝʔγϣϯͷ੍ޚ • will-change Λ࢖ͬͨΞχϝʔγϣϯͷ࠷దԽ • transform/translate Λ࢖ͬͨ࠲ඪҠಈ (ඳըෛՙ࠷దԽ) • ීஈͷ Web ϑϩϯτΤϯυ։ൃʹ௨͡Δٕज़Ͱ
 ߏ੒͞Ε͍ͯͨ • ͋͘·Ͱ Chromium ͷதͰ͸Ͷ

Slide 37

Slide 37 text

ϒϥ΢βͷ࣮૷Λ೷͘ͷ͸ ҙ֎ͱָ͍͠!! • C++ ॻ͚ͳͯ͘΋ɺงғؾͰԿͱͳ͘ॻ͍ͯ͋Δ͜ͱ͕෼͔Δ • ίϝϯτ΋ͦͦ͜͜ॻ͔Ε͍ͯΔͷͰ • ΤσΟλΛ׆༻͢Δ - $ ctags --languages=C++ ͰλάΛ࡞ͬͯ… - vim Ͱఆٛδϟϯϓͯ͠ιʔείʔυ㓢኶͢Δͱָ • ripgrep Έ͍ͨͳߴ଎ͳ grep ୅ସπʔϧ΋༗༻ • https://cs.chromium.org ΋ศར

Slide 38

Slide 38 text

ϒϥ΢β࣮૷ݟΔͷ͸ ͜Ε͕ॳΊͯͰͨ͠… ޡΓͳͲ͋Γ·ͨ͠Βɺ༏͘͠ڭ͍͑ͯͨͩ ͚Δͱ޾͍Ͱ͢

Slide 39

Slide 39 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠