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

광고 웹 SDK 개편기 with Preact

kakao
December 08, 2022

광고 웹 SDK 개편기 with Preact

#리팩토링 #Preact

광고 웹 SDK(AdFit Web SDK)는 AdFit 플랫폼을 이용하여 광고를 게재하고 수익을 창출하기 위해 웹사이트 등에서 사용하는 라이브러리입니다.
기존 프로젝트의 문제점을 분석하고 개선하고자 개편을 진행하였고 그 과정에서 얻은 소중한 경험들을 공유하려 합니다.
그리고 React의 이웃사촌, Preact를 소개하고 광고 SDK에 어떻게 도입하고 활용했는지도 이야기하고자 합니다.

발표자 : jake.baek
카카오 FE플랫폼팀의 비즈FE파트에서 광고 SDK를 개발하고 있는 제이크입니다.

kakao

December 08, 2022
Tweet

More Decks by kakao

Other Decks in Programming

Transcript

  1. 백종현 Jake.Baek 카카오 Copyright 2022. Kakao Corp. All rights reserved.

    Redistribution or public display is not permitted without written permission from Kakao. 광고 웹 SDK 개편기 with Preact if(kakao)2022
  2. 광고 웹 SDK 쇼핑몰이나 블로그와 같은 매체에 광고를 게재하고 수익을

    창출하기 위해 제공되는 웹 스크립트 AdFit SDK
  3. <!DOCTYPE html> <html lang="ko"> <head> <title>ݫੋ ࢲ࠺झ</title> </head> <body> <h1>ҟҊܳ

    ಿ਷ ࢲ࠺झ</h1> <!DOCTYPE html> <html lang="ko"> <head> <title>ҟҊ ࣗ੤</title> </head> <body> <img src="..." alt="Kakao for Business" /> <h1>ৢੋਗ ޖܐ ഈসో ଻օస</h1> ... </body> </html> </body> </html> 서비스에 노출된 소재 코드
  4. <!DOCTYPE html> <html lang="ko"> <head> <title>ݫੋ ࢲ࠺झ</title> </head> <body> <h1>ҟҊܳ

    ಿ਷ ࢲ࠺झ</h1> <iframe src="..." /> </body> </html> <!DOCTYPE html> <html lang="ko"> <head> <title>ҟҊ ࣗ੤</title> </head> <body> <img src="..." alt="Kakao for Business" /> <h1>ৢੋਗ ޖܐ ഈসో ଻օస</h1> ... </body> </html> iframe으로 격리된 소재 코드
  5. <ins class="kakao_ad_area" style="display:none;width:100%;" data-ad-unit="ҟҊױਤID" data-ad-width="ҟҊױਤ о۽ ࢎ੉ૉ" data-ad-height="ҟҊױਤ ࣁ۽ ࢎ੉ૉ"></ins>

    <script async type="text/javascript" src="//t1.daumcdn.net/kas/static/ba.min.js"></ script> 광고 소재 광고 웹 SDK 광고 단위 광고 서버
  6. SRP 단일 책임 원칙 OCP 개방-폐쇄 원칙 LSP 리스코프 치환

    원칙 ISP 인터페이스 분리 원칙 DIP 의존성 역전 원칙 SOLID Principles
  7. 의존관계에 따른 계층 구조 렌더링 프로세스 SDK 프로젝트의 통합 Unit

    Test 단일 책임 원칙에 충실한 광고 도메인 모델 개편 톺아보기
  8. 광고 소재 데이터 광고 단위 데이터 광고 요청 광고 객체

    ? ? ? class 하나의 객체에 모든 기능을 담게 된다면?
  9. 광고 렌더링 ? 광고 지표 수집 ? 광고 검증 ?

    광고 소재 데이터 광고 단위 데이터 광고 요청 광고 객체 ? ? ? class 하나의 객체에 모든 기능을 담게 된다면?
  10. 광고 요소 광고 단위 광고 렌더링 광고 서버 광고 소재

    광고 상태 관리 광고 업무 용어를 기준으로 한 도메인 모델 분리
  11. 단일 책임 원칙에 충실한 광고 도메인 모델 렌더링 프로세스 SDK

    프로젝트의 통합 Unit Test 의존관계에 따른 계층 구조 개편 톺아보기
  12. 광고 소재 광고 렌더링 광고 서버 광고 단위 광고 상태

    관리 변경이 의존 관계에 미치는 영향
  13. 광고 소재 광고 렌더링 광고 서버 광고 단위 광고 상태

    관리 광고 소재 변경 발생! 광고 렌더링 광고 서버 광고 상태 관리 변경이 의존 관계에 미치는 영향
  14. 광고 소재 abstract class 생성 광고 서버 interface 광고 응답

    광고 단위 광고 소재 스토어 추가 광고 소재 스토어 abstract class
  15. 의존성 역전 원칙의 적용 광고 서버 class 광고 소재 abstract

    class 광고 소재 스토어 abstract class 광고 서버 class
  16. 광고 서버 class 광고 소재 abstract class 광고 소재 스토어

    abstract class 광고 서버 구현체 SSP 광고 서버 요청/응답 광고 서버 interface 의존성 역전 원칙의 적용
  17. 단일 책임 원칙에 충실한 광고 도메인 모델 의존관계에 따른 계층

    구조 SDK 프로젝트의 통합 Unit Test 렌더링 프로세스 개편 톺아보기
  18. 하나의 광고 렌더링 함수 소재 렌더링 렌더링 검증 지표 수집

    ... 하나의 광고 렌더링 함수 소재 렌더링 렌더링 검증 지표 수집 ... 광고 렌더링에 필요한 기능들
  19. 광고 렌더링에 필요한 기능들 소재 렌더링 함수 지표 수집 함수

    렌더링 검증 함수 ... 하나의 광고 렌더링 함수 소재 렌더링 렌더링 검증 지표 수집 ...
  20. 렌더링 파이프라인 렌더러 함수 interface 소재 렌더링 함수 렌더링 검증

    함수 지표 수집 함수 ... 렌더러 함수와 렌더링 파이프라인
  21. 단일 책임 원칙에 충실한 광고 도메인 모델 의존관계에 따른 계층

    구조 렌더링 프로세스 Unit Test SDK 프로젝트의 통합 개편 톺아보기
  22. export default new ࠺ҕѐ_SDK( new ۪؊݂_౵੉೐ۄੋ([ ࠺ҕѐ_ࣗ੤_۪؊݂_ೣࣻ, ࠺ҕѐ_۪؊݂_Ѩૐ_ೣࣻ, ࠺ҕѐ_૑಴_ࣻ૘_ೣࣻ, ...,

    ]) ); 비공개 SDK 빌드 진입점 export default new ҕѐ_SDK( new ۪؊݂_౵੉೐ۄੋ([ ҕѐ_ࣗ੤_۪؊݂_ೣࣻ, ҕѐ_۪؊݂_Ѩૐ_ೣࣻ, ҕѐ_૑಴_ࣻ૘_ೣࣻ, ..., ]) ); 공개 SDK 빌드 진입점
  23. 단일 책임 원칙에 충실한 광고 도메인 모델 의존관계에 따른 계층

    구조 렌더링 프로세스 SDK 프로젝트의 통합 Unit Test 개편 톺아보기
  24. module.exports = { ..., // An object that configures minimum

    threshold enforcement for coverage results coverageThreshold: { "global": { branches: 90, functions: 90, lines: 90, statements: 90, }, }, ... }; Jest의 커버리지 검사 설정
  25. 의존성있는 함수 foo 예제 import {bar} from "./bar"; export function

    foo() { const barResult = bar(); return `if(kakao)${barResult}`; }
  26. 의존성있는 함수 foo의 테스트 코드 예제 import {foo} from "./foo";

    test("foo", () => { jest.mock("./bar", () => ({ bar: jest.fn(() => 2022), })); expect(foo()).toBe("if(kakao)2022"); });
  27. 의존성 주입을 사용한 함수 foo 예제 import {Baz} from "./Baz";

    export function foo(bar: Baz) { return () => { const barResult = bar(); return `if(kakao)${barResult}`; }; }
  28. 의존성 주입을 사용한 함수 foo의 테스트 코드 예제 import {foo}

    from "./foo"; test("foo", () => { const barMock = () => 2022; const fooWithBarMock = foo(barMock); expect(fooWithBarMock()).toBe("if(kakao)2022"); });
  29. const parent = document.createElement("div"); const child = document.createElement("p"); child.innerText =

    "Hello, World!"; parent.appendChild(child); return parent; return ( <div> <p>Hello, World!</p> </div> );
  30. - DOM 요소의 렌더링을 document.createElement 등으로 생성하거나 별도의 템플릿을 다룰

    필요없이 
 JSX 문법을 통해 간결한 표현이 가능해집니다. - 컴포넌트를 계층 구조로 나눠 복잡한 기능을 작은 컴포넌트로 분산시킬 수 있습니다. - 리액트 훅을 사용하면 컴포넌트 로직과 라이프사이클의 관리가 용이해집니다. - 리액트 컴포넌트에 익숙한 개발자가 많습니다. 광고의 렌더링을 리액트 컴포넌트로 표현하면?
  31. Preact 렌더러 함수 구현 import {render} from "preact"; export function

    preact_۪؊۞_ೣࣻ(ҟ Ҋࣗ੤) { render( <Component creative={ҟҊࣗ੤} />, element ); }
  32. Preact 렌더러 함수 구현 import {render} from "preact"; export function

    preact_۪؊۞_ೣࣻ(ҟ Ҋࣗ੤) { render( <Component creative={ҟҊࣗ੤} />, element ); } SDK 빌드 진입점 export default new SDK( new ۪؊݂_౵੉೐ۄੋ([ preact_۪؊۞_ೣࣻ, ۪؊݂_Ѩૐ_ೣࣻ, ૑಴_ࣻ૘_ೣࣻ, ..., ]) );
  33. 구현 방법의 풍부함 DOM 요소로 표현되네? 컴포넌트 라이프사이클 또는 상태

    로직이 필요해! 컴포넌트로 구현 안해도 되는 독립적인 기능이야!
  34. Components 구현 방법의 풍부함 Hooks DOM 요소로 표현되네? 컴포넌트 라이프사이클

    또는 상태 로직이 필요해! 컴포넌트로 구현 안해도 되는 독립적인 기능이야! Renderers
  35. - 컴포넌트를 독립적으로 테스트하며 개발할 수 있도록 도와주는 개발툴 -

    React, Vue, Svelte부터 Preact까지 다양한 프레임워크 지원 스토리북(Storybook)이란?
  36. 광고를 가리는 레이어입니다. 이 레이어에 가려지게 되면 viewable은 발동되지 않

    아야 합니다. 마우스로 드래그하여 레이어를 이동할 수 있습니다.
  37. 광고를 가리는 레이어입니다. 이 레이어에 가려지게 되면 viewable은 발동되지 않

    아야 합니다. 마우스로 드래그하여 레이어를 이동할 수 있습니다.
  38. 자동화 테스트 무겁지만 다양한 브라우저 환경 E2E Test 자동화 테스트

    실시간 개발 Unit Test 가벼운 실제 브라우저 환경 Storybook 실시간 개발
  39. 순환 복잡도 순환 복잡도(Cyclomatic Complexity)란 코드의 분기로 인한 경로 개수를

    측정해 복잡성을 나타내는 정량적 지표. 1976년 맥카비(Thomas J. McCabe)에 의해 개발됨. function isOdd(value: number) { if (value % 2 === 1) { return true; } return false; }
  40. 순환 복잡도 순환 복잡도(Cyclomatic Complexity)란 코드의 분기로 인한 경로 개수를

    측정해 복잡성을 나타내는 정량적 지표. 1976년 맥카비(Thomas J. McCabe)에 의해 개발됨. function isOdd(value: number) { if (value % 2 === 1) { return true; } return false; } 순환 복잡도 = P(분기 개수) + 1 = 1 + 1 = 2
  41. 순환 복잡도 비교 0 10 20 30 40 50 렌더링

    코드 메인 코드 개편 전 개편 후