Upgrade to Pro — share decks privately, control downloads, hide ads and more …

フロントエンドコーディングにおけるPageSpeed Insights対策 / fronten...

Kou
February 01, 2019

フロントエンドコーディングにおけるPageSpeed Insights対策 / frontend pagespeed insights-

Kou

February 01, 2019
Tweet

More Decks by Kou

Other Decks in Programming

Transcript

  1. Google PageSpeed Insightsͱ͸ Google͕ఏڙ͍ͯ͠ΔϞόΠϧ΍ύιίϯ͔ΒαΠτ΁ΞΫηεͨ͠ࡍͷ ύϑΥʔϚϯε͓ΑͼύϑΥʔϚϯεͷ՝୊ͱͳΔ໰୊఺ͷվળํ๏ΛϨ ϙʔτͯ͘͠ΕΔπʔϧͰ͢ɻ ύϑΥʔϚϯε݁Ռͷ෼ྨʹ͍ͭͯ͸ɺҎԼͷ̏ͭͷ෼ྨʹͳΓ·͢ɻ ଎͍ … είΞ

    90 Ҏ্ɻຆͲͷ࠷దԽ͕͞Εͨཧ૝తͳঢ়ଶ ฏۉ … είΞ 50ʙ89 ͷൣғɻ·ͩҰ෦࠷దԽՄೳͳ໰୊఺ΛؚΉ ஗͍ … είΞ 0ʙ49 ͷൣғɻ࠷దԽ͢΂͖఺͕͔ͳΓଟ͋͘Δ ύιίϯ͸ߴείΞΛग़͠΍͍͕͢ɺ ϞόΠϧʹ͍ͭͯ͸3Gճઢ૝ఆͷείΞͱͳ͓ͬͯΓɺ͔ͳΓݫ͠Ίͷ ධՁͱͳΓ·͢ɻ(2019೥1݄ݱࡏ)
  2. ϨϯμϦϯάϒϩοΫίʔυྫ <head> <link rel="stylesheet" href="/common_corporate/asset/css/reset_corporate.css"> <link rel="stylesheet" href="/common_corporate/asset/css/themify-icons.css"> <link rel="stylesheet"

    href="/common_corporate/asset/css/style.css?20181226"> <link rel="stylesheet" href="/common_corporate/asset/css/webfont.css"> <script src="/common_corporate/asset/js/lib/jquery.easing.1.3.js"></script> <script src="/common_corporate/asset/js/lib/jquery.matchHeight-min.js"></script> <script src="/common_corporate/asset/js/lib/truncate-text.js"></script> <script src="/common_corporate/asset/js/script.js"></script> </head> ͜ͷΑ͏ʹɺheadλάʹهड़ͨ͠CSSͷಡΈࠐΈ΍JavaScriptͷಡΈࠐΈ ͸ɺର৅ϑΝΠϧͷಡΈࠐΈͱ࣮ߦ͕׬ྃ͢Δ·ͰHTMLͷύʔεॲཧΛ ࣮ߦ͢Δ͜ͱ͕Ͱ͖ͳ͘ͳΔ(ʹϨϯμϦϯάϒϩοΫ͞ΕΔ)࢓༷ͱͳͬ ͍ͯ·͢ɻheadͰಡΈࠐΈࢦఆ͢ΔϑΝΠϧ͓ΑͼͦͷαΠζ͕ଟ͚Ε ͹ଟ͘ͳΔ΄ͲɺϨϯμϦϯάϒϩοΫ͞ΕΔ͕࣌ؒ௕͘ͳΓɺύϑΥʔ ϚϯεʹଟେͳѱӨڹΛٴ΅͠·͢ɻ
  3. ϨϯμϦϯάϒϩοΫίʔυվળྫᶃ <head> <link rel="preload" href="/common_corporate/asset/css/reset_corporate.css"> <link rel="preload" href="/common_corporate/asset/css/themify-icons.css"> <link rel="preload"

    href="/common_corporate/asset/css/style.css?20181226"> <link rel="preload" href="/common_corporate/asset/css/webfont.css"> <script src=“/common_corporate/asset/js/lib/jquery.easing.1.3.js" defer></script> <script src=“/common_corporate/asset/js/lib/jquery.matchHeight-min.js" defer></ script> <script src=“/common_corporate/asset/js/lib/truncate-text.js" defer></script> <script src=“/common_corporate/asset/js/script.js" defer></script> </head> CSSͷಡΈࠐΈʹ͸ preloadɺJavaScriptͷಡΈࠐΈʹ͸ defer ·ͨ͸ async Λ࢖͏͜ͱͰಡΈࠐΈॲཧΛϨϯμϦϯάϒϩοΫͤͣʹɺඇಉظ ͰಡΈࠐΈ͢Δ͜ͱ͕ՄೳʹͳΓ·͢ɻͰ͸ɺશͯͷλάʹ͜ͷࢦఆΛ͠ ͯྑ͍ͷ͔ͱ͍͏ͱͦ͏͍͏Θ͚Ͱ͸ͳ͘ɺܭଌλάͷΑ͏ͳHTML͕ಡ ΈࠐΈ͞ΕΔલʹεΫϦϓτͷ࣮ߦΛ׬͓͖͍ྃͯͨ͠έʔεʹ͓͍ͯ͸ defer ΍ async ͸͚ͭͳ͍ྫ͕ଟ͍Ͱ͢ɻ
  4. ϨϯμϦϯάϒϩοΫίʔυվળྫᶄ <head> <link rel="preload" href=“/common_corporate/asset/css/bundle.css"> <script src=“/common_corporate/asset/js/lib/vendor.bundle.js” defer></script> <script src=“/common_corporate/asset/js/lib/main.js"

    defer></script> </head> preload΍defer, asyncͰඇಉظʹϩʔυͤ͞Δ͚ͩͰ΋ϒϩοΩϯά͸վ ળ͠·͕͢ɺ͞ΒͳΔߴ଎Խʹ͸ಡΈࠐΉϑΝΠϧ਺ΛݮΒ͢ඞཁ͕͋Γ ·͢ɻվળલͩͱଟ਺ͷCSSͱJSΛಡΈࠐΜͰ͍·͕ͨ͠ɺCSS΍JS͸ ̍ͭʹͰ͖Δ΋ͷ͸̍ͭʹ·ͱΊͨํ͕ϩʔυ࣌ؒ΋ݮগ͠·͢ɻ ͜Ε͸ϒϥ΢β͕1ͭͷυϝΠϯʹରͯ͠Ұ౓ʹฒྻॲཧՄೳͳ઀ଓ਺͕ ܾ·͓ͬͯΓɺͦͷ਺Λ௒͑Δͱ݁ہಡΈࠐΈʹ͕͔͔࣌ؒΔͨΊͰ͢ɻ CSS΍JSΛ1ͭʹ·ͱΊΔʹ͸PostCSSɺwebpackɺParcelɺFuseBoxͳ ͲͷόϯυϥʔΛ࢖͏ͱ؆୯ʹͰ͖·͢ɻ
  5. loadCSSͷࢦఆྫ <head> <link rel="preload" href=“/common_corporate/asset/css/bundle.css” onload="this.onload=null;this.rel='stylesheet'"> <noscript> <link rel="stylesheet" href=“/common_corporate/asset/css/bundle.css”>

    </noscript> <script> !function(n){"use strict";n.loadCSS||(n.loadCSS=function(){});var o=loadCSS.relpreload={};if(o.support=function(){var e;try{e=n.document.createElement("link").relList.supports("preload")}catch(t){e=!1}return function(){return e}}(),o.bindMediaToggle=function(t){var e=t.media||"all";function a() {t.addEventListener?t.removeEventListener("load",a):t.attachEvent&&t.detachEvent("onload",a),t.setAttribute("onload",null),t.media=e}t.addEventListener? t.addEventListener("load",a):t.attachEvent&&t.attachEvent("onload",a),setTimeout(function(){t.rel="stylesheet",t.media="only x"}),setTimeout(a,3e3)},o.poly=function(){if(! o.support())for(var t=n.document.getElementsByTagName("link"),e=0;e<t.length;e++){var a=t[e];"preload"!==a.rel||"style"!==a.getAttribute("as")||a.getAttribute("data-loadcss")|| (a.setAttribute("data-loadcss",!0),o.bindMediaToggle(a))}},!o.support()){o.poly();var t=n.setInterval(o.poly,500);n.addEventListener?n.addEventListener("load",function() {o.poly(),n.clearInterval(t)}):n.attachEvent&&n.attachEvent("onload",function(){o.poly(),n.clearInterval(t)})}"undefined"!=typeof exports?exports.loadCSS=loadCSS:n.loadCSS=loadCSS} ("undefined"!=typeof global?global:this); </script> </head> loadCSS͸ preload ࢦఆͷରԠϒϥ΢βͰ͋Ε͹ͦͷ··ϒϥ΢βͷ preloadΛར༻͠ɺඇରԠϒϥ΢βͰ͋Ε͹JSʹͯpreload૬౰ͷॲཧΛ࣮ ݱ͢Δ΋ͷʹͳΓ·͢ɻ্هͷྫͷ࠷ޙʹ͋Δscriptλά͕loadCSSͷຊ ମͰɺ͜ΕΛΠϯϥΠϯهड़(ίϐϖ)͠·͢ɻ
  6. Critical Path CSSͷࢦఆ Critical Path CSSͱ͸Critical Rendering PathΛվળ͢ΔͨΊͷCSSʹͳ Γ·͢ɻCritical Rendering

    Pathͱ͸ϒϥ΢βʹ࣮ࡍʹը໘Λඳը͢Δͨ Ίʹඞཁͳॲཧγʔέϯεͷ͜ͱΛࢦ͠·͢ɻCritical Path CSS͸Critical Rendering PathͷCSSʹؔ͢Δ෦෼Λࢦ͠·͢ɻ Θ͔Γ΍͍͑͘͢͹ɺϑΝʔετϏϡʔͷඳըʹඞཁͳCSSͱ͍ͬͨͱ͜ ΖʹͳΓ·͢ɻ preload࣌ͷFOUCΛվળ͢Δʹ͸ɺ͜ͷCritical Path CSSΛ͋Β͔͡Ί HTMLͷstyleλά಺ʹΠϯϥΠϯهड़Λ͓ͯ͘͜͠ͱͰվળՄೳʹͳΓ· ͢ɻ
  7. Critical Path CSSͷࢦఆྫ <head> <link rel="preload" href=“/common_corporate/asset/css/bundle.css"> <style> *,:after,:before{background-repeat:no-repeat;-webkit-box-sizing:border-box;box- sizing:border-box}:after,:before{text-decoration:inherit;vertical-align:inherit}

    html{font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.15; </style> </head>
  8. 3xղ૾౓࣌୅ͷը૾ͷѻ͍ RetinaσΟεϓϨΠ(2xղ૾౓)͕ొ৔ͯ͠ਵ෼ܦͪ·͕͢ɺ࠷ۙͰ͸͞Β ʹͦͷ্ͷ3xղ૾౓Λ࣋ͭRetina Display͕ొ৔͍ͯ͠·͢ɻ(iPhone Xɺ XSɺXS MaxͳͲ͕͜Εʹ͋ͨΓ·͢) 2x͕ओྲྀͷ࣌୅ͩͱ2xͷը૾͚ͩΛ༻ҙͯͦ͠ΕΛ width ΍

    height ࢦఆ Ͱ 1x αΠζʹͯ͠ίʔσΟϯάΛ͍ͯ͠Δํ΋தʹ͸͍͔ͨͱࢥ͍·͢ ͕ɺ3xαΠζͱͳΔͱ࠷దԽͯ͠΋ͦͦ͜͜େ͖ͳαΠζͰ͢ɻ ͦͷͨΊɺͲͷσΟεϓϨΠʹ͓͍ͯ΋3xΛॖখͯ͠࢖͏ͱ͍ͬͨํ๏ͩ ͱɺ3xղ૾౓Ҏ֎ͷσΟεϓϨΠͰ͸ຊདྷෆཁͳͷʹඞཁҎ্ʹେ͖ͳը ૾ΛಡΈࠐΉඞཁ͕ग़͖ͯͯ͠·͏(ʹ͕͔͔࣌ؒΔ)݁Ռͱͳͬͯ͠·͍ ·͢ɻ ͜ΕΛղܾ͢Δʹ͸Ͳ͏͢Ε͹Α͍Ͱ͠ΐ͏͔ɻ
  9. srcsetଐੑʹ͍ͭͯ imgλάʹ͸srcsetͱ͍͏ଐੑ͕͋Γ·͢ɻ͜Ε͸ը໘ղ૾౓͝ͱʹಡΈ ࠐΉը૾ΛࢦఆͰ͖Δͱ͍͏ଐੑͰ͢ɻҎԼͷΑ͏ʹར༻͠·͢ɻ <img src="./images/display.png" srcset="./images/display@2x.png 2x, ./images/ display@3x.png 3x">

    srcଐੑʹ͸ 1x ͷը૾αΠζɺsrcsetଐੑʹ͸ 2x ͱ 3x ͷը૾αΠζΛ্ هͷΑ͏ʹࢦఆ͢Δ͜ͱͰɺϒϥ΢βଆͰࣗಈతʹը໘ղ૾౓ʹԠͨ͡ը ૾͚ͩΛಡΈࠐΈͯ͘͠Ε·͢ɻ
  10. vanilla-lazyloadͷࢦఆྫ HTML <img class="js-lazyload" src="./images/loading.png" data-src="./images/display.png" data-srcset="./images/display@2x.png 2x, ./images/display@3x.png 3x"

    alt="Display Image") /> JavaScript (Babel) import LazyLoad from 'vanilla-lazyload'; new LazyLoad({ elements_selector: '.js-lazyload', });