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

웹 성능 게이트 키퍼: 웹 성능 모니터링 서비스, '파루스' 의 기술과 활용

kakao
November 01, 2024

웹 성능 게이트 키퍼: 웹 성능 모니터링 서비스, '파루스' 의 기술과 활용

#FE #웹 성능 측정 #lighthouse

좋은 품질의 웹서비스를 제공하기 위해서는 웹서비스의 성능을 지속적으로 모니터링하고 개선하는 것이 중요합니다.
카카오 FE플랫폼에서는 웹 성능 모니터링 서비스, 파루스(Pharus) 를 개발하고 있습니다.
파루스는 100개가 넘는 서비스에서 1000여개 이상의 페이지 성능을 일관된 기준으로 모니터링(가시화)하고 분석 리포트를 제공하여 개선 전략을 세우는데 도움을 주고 있습니다.
이번 발표에서는 파루스의 주요 기능과 기술을 소개하고 서비스의 활용 사례를 공유하고자 합니다.

발표자 : ted.chung, dino.saur
카카오 FE 플랫폼팀에서 파루스 서비스를 담당하고 있는 테드입니다.
카카오 FE 플랫폼팀에서 파루스 서비스를 담당하고 있는 디노입니다.

kakao

November 01, 2024
Tweet

More Decks by kakao

Other Decks in Programming

Transcript

  1. ↟ 4ZOUIFUJD.POJUPSJOH ↟ प೷पജ҃ীࢲ੄ࢿמݽפఠ݂ ↟ ਬ੷੄೯ز ਢಕ੉૑੽Ӕ١ਸदޯۨ੉࣌ ↟ 3FBM6TFS.POJUPSJOH 36.

    ↟ पઁਬ੷੄૑಴ࣻ૘ ↟ ׮নೠ௿ۄ੉঱౟ജ҃ীࢲࢿמஏ੿ ਢࢿמݽפఠ݂ 36. 4ZOUIFUJD.POJUPSJOH  .%/8FC%PDT u1FSGPSNBODF.POJUPSJOH36.WTTZOUIFUJDNPOJUPSJOHu ֙ਘੌ IUUQT EFWFMPQFSNP[JMMBPSHFO - 64EPDT8FC1FSGPSNBODF3VN - WT - 4ZOUIFUJD
  2. ↟ ஏ੿ ↟ ஏ੿ࢲ࠺झಕ੉૑ࢸ੿ ١۾ ↟ ஏ੿द੼ ↟ ஏ੿ߑߨ ҳઑ

    ↟ ܻನ౟ ↟ ױੌஏ੿࠙ࢳ ↟ ੼ࣻ߸ചӒې೐ ౵ܖझ੄ӝמ
  3. ↟ ,VCFSOFUFTߓನ ↟ XFC BQJTFSWFS ↟ NPOJUPSJOHQPE ↟ SVOOFS XPSLFSQPE

    ↟ DSPOKPC ↟ ࢎղੋ೐ۄোز ↟ 3FEJT ↟ .Z42- ↟ 3BCCJU.2 ஏ੿ߑߨߓನߑध
  4. ↟ ஏ੿ ↟ ஏ੿ࢲ࠺झಕ੉૑ࢸ੿ ١۾ ↟ ஏ੿द੼ ↟ ஏ੿ߑߨ ҳઑ

    ↟ ܻನ౟ ↟ ױੌஏ੿࠙ࢳ ↟ ੼ࣻ߸ചӒې೐ ౵ܖझ੄ӝמ
  5. /PEF1PE+PC affinity: podAntiAffinity: // podо ࢲ۽ ׮ܲ nodeীࢲ प೯ೞӝ ਤೠ

    ࢸ੿ requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - pharus-runner ↟ ೞա੄/PEFীחೞա੄1PE݅ਬ૑ೞҊೞա੄+PC ஏ੿ ݅प೯ ↟ ܻࣗझ DQV NFNPSZ ࢎਊਸ౵٘ೞաীࢲ૘઺ೞҊয়૒ஏ੿ী݅ࢎਊೡࣻ੓חജ҃ҳࢿ
  6. -JHIUIPVTF W $ISPNF GPS5FTUJOH 1VQQFUFFS W ↟ ࠛউ੿ೠ׮਍۽٘ ↟ ߡ੹ஶ౟܀ࠛо

    ↟ ੌ߈࠳ۄ਋૚ীࠗ੸೤ ↟ ծ਷द੢੼ਬਯ ࠳ۄ਋੷ࢶఖҗߡ੹ҙܻ
  7. ENV PUPPETEER_SKIP_DOWNLOAD true // CfT ׮਍۽٘ ઺૑ ENV CHROME_BIN=“/usr/bin/chromium-browser" RUN

    apk add --no-cache chromium // ࠳ۄ਋੷ܳ ࣻز ࢸ஖ -JHIUIPVTF W $ISPNJVN W 1VQQFUFFS W ࠳ۄ਋੷ࢶఖҗߡ੹ҙܻ Puppeteer.launch({executablePath: process.env.CHROME_BIN}); // ࠳ۄ਋੷ܳ ࢸ஖ೠ ҃۽ ࢸ੿
  8. $ISPNJVN $ISPNF $ISPNFGPS5FTUJOH ӝࠄ੿੄ য়೑ࣗझਢ࠳ۄ਋੷ (PPHMFਢ࠳ۄ਋੷ పझ౟੗زചܳਤೠਢ࠳ۄ਋੷ ੌ߈੸ੋ࠳ۄ਋૚ীࢎਊೞ૑ঋب۾ӂ੢ ӝמ ӝࠄ࠳ۄ਋੷ӝמ

    (PPHMF੗زসؘ੉౟ %3.١ పझ౟୭੸ചӝמ ੗زചبҳ૑ਗ द੢੼ਬਯ ծ਺ ֫਺ ݒ਋ծ਺ ݫݽܻࢎਊ۝ ծ਺ ֫਺ ծ਺ प೯ࣘب ࡅܴ ݒ਋ࡅܴ ࡅܴ పझ౟੗زചജ҃ী୭੸ച $ISPNJVN࠺Ү
  9. ী۞Ѻܻஏ੿೐۽ࣁझܻ࠙ߑߨ $IJME1SPDFTT $MVTUFS 8PSLFS5ISFBET ӝࠄױਤ ೐۽ࣁझ ೐۽ࣁझ ॳۨ٘ ݫݽܻࢎਊ ೐۽ࣁझة݀੸ݫݽܻҕрࢎਊ

    ೐۽ࣁझة݀੸ݫݽܻҕрࢎਊ ҕਬݫݽܻ ী۞୊ܻ ೐۽ࣁझղ୊ܻ ݃झఠ೐۽ࣁझҙܻ೙ਃ ॳۨ٘ղ୊ܻ ࢎਊ৘द $16૘ড੸ੋ੘সী੸೤ ਢࢲߡ੄۽٘࠙࢑ ؘ੉ఠ୊ܻ ࠺زӝ੘স
  10. ী۞Ѻܻஏ੿೐۽ࣁझܻ࠙௏٘ import {spawn} from ‘child_process'; auditProcess = spawn('lighthouseProcess.js')], // child

    process ౵ੌ प೯ { env: { NODE_OPTIONS: ‘--max-old-space-size=2048', // child process ੄ heap ௼ӝ ࢸ੿ }, // processр ؀ਊ۝ ؘ੉ఠ ੹࣠ਸ ਤೠ ipc ࢸ੿ stdio: ['ignore', process.stdout, process.stderr, ‘ipc’] }); auditProcess.on('message', resolve); // child process ݫद૑ ੉߮౟ ࢸ੿ auditProcess.on('error', reject); auditProcess.on(‘exit', exit); // child process ী۞ or (࠺)੿࢚ ઙܐ द ୊ܻ auditProcess.send({url,port}); // child process ী urlҗ ࠳ۄ਋੷ port ੹׳ // lighthouse(url, {port, …}, …) ࢎਊ оמ
  11. ஏ੿ߑߨ4JNVMBUFE࠺Ү 4JNVMBUFE %FWUPPMT 1BDLFU - -FWFM ౠ૚ ୡӝ۽ؘ٘੉ఠܳӝ߈ਵ۽ಕ੉૑दޯۨ੉࣌ ࠳ۄ਋੷ࣻળীࢲ੄૑োदޯۨ੉࣌ ಁఉࣻળীࢲ੄૑ো߂ؘ੉ఠ

    ࣚपਸݽ؛݂ ੢੼ ↟ ஏ੿ࣘبоࡅܴ ↟ ؀׮ࣻࢎ੉౟ীੌҙؽ ↟ 1BHF4QFFE*OTJHIUT੸ਊ ↟ ੌ߈੸ੋపझ౟ীਬਊ ↟ $ISPNF%FW5PPMT੸ਊ न܉بо֫਺ 
 8FC1BHF5FTU੸ਊ ױ੼ ࠺੿࢚੸ੋ࢚ടীࢲ੄੿ഛࢿ੉ڄয૕ࣻ੓਺ ↟ അप߈৔ࠗ઒ೣ ҳࢿҗҙܻоয۰਑  (PPHMF%PDT u-JHIUIPVTF.FUSJD7BSJBCJMJUZBOE"DDVSBDZu ֙ਘੌ IUUQT EPDTHPPHMFDPNEPDVNFOUE#RU-O(SY80*30Q*U431PX;7O:+@H#&2$+&F6&FEJUIFBEJOHIMNLHIGWNT 
  EFCVHCFBS t/FUXPSL5ISPUUMJOH.FUIPET%FW5PPMTWT-JHIUIPVTFWT/FUFNu ֙ਘੌ IUUQT XXXEFCVHCFBSDPNCMPHOFUXPSL - UISPUUMJOH - NFUIPET
  12. ஏ੿പࣻഥ ↟ ੿ഛبܳಣоೞҊҙ଴പࣻо݆ਸࣻ۾࠙࢑੉঴ ݃ածই૑ח૑੿۝ച ↟ ߣஏ੿ೡٸ ࠙࢑੉؀ۚ੿بծই૗ ↟ ஏ੿दрҗ੿ഛبܳҊ۰೧ࢲഥஏ੿ਵ۽Ѿ੿ t"DDVSBDZuPG3VOT

    5PBTTFTTUIFBDDVSBDZPGTJOHMFPCTFSWBUJPOTBOERVBOUJGZIPXNVDIMPXFSUIF WBSJBODFCFDPNFTXJUINPSFPCTFSWBUJPOT XFDBODPNQVUFUIFTBNFTVDDFTT NFUSJDTPOBSBOEPNTVCTFUPGUIFEBUB#FMPXBSFUIFUIQFSDFOUJMFBOEBWFSBHF TQFBSNBOTSIP."1&WBMVFTPGPVSPUIFSPCTFSWBUJPO - CBTFEBQQSPBDIFTGPS   BOESVOT - UIBUJTUPTBZ UIFTFBSFUIFWBMVFTPGPVSTVDDFTTNFUSJDTXFNJHIU FYQFDUUPTFFXIFOVTJOHKVTUO - PCTFSWBUJPOTPGBNFUSJD 5IFUBCMFTDBOCFGPVOECFMPX*OTVNNBSZ BDSPTTBMMNFUSJDTWBSJBODFBOE."1& EFDSFBTFTCZSPVHIMZXIFONPWJOHGSPNSVOUPSVOTBOECZSPVHIMZ XIFONPWJOHGSPNSVOUPSVOT"DPO fi EFODFJOUFSWBMPGBTJUFXJUIBWFSBHF '.1QFSGPSNBODFGPSBSVODBTFXPVMETQBO SVODBTFXPVMETQBO  SVODBTFXPVMETQBO"TJUFXJUIBWFSBHF55*QFSGPSNBODFGPSBSVODBTF XPVMETQBO SVODBTFXPVMETQBO SVODBTFXPVMETQBO  (PPHMF%PDT u-JHIUIPVTF.FUSJD7BSJBCJMJUZBOE"DDVSBDZu ֙ਘੌ IUUQT EPDTHPPHMFDPNEPDVNFOUE#RU-O(SY80*30Q*U431PX;7O:+@H#&2$+&F6&FEJUIFBEJOHIMNLHIGWNT
  13. ੼ࣻಣо&VDMJEFBOEJTUBODF ↟ ߣஏ੿Ѿҗ઺ীࢲ੸੺ೠѾҗчਸࢶ੿ೞחߑߨ ↟ пஏ੿Ѿҗ੄'$1 55*ஏ੿чਸഝਊ '$1઺рч पઁ'$1ч 55*઺рч पઁ55*ч

    ӡ੉оо੢ૣ਷чਸ଺਺  8JLJQFEJB t&VDMJEFBOEJTUBODFu ֙ਘੌ IUUQT FOXJLJQFEJBPSHXJLJ&VDMJEFBO@EJTUBODF 
  (JUIVC (PPHMF$ISPNFMJHIUIPVTF ֙ਘੌ IUUQT HJUIVCDPN(PPHMF$ISPNFMJHIUIPVTFCMPCDDBEEBBEBBEBBGDPSFMJCNFEJBO - SVOKT-
  14. ੼ࣻಣо&VDMJEFBOEJTUBODF const medianFCP = getFcpMedian(auditResults); // 5ѐ Ѿҗ઺ FCP ઺рчਸ

    ୶୹ೠ׮. const medianTTI = getTtiMedian(auditResults); // 5ѐ Ѿҗ઺ TTI ઺рчਸ ୶୹ೠ׮. function getEuclideanDistance (auditResult, medianFcp, medianTTI) { const distanceFCP = medianFcp - auditResult.fcp; const distanceTTI = medianTTI - auditResult.tti; return distanceFCP ** 2 + distanceTTI ** 2; } const result = auditResults // FCP, TTI ઺рчҗ о੢ оө਍(੘਷) Ѿҗܳ ߈ജ .slice() .sort((a, b) => getEuclideanDistance(a, medianFCP, medianTTI) - getEuclideanDistance(b, medianFCP, medianTTI) )[0];
  15. ઑ૒ղ 
 ࢿמѐࢶ 
 ഝز   ౵ܖझ੄ӛ੿੸ࢿҗ ಕ੉૑੼ࣻ࠙ನب 

              ੼੉ೞ _੼ ੼੉࢚ ࢿמѐࢶী؀ೠੋधਸъചೞҊѐࢶഝزਸૐ૓
  16. ౵ܖझী؀ೠ׮নೠ੄Ѽ ↟ ಴ળಞରоցޖ௾಩ੋ҃਋о݆णפ׮ ↟ ౠࢿ࢚प૕੸ੋపझ౟оয۰ਕࢲ੉ࠗ࠙੉ѐࢶؼࣻ੓׮ݶજਸѪэणפ׮ ↟ ౵ܖझח஠஠য়੄ࢲ࠺झܳ؀࢚ਵ۽ೞח݅ఀ ੿݈਋ܻࢲ࠺झ੉ਊীب਑੉ ؼࣻ੓ח૑಴ܳ࢜܂ѱ੿੄ೞҊஏ੿ೡࣻ੓ਵݶજਸѪэणפ׮ ↟

    ѐ߹ஏ੿द݃׮ಞରо੓׮ࠁפөౠ੿ӝрਵ۽ࠌਸٸಣӐҗಞରܳࠅࣻ੓ ਵݶب਑੉ؼࣻ੓ѷ׮ۄחࢤп੉ٜ঻णפ׮ ↟ ୭Ӕࢿמѐࢶ੘সਸ૓೯ೞҊѾҗܳഛੋ೧ࠁחؘ पઁࢿמ਷ѐࢶغ঻૑݅ ੼ࣻо؊ծই૑חഅ࢚੉੓঻׮ ↟ ޙઁ݅ઁदೞחѪ੉ইפۄޙઁী؀ೠ೧Ѿ଼بೣԋઁदೞݶજਸѪэणפ ׮р഑੉ѱޙઁ׮ۄҊաয়חؘ৵੉ѱޙઁੋ૑଺חؘয۰਑੉੓ਸٸب੓ חѪэणפ׮ ↟ Ӓ৻׮নೠ੄Ѽ੉੓঻਺ ৈ੹൤о੢௾ҙबࢎחࢲ࠺झ੼ࣻ੄न܉ࢿ न܉ࢿ উ੿ࢿ ಞ੄ࢿ ӝఋ    
  17. 2"