본문으로 건너뛰기

만약 Web 이当初 동적화를 지원하지 않았다면

무료2020-10-03#Mind#移动端动态化#客户端容器化#移动端动态更新#热修复#插件化

만약 Web 이当初 동적화를 지원하지 않았다면, 프론트엔드 대군은 어떠한 동적화의 길을 걸어갔을까요?

서자

Web 은 태생적으로 극도로 유연한 동적화 기초 능력을 갖추고 있습니다. 예를 들어:

  • 동적으로script 태그를 삽입하여 임의의 스크립트 로직 실행

  • 동적으로style 태그를 삽입하여 임의의 CSS 스타일 규칙 도입

  • iframe 태그를 통해 전체 사이트 임베드

  • 위 태그들은 모두 직접 네트워크 리소스를 로드 가능

  • 이러한 콘텐츠를承载하는 Web 페이지는 원격 서버에 배포되며, 언제든지 동적 업데이트 가능하고, 즉시生效

지금까지의 탐색과 실천은 끊임없이 동적화 능력의 엔지니어링 가치를 발굴하고, 더 적합한 응용 시나리오를 찾고 있을 뿐입니다. 예를 들어 초기의frameset, 현재의 마이크로 프런트엔드/마이크로 애플리케이션

한편, 모바일 엔드는 정반대로, 태생적으로 많은 유연성 제한을 갖추고 있습니다:

  • 네이티브는 동적으로 로직 코드를 실행하는 것을 지원하지 않음

  • 모바일 애플리케이션을 구성하는 중요한 리소스의 대부분은 설치 패키지에 박아야 함 ([동적 라이브러리](/articles/node-js-c 확장 입문 가이드/) 는 예외)

  • 애플리케이션은 사용자 디바이스에 설치되며, 설치 패키지 업데이트는 앱 스토어 심사를 거쳐야 하고, 사용자가 재설치해야만生效

모바일 비즈니스의 발전은 끊임없이 동적화 능력에 더 높은 요구를 제기하고 있지만, 동적화의 기초 능력이 부족하여, 항상 더 유연한 기술 방안을 탐색하고 있습니다. 예를 들어 초기의 핫픽스/핫업데이트, 현재의 미니프로그램 등

실제로, 둘은 동적화 기술 능력상에서 해결해야 할 엔지니어링 문제는 일치합니다. 예를 들어 동적으로 의존 라이브러리, 뷰 컴포넌트, 심지어 전체 애플리케이션을 로드하는 등. 따라서, Web 이 동적화를 지원하지 않는다고 가정하고, Native 의 비즈니스 요구에 기반하여 Web 동적화 기술의 발전 궤적을 추연해 봅시다

##伊始: 네이티브 WebAssembly

0061 736d 0100 0000 0187 8080 8000 0160
027f 7f01 7f03 8280 8080 0001 0004 8480
8080 0001 7000 0005 8380 8080 0001 0001
0681 8080 8080 000007 9080 8080 0002 066d
656d 6f72 7902 0003 6763 6400 000a ab80
8080 0001 a580 8080 0001 017f 0240 2000
450d 0003 4020 0120 0022 026f 2100 2002
2101 2000 0d00 0b20 020f 0b20 010b

옛날, Web 애플리케이션은 이 [wasm](/articles/webassembly 시범/) 과 같은 바이너리 형식으로 패키징되어,各大手 브라우저 앱 스토어에 릴리스되는 수밖에 없었습니다. 그 사이, 수일간의 심사를 기다려야 하고, 통과한 후에도 사용자가 적극적으로 업데이트를 설치하는 것을 기다려야 하며,新版本이 진짜로「生效」할 때까지 (대부분의 사용자를 커버) 는, 이미 수개월 후가 되어 있을 가능성이 있었습니다

버전 갱신이 느려, 전략적으로 중요한 기능이라도 十万火急의 문제 수정이라도, 시기적절하게 사용자에게 도달할 수 없습니다. 설령 온라인에서 화재가 발생해도, 가장 신속한 소화 방안이라도 수일甚至수주 후가 아니면 효과를 발휘할 수 없습니다

더 신속하게 문제를 수정하고, 리스크를 낮추기 위해, 핫픽스 방안의 탐색이 여기에 시작되었습니다

낭화: 핫픽스를 위해 스크립트 언어 JavaScript 를 도입

핫픽스는 (설치 패키지 밖의) 로직 코드를 로드하여 실행해야 하므로,有人은 직접 WebAssembly 모듈 로드 메커니즘에서着手하여, 몇 가지 Hook 방안을 ��구해 내고, 동적으로 어떤 모듈/파일을 교체할 수 있었습니다

有人은 이 방향으로 더 멀리 나아가,时效性, 성능, 호환성과 안정성을 权衡하고, 컴파일挿桩, 엔지니어링 부대 시설, 런타임 프레임워크 등의 수단을 통해 모듈 의존, 버전 관리, 차량 업데이트 등의 문제를 해결하고, 애플리케이션의 각 기능 모듈을플러그인화했습니다

有人은 다른 길을 개척하고, 경량급의 스크립트 언어 런타임 (JavaScript 엔진 등) 을 도입하고, 브라우저 네이티브 WebAssembly 와 JavaScript 세계 사이에 다리를架设하여, JavaScript 를 통해 네이티브의 시스템 플랫폼 능력을 호출하는 것을 허용하여, 이로써동적화의 기초 능력을 확장했습니다

동적화는一道의 파문을漾起하고, 이어서呼啸而来的인 동적 업데이트의 파도가 왔습니다

해소: JavaScript 에 기반한 동적 업데이트

동적화 방향에 한 걸음을 내디딘 후, 전면적인 동적화의 아름다운 전망까지 한 걸음 남았습니다:

Any application that can be written in JavaScript, will eventually be written in JavaScript. —— Jeff Atwood

(The Principle of Least Power 에서 발췌)

전면적인 동적화는 다음을 의미합니다:

  • 애플리케이션 중에서 동적화 가능한 모든 부분을 JavaScript 로 구현하도록 이전

  • 방대한 JavaScript 코드를 기능 모듈별로 조직하고, 기능 모듈 간의 의존 관계를 관리

이를 통해기능 모듈을 단위로 한 신속한 이터레이션을 실현하고, 핫픽스 기술을 문제 수정 이외의 니즈 이터레이션에 적용하는것에 상당하며, 버전을 발행할 필요가 없고, 심사 사이클을免去하며, 사용자가 적극적으로 설치하는 것을 기다릴 필요도 없이, 신기능이 동적으로 릴리스되고 신속하게 액티브 사용자를 커버

제방: 컨테이너 개념 형성

동적화 정도의不断한 향상과 함께, JavaScript 의 애플리케이션 중의占比는 점점 높아지고, 최종적으로 동적화할 수 없는 (또는 동적화할 필요가 없는) 부분만 WebAssembly 로 구현되게 되었습니다. 다음을 포함합니다:

  • 시스템 플랫폼 능력 브릿지

  • 기초 UI 컨트롤, 인터랙션 능력

  • 뷰 층 프레임워크 (히스토리 스택 관리, 라이프사이클 서포트 등)

  • 특정 비즈니스 영역 능력 (예를 들어 멀티미디어 콘텐츠 제작, IM SDK 등)

  • 통신 메커니즘 (브로드캐스트, 상태 공유 등)

이러한 부분들은컨테이너(네이티브 외곽) 를 형성하고, 브라우저 중에서 실행되는 동적화 런타임에 상당하며, 컨테이너가圈定한 능력 범위 내에서, 비즈니스는 동적 우위를 충분히 이용하여, 신속한 수정, 신속한 릴리스, 신속한 도달, 신속한 이터레이션을 실현할 수 있습니다

그러나 컨테이너 개념과 함께 나타난 것은, 비즈니스를 더 빠르게 달리게 하는赋能之外에, 동적 비즈니스와 컨테이너 간의 의존 문제도 있습니다:

  • 둘 간의 강결합을 어떻게 해제하는가, 예를 들어 라우트, 혼합 뷰 컨테이너 등의 시나리오?

  • 둘 간의 의존 관계를 어떻게 식별하는가?

  • 의존 관계가 제어 가능함을 어떻게 보증하는가, 예를 들어 새 능력에 의존하는 동적 비즈니스를 구 컨테이너에 릴리스하는 것을 금지?

엔지니어링 부대 시설을 통해 의존을管束한 후, 다음的首要 문제는 동적 비즈니스가 의존하는底层 컨테이너의 신뢰성을 보증하는 방법을 생각하는 것입니다

경계:HTML, JavaScript, CSS 가 컨테이너 표준을 구성

변화를 격리하는 慣用 수단은 추상 층을 1 층 추가하고, 변화하는 부분을 추상 층의 아래에 두는 것입니다:

  • BOM API: 시스템 플랫폼, 뷰 층 프레임워크 능력 및 통신 메커니즘의 추상

  • Native Module API: 특정 비즈니스 영역 능력의 추상

  • DOM API: 기초 뷰 렌더링 능력의 추상

  • JS API: JavaScript 런타임의 추상

  • CSS: 스타일, 레이아웃 능력의 추상

  • HTML: 기초 UI 컨트롤, 인터랙션 능력의 추상

추상화된 이러한 표준들은稳固한 컨테이너 경계를 확립하고, 경계의 안쪽에서는, 동적 비즈니스는肆意하게 발휘할 수 있고, 경계의 아래에서는, 컨테이너도不断하게 정진하고, 컨테이너 능력을 풍부하게 하고, 경계를拓宽할 수 있습니다. 동시에, 표준 정의된 API 는 구조화된 형식으로 유지할 수 있고, 개발 체험에 크게裨益합니다

운해: 브라우저가 네트워크 리소스의 로드를 서포트

另一方面, 표준화 과정에서, 몇 가지 동적화 비즈니스 실천도 컨테이너の中に沈澱했습니다. 예를 들어:

  • 동적 스크립트: script 가 네트워크 리소스의 로드를 서포트

  • 동적 스타일: style 가 네트워크 리소스의 로드를 서포트

  • 동적 라우트: 브라우저가 직접 URL 을 통해 로드, 또는iframe 을 통해 네트워크 애플리케이션을 임베드하는 것을 서포트

핫픽스부터 CDN 에서 JS 파일을_PULL 하고, 런타임에서 동적으로 해석 실행할 수 있었지만, 컨테이너 표준은 이 방식에便捷한 서포트를 제공할 뿐만 아니라, 동적화의 기초 능력을 로직에서 뷰, 스타일, 정적 리소스 등으로 확대했습니다

至此, 동적화에서 가장 중요한 기초 능력이完备했습니다. JavaScript 로 이전한 기능 모듈은 더욱 클라우드에 배포할 수 있고, 오프라인 통합, 온라인托管의 2 개의 모드의 유연한 전환을 실현

일색:동기, 비동기 모드의 전환 자재

完备한 동적화 기초 능력은 많은 새로운玩法을 잠금 해제했습니다. 예를 들어:

비즈니스 모듈 (bundle) 을 더욱 기능 모듈 (chunk) 로 분할하고, 비코어 모듈을 비동기하고, 동적按需 로드를 실현합니다. 예를 들어 서드파티 JS SDK, jQuery 플러그인, 및 쉐어/댓글/도시 선택 등의 중량급 컴포넌트

콘텐츠 제시의偏静的 시나리오에 대해서는, SSR 을 통해 서버사이드에서 (대부분의) 페이지 렌더링 작업을 완료하고, 초화면 콘텐츠 제시를 가속할 수 있습니다

另一方面, Hydration, lazy 컴포넌트, Suspense 등의 런타임 특성에 의해, 온라인의 동적 부분과 오프라인의 비동적 부분을 충분히 융합할 수 있고, 더 세粒度의 비즈니스 동적화를 실현하고, 온라인托管을 진짜로 1 개의 배포 옵션으로 만듭니다

与此同时, 동적 비즈니스 자신의 컴포넌트화 정도도不断하게 깊어지고, 프론트엔드 개발의 핵심 작업은 페이지, 모듈 개발에서 컴포넌트, 편성 로직 개발로 이전했습니다

유운:데이터 구동의 프론트엔드 애플리케이션

컴포넌트 체계가趋向成熟한 후, 由来已久的인 개념이 드디어 완전히 떠올랐습니다——데이터 구동

전후단分层의 데이터 프로토콜에서, 점차 데이터 구동으로 진화했습니다. 여기의 데이터는 3 부분을 포함합니다:

  • 후단 비즈���스 영역 데이터

  • 프론트엔드 상태 데이터

  • (후단 비즈니스 영역 데이터에 기반한) 프론트엔드 파생 데이터

이러한 데이터를 비즈니스 컴포넌트에填入하면, 완전한 기능 모듈을 렌더링할 수 있습니다 (클라이언트에서도 서버사이드에서도), 그것을 뷰 컨테이너 중의 적절한坑位에放置하면, 1 회의 컴포넌트 급의「릴리스」과정이 완료됩니다

이 모드는 5 개의 중요한環節을 포함합니다:

  • 비즈니스 데이터 (후단 비즈니스 영역 데이터와 프론트엔드 파생 데이터를 포함) 의 생산

  • 비즈니스 컴포넌트 (프론트엔드 상태 데이터를 포함) 의 생산과 유지

  • 컴포넌트의 렌더링 (비즈니스 데이터 + 비즈니스 컴포넌트 = 기능 모듈)

  • 坑位의 생산

  • 기능 모듈의投放

그 중에서, 비즈니스 컴포넌트, 坑位는 더욱 동적화의 열쇠이며, 4 개의 단계로 나뉩니다:

  • 한個蘿蔔한個坑:정적 비즈니스 컴포넌트 + 정적坑位

  • 한個蘿蔔到處던짐:정적 비즈니스 컴포넌트 + 동적坑位

  • 여러個蘿蔔番輪던짐:동적 비즈니스 컴포넌트 + 정적坑位

  • 여러個蘿蔔到處던짐:동적 비즈니스 컴포넌트 + 동적坑位

여러個蘿蔔到處던짐의 컴포넌트 급 동적화究極 목표에 도달하려면, 비즈니스 컴포넌트를 동적 릴리스, 坑位를 동적 릴리스할 수 있어야 합니다

교융:동적 비즈니스 컴포넌트 + 동적坑位

端과 클라우드의 시각에서 보면, 비즈니스 컴포넌트도 데이터 (클라우드) 의 일부로 볼 수 있습니다.相比之下坑位와端의关联은 더욱 긴밀하고, 동적화의 유일한 수단은端측의 것을 클라우드 위로 옮기는 것이므로, 해결해야 할열쇠 문제는 어떻게坑位의 동적화를 실현하는가입니다

2 개의思路가 있습니다:

  • 坑位개념을干掉:坑位개념을 컴포넌트 급에서 페이지 급으로 확장하고, 1 개의 페이지 컨테이너 (1 개의 URL) 즉 1 개의坑位

  • 坑位를 컴포넌트화:표준적인坑位컴포넌트를 제공하고, iframe 처럼

페이지는天然的인 동적坑位로, 새로운 페이지 컨테이너를 열어 임의의 URL 을 로드할 수 있습니다

페이지 이외의其它레이아웃 컨테이너에 대해서는, 예를 들어 대화框, 메시지条, Banner 位, 허리띠 등은, 坑位를 표준화하여 컨테이너 컴포넌트로 하고, 비즈니스 컴포넌트와 함께 동적 릴리스하고, 坑位의賃貸 관계를 서비스端에서 유지하고, 데이터 구동의 데이터의 하나로 합니다

至此, 전후단分层의 경계는 여러 번 재정의되고, 드디어 JSP/PHP 가 데이터와 템플릿을 융합한 황금년대를 맞이했습니다……

참고 자료

댓글

아직 댓글이 없습니다

댓글 작성