javascript - behind the scene

javascript - behind the scene

javascriptのロードからパースまでの仕組みと最適化について

Transcript

  1. Javascript Behind the scene

  2. Name !CSO 5BLFUPTIJ"POP੨໺݈ར  Occupation 'SPOUFOE%FWFMPQFS1SPEVDU0XOFS Company $ZCFSBHFOU"EUFDI4UVEJP"*.FTTFOHFS OSS $POUSJCVUPSPG7

    About IUUQJOGPCODI
  3. ຊ೔࿩͢಺༰ ϒϥ΢β͸ͲͷΑ͏ʹJavascriptΛऔಘͯ͠ύʔε͢Δͷ͔ ͦͯ͠զʑ͸Ͳ͏࠷దԽ͢΂͖͔ʁ ͳΜͯݴ͍ͭͭ໨৽͍͜͠ͱ͸ແ͍Ͱ͢… ͋ͱ࣮ߦ࣌ͷ࿩͸࣌ؒͷؔ܎্͠·ͤΜ

  4. Script Critical Path

  5.  Parse HTML Fetch Resources Parse and evaluate script

  6.  Parse HTML Fetch Resources Parse and evaluate script

  7. Resource Fetching

  8. Script Types Scriptʹ͸2ͭͷछྨͱ3ͭͷϑϥά͕͋Δɻ classic_script / module_script blocking / defer /async

  9. Classic Script ͍ΘΏΔ௨ৗͷscriptλά ଟ͘ͷ৔߹͸ͪ͜ΒͷscriptΛ࢖͍ͬͯΔ͸ͣ

  10. Module Script Ecmascript ModuleରԠͷscript type=moduleΛઃఆ͢Δ͜ͱͰಈ࡞͢Δ Import/exportͷॲཧΛμΠφϛοΫʹߦͬͯґଘͷղܾΛ͢Δ

  11. Async scriptλάʹasyncϑϥάΛ෇༩͢Δ͜ͱͰscriptͷfetchλΠϛϯά ΛඇಉظՄ͢Δ͜ͱ͕Ͱ͖Δ ͦͷͨΊɺґଘ͋͠Θͳ͍scriptλά͸asyncͰ࣮ߦ͢Δ͜ͱ͕๬·͍͠

  12. Defer scriptλάʹdeferϑϥάΛ෇༩͢Δ͜ͱͰscriptͷ࣮ߦλΠϛϯάΛ ඇಉظԽ͢Δ͜ͱ͕Ͱ͖Δ defer͸ඞͣscriptλάͷॱংͰ࣮ߦ͞ΕΔͨΊɺscriptͷॱংΛҡ࣋ ͭͭ͠script࣮ߦλΠϛϯάΛඇಉظʹ͍ͨ͠৔߹͸ͪ͜ΒΛ࢖͏

  13. Behind the scene Connection

  14. Create TCP Connection per resource ScriptϑΝΠϧͷϩʔυͷͨΊʹϒϥ΢β͸scriptλάͷsrc͔Βϩʔυ ͢΂͖ϦιʔεΛ୳͠ αʔό΁ϦΫΤετΛ౤͛Δ

  15. Optimization

  16. Limit of TCP Connection count per server HTTP1.1Λར༻͢Δ৔߹ɺࠓͷॴϒϥ΢β୯ҐͰಉ࣌઀ଓ੍ݶ͕ଘࡏ͢Δ ͦͷͨΊasync/deferଐੑΛར༻ͯ͠΋֎෦Ϧιʔε਺ͷ੍ݶʹҾ͔ͬ ͔ͬͨ৔߹ʹ͸଴͕ͪ࣌ؒൃੜ͢Δ

  17. HTTP1.0 Connection limitation Queued

  18. HTTP1.0 Connection limitation

  19. TCP Connection limits for HTTP1.1 https://docs.pushtechnology.com/cloud/latest/manual/html/designguide/solution/support/connection_limitations.html

  20. Using HTTP2.0 HTTP2.0Λར༻͢Δ৔߹ɺHTTP2.0ͷϦΫΤετɾϨεϙϯεଟॏԽʹ ΑͬͯυϝΠϯ୯ҐͰ1ͭͷίωΫγϣϯΛ࢖͍ճͨ͢Ί HTTP1.1ͷΑ͏ͳ઀ଓ਺੍ݶ͸ͳ͘ͳͬͨ(಺෦Ͱ͸͋Δ)

  21. HTTP2.0 Multiplex connection

  22. HTTP2.0 Multiplex connection " #

  23. Behind the scene Fetching

  24. Resource fetching ϒϥ΢β͸ϦιʔεΛ࣮ࡍʹऔಘ͢Δલʹ࣍ͷΑ͏ͳಈ࡞Λߦ͏

  25. Browser resource fetching sequece Browser Cache 1. Check cache existence

    2. Check cache expiration(if max-age specified) 3. Use cache or request updated resource If cache not stored, fetch resources Response with ETag: “…”, Cache-Control: “…” Gunzip if gziped Store cache if Cache-Control value isn’t “no-store”
  26. Browser resource fetching sequece Browser Cache 1. Check cache existence

    2. Check cache expiration(if max-age specified) 3. Use cache or request updated resource If cache not stored, fetch resources Response with ETag: “…”, Cache-Control: “…” Gunzip if gziped Store cache if Cache-Control value isn’t “no-store”
  27. Browser Cache ϒϥ΢βΩϟογϡΛར༻͢Δ͜ͱͰϦΫΤετݮগɾϨεϙϯεαΠζݮ গͷԸܙΛड͚Δ͜ͱ͕Ͱ͖Δ

  28. ETag ϒϥ΢βΩϟογϡͷͨΊʹETagͱ͍͏࢓૊ΈΛ࢖͏ Cache-ControlͱETagͷ૊Έ߹ΘͤͰϦιʔεͷServerΛհͨ͠༗ޮͳΩϟογϡͷ࢓૊ΈΛ ར༻Ͱ͖Δ ϒϥ΢β͸ҎԼͷಈ࡞ΛͱΓ͏Δ - ϒϥ΢βΩϟογϡΛͦͷ··ར༻͢Δ - ϒϥ΢βΩϟογϡ͕ظݶ੾ΕͷͨΊɺϦΫΤετΛ౤͛ͯαʔό͔Β৽ͨͳϦιʔεΛऔಘ ͢Δ

    αʔό͸ҎԼͷબ୒ࢶ͕͋Δ - ETagϔομΛݟͯϦιʔε͕ߋ৽͞Ε͍ͯͳ͚Ε͹304 Not ModifiedͰϨεϙϯεແ͠ͷ ஋Λฦ͢ - ৽ͨͳϦιʔεͱETagΛฦ͢
  29. ETag: “adda4f05-9bef-4a10-9f62-9ad11f3b9498” 3FTQPOTF If-None-Match: “adda4f05-9bef-4a10-9f62-9ad11f3b9498” 3FRVFTU

  30. Browser resource fetching sequece #SPXTFS$BDIF  $IFDLDBDIFFYJTUFODF  $IFDLDBDIFFYQJSBUJPO JGNBYBHFTQFDJpFE

      6TFDBDIFPSSFRVFTUVQEBUFESFTPVSDF *GDBDIFOPUTUPSFE GFUDISFTPVSDFT 3FTQPOTFXJUI&5BHlʜz $BDIF$POUSPMlʜz (VO[JQJGH[JQFE 4UPSFDBDIFJG$BDIF$POUSPMWBMVFJTO`UlOPTUPSFz
  31. Cache-Control αʔό͸Cache-ControlϔομͰΫϥΠΞϯτʹରͯ͠ ΩϟογϡΛͲͷΑ͏ʹߦ͏͔ࢦࣔͰ͖Δ

  32. Cache-Control: max-age=120 3FTQPOTF Cache-Control: s-maxage=120 Cache-Control: no-cache Cache-Control: no-store Cache-Control:

    immutable ϦΫΤετͷૹ৴ऀ͸௨ৗNBYBHFΛݟΔ͕ɺ $%/౳ͷ1SPYZαʔόͱΫϥΠΞϯτͰΩϟογϡ࣌ؒΛม͍͑ͨ৔߹ʹ͸ TNBYBHFͰ1SPYZଆͷNBYBHFͰΫϥΠΞϯτଆͷΩϟογϡ࣌ؒΛࢦఆ͢Δ͜ͱ͕Ͱ͖Δ OPDBDIFͷ৔߹͸DBDIFΛߦ͏͕ɺຖճαʔό΁ߋ৽ΛͨͣͶΔ OPTUPSFͷ৔߹͸DBDIFΛ׬શʹߦΘͳ͍ ·ͨJNNVUBCMFΛࢦఆ͢Δ͜ͱͰϖʔδϦϩʔυ࣌ͷ$POEJUJPOBM(&5 αʔό΁ͷߋ৽֬ೝ΋ఀࢭͰ͖Δ
  33. Service Worker and Cache-Storage ServiceWorkerͰϦΫΤετΛinterruptͯ͠Ωϟογϡͨ͠ϦιʔεΛ ฦ͢͜ͱͰߋʹϦΫΤετ਺ΛݮΒ͢͜ͱ͕Ͱ͖Δ

  34. ServiceWorker cache sequence $BDIF4UPSBHF $IFDLDBDIFFYJTUFODF *GDBDIFOPUTUPSFE GFUDISFTPVSDFT 3FRVFTUSFTPVSDF 4FSWJDF8PSLFS 4UPSFDBDIFUPTUPSBHF

    3FHJTUFS4FSWJDF8PSLFS *OUFSSVQUSFRVFTUBOESFUVSOGSPN$BDIF4UPSBHF
  35. Service Worker and Cache-Storage ೳಈతʹඞཁͳϦιʔεΛࣄલʹΩϟογϡ͢Δ͜ͱ͕Ͱ͖Δ ࣄલʹ಺༰͕ܾ·͍ͬͯΔ੩తίϯςϯπͷΩϟογϡʹ޲͍͍ͯΔ

  36. Optimization

  37. Preload link rel=preload Λ࢖͏͜ͱͰࣄલʹϒϥ΢βʹϦιʔεΛϩʔυ͓ͤͯ͘͞

  38. Compress response ϨεϙϯεΛѹॖͯ͠ฦ٫͢Δ͜ͱͰɺϨεϙϯεαΠζΛখ͘͢͞Δ͜ͱ ͕Ͱ͖Fetching଎౓ʹେ͖͘Өڹ͢Δ ΞϧΰϦζϜͱͯ͠gzipͰ͸ͳ͘BrotliΛ࢖͏͜ͱͰߋʹѹॖ཰ΛߴΊΒ ΕΔ(ͨͩ͠ࣄલʹѹॖࡁΈϑΝΠϧΛ༻ҙ͢Δඞཁ͕͋Δ)

  39. Caching 1. ETagΛઃఆ 2. Cache-ControlΛઃఆ 3. ServiceWorkerΛઃఆ ͜ͷ3εςοϓͰ Scriptͷߋ৽͕ͳ͚Ε͹1Ϣʔβʔʹରͯ͠1ϦΫΤετͷΈͷൃߦͰ ϦιʔεͷऔಘΛߦ͏͜ͱ͕Ͱ͖Δ

  40. CDN CDN͔Β഑৴͢Δ͜ͱͰ ஍ཧతʹ͍ۙωοτϫʔΫ΁ΞΫηεͯ͠ɺFetching଎౓Λ޲্ͤ͞Δ CDNଆͰETagͱCache-ControlΛਖ਼͘͠ઃఆ͢Δ

  41. Webpack Workbox΍sw-precacheͱ͍ͬͨpluginΛར༻͢Δ͜ͱͰ webpack͔ΒServiceWorkerͱΩϟογϡίʔυΛ؆୯ʹ࡞੒͢Δ͜ͱ͕ Ͱ͖Δ

  42. Code Spliting ·ͨSPA౳͸࣮ࡍʹϑΝΠϧ͕ඞཁʹͳΔ·Ͱ FetchingΛ஗Ԇͤ͞Δ͜ͱͰແବͳϦΫΤετ΍ϖΠϩʔυͷαΠζΛݮ Β͢͜ͱ͕Ͱ͖Δ ྫ. React.Suspense + React.lazy +

    Dynamic Import + Webpack splitChunksͰϑΝΠϧ෼ׂ + ಈతಡΈࠐΈ
  43. Future

  44. HTTP/3 Quic HTTP৽όʔδϣϯͰ͋Γݱࡏࡦఆத Quicͷ্ʹߏங͞ΕΔHTTPϨΠϠ Quic͸TCPͰ͸ͳ͘UDP্ʹ᫔᫓੍ޚ౳Λ࣮૷ͨ͠Transport૚ͱͳͬͯ ͍Δ HTTP/3͸HTTP/2ͷར఺ΛҾ͖ܧ͗ͭͭɺTransport૚ࣗମͷվળʹΑͬ ͯߋʹߴ଎ͳϓϩτίϧͱͳΔ༧ఆ

  45. Priority-hints WICGʹఏҊ͞Ε͍ͯΔ࢓༷ Resourceͷॏཁ౓Λώϯτͱͯ͠Τϯδϯʹ఻͑ΔͨΊͷimportanceଐ ੑ͕௥Ճ͞ΕΔ importanceଐੑʹ͸highɾlowɾautoͷͲΕ͔Λࢦఆ͢Δ͜ͱ͕Ͱ͖Δ

  46. WebBundle/WebPackaging Web্ͷίϯςϯπΛ1ͭͷόϯυϧʹͯ͠഑৴͢ΔͨΊͷ࢓༷ WebαΠτؙ͝ͱPackagingͯ͠഑৴͢ΔͨΊʹ࢖͑Δ͕ɺScriptͷόϯ υϧΛ഑৴͢Δͷʹ΋࢖͑Δ͔΋ʁ

  47.  1BSTF)5.- 'FUDI3FTPVSDFT 1BSTFBOEFWBMVBUFTDSJQU

  48. Parsing

  49. Heavy but needed Parsingͱ͸Fetchͨ͠ScriptΛ࣮ߦ͢ΔͨΊʹίʔυΛParseͯ͠ Abstract Syntax Treeʹม׵͢ΔϑΣʔζ ͜ͷϑΣʔζΛܦͯScript͸Binary΁ม׵͞Ε࣮ߦ͞ΕΔ

  50. if (x) { y = 100 }

  51. Then Assign VarProxy Literal Expression Statement y = 100 100

    y IF if Condition (x) Block {
  52. Behind the scene Parsing

  53. Large and Heavy ͨͩ͠ɺParseॲཧ͸ͱͯ΋ॏ͍ ಛʹ࠷ۙͷJS͸1όϯυϧʹͳ͓ͬͯΓ1ϑΝΠϧ୯ҐͷίʔυαΠζ΋େ ͖͍

  54. Laziness Parse͸PreParseͱParseͷ2ͭͷϑΣʔζʹ෼͔ΕΔ javascript͸࣮ࡍʹ࣮ߦ͞ΕΔ·Ͱ࣮ߦ͞ΕΔίʔυ͕Θ͔Βͣɺ Parse࣌ؒ୹ॖͷͨΊʹॳճ͸ؔ਺໊ɾߦ൪߸ɾม਺৘ใͷΈΛύʔεͯ͠ ͓͖ɺ ݺͼग़͞ΕͨλΠϛϯάͰͦΕΒͷ৘ใΛ࢖࣮ͬͯࡍͷύʔεॲཧΛ͢Δ

  55. function x(a, b) { return a + b; } Function(X)

    parameter-count: 2 start-position: 1 end-position: 1 use-super-property: false
  56. // When x is called x() Return Function Name (x)

    BinaryExpression VarProxy a VarProxy b
  57. Streaming Google ChromeͰ͸javascriptͰετϦʔϛϯάͰॲཧ͠ͳ͕ΒParse ͢Δ͜ͱͰɺFetchingͱParsingͷίετΛ཈͍͑ͯΔ

  58. Stop parsing HTML javascriptͷParse͕࢝·ͬͨஈ֊ͰHTMLͷύʔεॲཧ͕ ఀࢭ͢ΔͨΊ scriptλάͷҐஔɾasyncɾdeferͷઃఆ͸ॏཁͱͳΔ

  59. HTML Parsing and script execution flow Script HTML Script(defer) HTML

    Script(async) HTML Script(module) HTML Script(module, async) HTML HTML Parsing Script fetching Script execution
  60. Optimization

  61. Bundle size 50 ~ 100KB͋ͨΓΛ໨҆ʹίʔυͷ෼ׂΛߦͬͨ΄͏͕ྑ͍ ಛʹϞόΠϧσόΠεͰ͸Parsing࣌ͷCPUίετɾϝϞϦ࢖༻ྔ͕അࣛʹ ͳΒͳ͍

  62. Async/Defer Chrome͸async/deferredͳscriptΛ·ͱΊͯίϯύΠϧ͢ΔͨΊɺ௨ ৗͷScriptΑΓ΋ߴ଎ʹॲཧͰ͖Δ ͨͩ͠asyncͰ͸࣮ߦΛ஗ԆͰ͖ͳ͍ͷͰɺͰ͖ΔݶΓscriptʹ͸defer ଐੑΛ෇༩ͨ͠΄͏͕ྑ͍

  63. Transpiling Await/Generator͸Transpile͞ΕΔͱڊେͰඇޮ཰ͳίʔυΛੜ੒͢ ΔͨΊɺରԠϒϥ΢βʹ͸͜ΕΒ͕Transpile͞Ε͍ͯͳ͍όʔδϣϯΛ ఏڙ͢Δ΄͏͕๬·͍͠ instagramͰ͸transpileΛ΍ΊΔ͜ͱͰɺ5.7%ͷίʔυαΠζ࡟ݮ 3%ͷϩʔυ࣌ؒ࡟ݮΛ࣮ݱͨ͠ https://instagram-engineering.com/making-instagram-com-faster-code-size-and-execution-optimizations- part-4-57668be796a8

  64. JSON.parse ΦϒδΣΫτϦςϥϧΛJSON.parse(“…”)ͷܗࣜͰهड़͢Δͱɺ࣮ߦ࣌· Ͱ׬શͳΦϒδΣΫτͷύʔεΛߦ͏λΠϛϯά͕ͣΕΔͨΊɺParsingͷ ύϑΥʔϚϯε͕޲্͢Δ ·ͨJSONΦϒδΣΫτʹ͸Getter/Setter౳͕ແ͍ͨΊɺParseࣗମ΋ ߴ଎ʹߦ͏͜ͱ͕Ͱ͖Δ

  65. Immediate call V8Ͱ͸ଈ࣌ؔ਺ͷ৔߹ɺ஗ԆParseΛߦΘͳ͍ͷͰ ଈ࣮࣌ߦ͞ΕΔ΂͖ؔ਺͸ҎԼͷύλʔϯͰهड़͢ΔͱύϑΥʔϚϯε্͕ ͕Δ (function() {}) !function() {}() function()

    {}()
  66. Polyfill Polyfill͸ϑΝΠϧαΠζΛ૿΍͠ɺParsingʹ͔͔Δ࣌ؒΛ૿΍͢ݪҼ ͱͳΓ͏Δ polyfill.ioΛར༻͢ΔͳͲͯ͠PolyfillͷαΠζ࡟ݮΛߦ͏΂͖ ·ͨɺຊདྷϖʔδશମͰ1ͭͷPolyfill͕๬·͍͕͠޿ࠂɾܭଌ౳ͷλά Λಋೖ͍ͯ͠Δ৔߹͸೉͍͔͠΋͠Εͳ͍͕…

  67. Future

  68. Binary AST ڞ௨ͷASTϑΥʔϚοτΛఆٛͯ͠ɺASTΛ௚઀഑৴͢Δ͜ͱͰɺParsing ͷίετΛ0ʹ͢Δ ݱࡏEcmascript΁proposal͕͋Δ͕ͦͷ͏ͪWhatwgʹҠಈ͢Δ༧ఆ

  69. Appendix Execution

  70. See https://speakerdeck.com/brn/source-to-binary-journey-of-v8-javascript- engine

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

  72. Reference https://github.com/chromium/chromium https://v8.dev/blog/cost-of-javascript-2019 https://developers.google.com/web/fundamentals https://wicg.io/ https://instagram-engineering.com/making-instagram-com-faster-code-size-and- execution-optimizations-part-4-57668be796a8 https://html.spec.whatwg.org/multipage/scripting.html#attr-script-async https://blog.jxck.io/entries/2019-11-12/webbundle.html https://speakerdeck.com/brn/source-to-binary-journey-of-v8-javascript-engine