├── .github └── workflows │ └── action.yml ├── .mergify.yml ├── Android └── application fundamentals.md ├── Browser ├── BrowserXY.md ├── Cookie.md ├── Cookie_Store.md ├── FOUC.md ├── HTTP2_Websocket.md ├── IndexedDB_WebSQL.md ├── Layer_Model.md ├── WebWorker.md ├── Worklet.md ├── 웹 브라우저의 작동 원리.md └── 최신_브라우저의_내부_살펴보기.md ├── CS ├── Binding.md ├── Bomb-Lab(1).md ├── Call-By-Sharing.md ├── Counting-sort.md ├── Graph.md ├── Memory.md ├── Radix-sort.md ├── aspect-oriented-programming.md ├── cohension&coupling.md ├── compression.md ├── dependency-inversion-principle.md ├── grasp.md ├── information_theory.md ├── integer_representation.md ├── interface-segregation-principle.md ├── liskov_substitution_principle.md ├── methods_in_IPC.md ├── non-blocking.md ├── non-linear-search.md ├── open-closed-principle.md ├── soc.md ├── srp.md ├── union-find.md ├── 페이징과 세그먼테이션.md └── 플로이드-와샬-알고리즘.md ├── CSS ├── CJK.md ├── WebToMobile.md └── safe-area.md ├── Database ├── DB Connection Pool.md ├── Query Builder ( Knex.js).md └── Types of Databases.md ├── Deprecated ├── AMD와 CommonJS.md ├── Async-Await.md ├── B_EventLoop.md ├── B_Module.md ├── CORS(Cross-Origin Resource Sharing).md ├── CSS 애니메이션 vs JS 애니메이션.md ├── CallByReference.md ├── EventLoop.md ├── EventLoop_Advanced.md ├── Funtional.md ├── Higher_Order_Functions.md ├── Javascript_BuildTool.md ├── Module.md ├── Promise1.md ├── Promise2.md ├── Reactive.md ├── Repaint와 Reflow.md ├── WebWorker.md ├── animation.md ├── setState.md ├── 기본적인 렌더링 최적화 방법.md ├── 웹 브라우저의 작동 원리.md └── 점진적향상_우아한하향.md ├── Design_Pattern ├── Composite.md ├── JSP model.md ├── MSA.md ├── MVC1, MVC2.md ├── MVC_MVP_MVVM.md ├── Memoization.md ├── RxJS.md ├── Singleton.md └── Throttle and Debounce.md ├── ECMAScript ├── ArrowFunction.md ├── Destructuring_Assignment.md ├── ECMA2019.md ├── ES6-module-in-Browser.md ├── Generator와 async-await.md ├── Includes_IndexOf.md ├── Iteration_Protocol.md ├── ModulePattern_class.md ├── Number_isNaN.md ├── Spread_Operator.md └── Tagged_Template_Literals.md ├── Git └── gitBy_.git.md ├── HTML ├── ARIA.md ├── DOM API.md ├── DOM.md ├── HTML-Templating.md ├── Head_Meta.md ├── Standard&QuirksMode.md ├── WebM&WebP.md ├── input태그의_value바꾸기(input태그의_dirty flag).md ├── preload&prefetch.md └── 웹 컴포넌트(Web Component).md ├── Java ├── ArrayList vs LinkedList 그리고 Vector.md ├── Comparable vs Comparator.md ├── Dependency Injection(DI).md ├── JSP와 Servlet처리.md ├── JVM(Java Virtual Machine).md ├── Java Garbage Collection(GC).md ├── Mybatis.md ├── Set.md ├── String, StringBuilder, StringBuffer.md ├── String,StringBuilder, StringBuffer차이.md ├── Upcasting과 Downcasting.md ├── WAS.md ├── copy-object.md ├── date-api-in-java.md └── junit-setup.md ├── Javascript ├── Ajax.md ├── Animation.md ├── B_Async.md ├── B_Call_Apply_Bind.md ├── B_Callback.md ├── B_Class.md ├── B_Function.md ├── B_Type.md ├── Build Tool.md ├── CallStack.md ├── Closure.md ├── Control_CSSOM.md ├── DocumentFragment.md ├── Event Delegation.md ├── InsertAdjacentHTML.md ├── JavaScript의 this.md ├── Javascript_Engine.md ├── Javascript_메모리관리.md ├── Javascript의_동작원리-변수객체(VariableObject).md ├── Javascript의_동작원리-실행컨텍스트(Execution Contexts).md ├── Jest.md ├── Learning_more_about_this.md ├── Module.md ├── MouseEvent.md ├── Object.create&Object.assign.md ├── Observer.md ├── Optional_Chaining.md ├── PromisePattern.md ├── Prototype_Chain.md ├── Proxy.md ├── Reduce.md ├── Redux State 정규화.md ├── Regular_Expressions.md ├── Scope.md ├── Some_Every.md ├── Storybook.md ├── Sync&Async_Multi&Single_Thread.md ├── TimeInJS.md ├── Variable.md ├── WebRTC.md ├── Web_Storage_API.md ├── ajax(2).md ├── bind.md ├── object.md ├── object_create_pattern-constructor.md ├── object_생성패턴.md ├── prototype(2).md ├── prototype.md ├── scope_this.md ├── throttling과 rAF.md ├── tricks_of_js.md ├── underscore와 lodash그리고 Native.md ├── window.history.md ├── 논리연산자.md ├── 렉시컬_속이기(eval).md ├── 배열 내장함수.md ├── 상태관리 라이브러리.md ├── 이벤트 루프(Event Loop).md ├── 클래스(class).md ├── 클로저.md └── 함수 선언.md ├── LICENSE ├── Language ├── Currying.md ├── Lamda.md ├── Reactive.md ├── XML_JSON.md ├── 고차함수(High Order Function).md └── 함수형 프로그래밍.md ├── ML └── 머신러닝이란.md ├── Network ├── 3-way handshaking & 4-way handshaking.md ├── CORS.md ├── DHCP&DNS.md ├── Flow control.md ├── HTTP3.md ├── IP.md ├── JSend.md ├── OSI7 Layer.md ├── REST API.md ├── REST.md ├── SOAP API.md ├── Subnetmask.md ├── Switch.md ├── TCP & UDP.md ├── TypesOfIP.md ├── comet.md ├── congestion control.md ├── get&post.md ├── http-caching.md ├── 로드밸런싱 & 클러스터링.md └── 사용자 인증 방식(Cookie, Session & oAuth 2.0 & JWT).md ├── Node.js ├── make_meta_file.md └── nodejs의_특징.md ├── OpenCV └── 이미지전처리.md ├── Performance ├── DeadLock(교착상태).md ├── HTTP2.0의 필요성.md ├── Reflow Repaint.md ├── Throttling vs Debouncing.md ├── requestAnimationFram(rAF).md ├── 기본적인 렌더링 최적화 방법.md ├── 서버 사이드 렌더링(SSR).md └── 점진적향상_우아한하향.md ├── README.md ├── React ├── Component, Props, State.md ├── Composition.md ├── Element와 Component.md ├── ImmutableState.md ├── React Server Components.md ├── React.memo.md ├── React의 Lifecycle Event.md ├── SWR.md ├── Virtual DOM.md └── props와 state.md ├── Rules ├── Commit.md └── Markdown.md ├── Security ├── HTTPS와 SSL.md ├── Response_Header_Security.md ├── SQL_Injection.md └── 리만가설과 소수정리.md ├── Tool ├── Chrome_80_DevTool.md ├── Framework vs Library.md └── Package Manager.md ├── Typescript ├── 인터페이스(Interface).md ├── 정적 타이핑.md ├── 제네릭(Generic).md └── 클래스(class).md ├── Vue └── Vue_LifeCycle.md ├── WPF └── wpf.md └── assets ├── IndexDB ├── TodoList │ ├── index.html │ ├── js │ │ ├── indexDB.js │ │ └── todo.js │ └── todoStyle.css └── index2.html ├── TEST ├── bigfile.html ├── img_css_image_sprites.png └── window.history.demo.html ├── gif ├── MobileCSS.gif ├── MobileDock.gif └── MobileLayout.gif └── images ├── CallByValue.png ├── Collection_Hierarchies.png ├── EventLoop.png ├── Functional_Programming_Main.png ├── Gecko.jpg ├── Graph-그래프.png ├── Graph-리스트_무향.png ├── Graph-리스트_유향.png ├── Graph-보행.png ├── Graph-종류.png ├── Graph-쾨니헤스베르크_다리.png ├── Graph-크기.png ├── Graph-행렬.png ├── HTML-Templating1.png ├── HTML-Templating2.png ├── HTML-Templating3.png ├── HTMLCollection.png ├── HashTable.png ├── LongPolling.png ├── Parent_Child_workflow.png ├── SQL_Injection_1.png ├── SQL_Injection_2.png ├── ScopeChain.png ├── ServletClass.png ├── Sync&Async_Multi&Single_Thread_1.jpg ├── Vue-lifecycle.png ├── Webkit.png ├── ajax.png ├── array_list.png ├── bucket-sort.png ├── call-by-sharing01.png ├── coalescing.png ├── compaction.png ├── compilerDesign.jpg ├── copy-object01.png ├── event_delegation.png ├── event_loop.jpeg ├── event_loop_gif.gif ├── flux_architecture.png ├── get&post.png ├── gitBy_.git_gitlifecycle.png ├── gitBy_.git_gitobjects.png ├── https_asymmetric_key.png ├── hystrix.png ├── insertAdjacentHTML_1.PNG ├── insertAdjacentHTML_2.PNG ├── insertAdjacentHTML_3.PNG ├── java_Runtime_Data_Areas.jpg ├── java_gc_heap.png ├── java_gc_object.png ├── java_runtime_data_area.png ├── javascript의_동작원리-실행컨텍스트(ExecutionContexts)-1.png ├── javascript의_동작원리-실행컨텍스트(ExecutionContexts)-2.png ├── linked_list.png ├── memoryHier.png ├── memorymodel.png ├── non-blocking.png ├── non-linear-search-bfs.png ├── non-linear-search-dfs.png ├── non-linear-search.gif ├── page_pageframe.png ├── polling.png ├── preflight-process.png ├── primitiveCasting.png ├── prototype1.png ├── prototype2.png ├── react_lifecylce.png ├── rendering.png ├── segmentation.png ├── server_side.png ├── servletArchitecture.png ├── streaming.png ├── typescript_access_modifier.png ├── typescript_type.png ├── was1.png ├── was2.png ├── was3.png └── was4.png /.github/workflows/action.yml: -------------------------------------------------------------------------------- 1 | name: "Pull Request Action" 2 | on: 3 | pull_request: 4 | types: [opened] 5 | 6 | jobs: 7 | test: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Create link 11 | uses: Im-D/Im-Bot/packages/pr-supporter@master 12 | with: 13 | myToken: ${{ secrets.GITHUB_TOKEN }} 14 | - name: Create reviewRequest 15 | uses: Im-D/Im-Bot/packages/pr-reviewer@master 16 | with: 17 | myToken: ${{ secrets.GITHUB_TOKEN }} 18 | - name: Create Link at README file 19 | uses: Im-D/Im-Bot/packages/update-readme@master 20 | with: 21 | myToken: ${{ secrets.GITHUB_TOKEN}} 22 | linkLocTarget: '### 📅 History' -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: Automatic merge on review 3 | # https://doc.mergify.io/examples.html#require-all-requested-reviews-to-be-approved 4 | conditions: 5 | - "#approved-reviews-by>=4" 6 | - "#changes-requested-reviews-by=0" 7 | - base=master 8 | - label=approval + 3 9 | actions: 10 | merge: 11 | method: merge 12 | delete_head_branch: {} 13 | 14 | - name: Add Label needs author response 15 | conditions: 16 | - "#changes-requested-reviews-by>=1" 17 | actions: 18 | label: 19 | add: ["needs author response"] 20 | remove: ["needs review"] 21 | 22 | - name: Remove Label needs author response 23 | conditions: 24 | - "#changes-requested-reviews-by=0" 25 | actions: 26 | label: 27 | add: ["needs review"] 28 | remove: ["needs author response"] 29 | 30 | - name: Add Label approval + 1 31 | conditions: 32 | - "#approved-reviews-by=1" 33 | actions: 34 | label: 35 | add: ["approval + 1"] 36 | 37 | - name: Add Label approval + 2 38 | conditions: 39 | - "#approved-reviews-by=2" 40 | actions: 41 | label: 42 | add: ["approval + 2"] 43 | remove: ["approval + 1"] 44 | - name: Add Label approval + 3 45 | conditions: 46 | - "#approved-reviews-by=3" 47 | actions: 48 | label: 49 | add: ["approval + 3"] 50 | remove: ["approval + 2"] 51 | -------------------------------------------------------------------------------- /Browser/FOUC.md: -------------------------------------------------------------------------------- 1 | # FOUC(Flash of Unstyled Content) 2 | 3 | `FOUC(Flash of Unstyled Content)`란 브라우저에서 웹 페이지에 접근했을 때, 미처 스타일이 적용되지 못한 상태로 화면이 나타나는 현상을 말한다. 4 | 5 | 스타일이 적용되기 전의 상태가 먼저 화면에 렌더링된 후 그 상태에서 스타일이 적용되기 때문에 스타일이 적용되는 과정이 사용자에게 그대로 노출되는 현상이다. 이러한 현상은 사용자의 경험(UX)를 떨어트리게 된다는 문제가 있다. 6 | 7 | `FOUC`는 특히 `IE(Internet Explorer)` 브라우저에서 주로 발생되며 `IE11`에서도 여전히 발생되고 있는 문제다. 8 | 9 | ## FOUC의 발생 원인 10 | 11 | `FOUC`의 발생 원인은 다양하지만 몇 가지만 우선적으로 살펴보면 다음과 같다. 12 | 13 | ### CRP(Critical Rendering Path) 14 | 15 |  16 | 17 | 위처럼 브라우저에서 화면이 그려지기까지의 주요한 과정을 `CRP(Critical Rendering Path)`라고 한다. 18 | 19 | 1. HTML 마크업을 처리하고 DOM 트리를 빌드한다. 20 | 2. CSS 마크업을 처리하고 CSSOM 트리를 빌드한다. 21 | 3. DOM 및 CSSOM을 결합하여 Rendering 트리를 형성한다. 22 | 4. Rendering 트리에서 레이아웃을 실행하여 각 노드의 기하학적 형태(화면의 위치)를 계산한다. 23 | 5. 개별 노드를 화면에 paint한다. 24 | 25 | `Render Tree`가 노출된 후 CSS와 JS 파일등으로 변경되면 이 변경 사항들이 화면에 노출될 수 있다. 이 현상이 `FOUC`다. 26 | 27 | 웹 브라우저의 작동 원리에 대해 좀 더 자세히 알고 싶다면 [다음](https://github.com/im-d-team/Dev-Docs/blob/master/Browser/%EC%9B%B9%20%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98%20%EC%9E%91%EB%8F%99%20%EC%9B%90%EB%A6%AC.md)을 참고하길 바란다. 28 | 29 | 최근의 웹 페이지들은 여러 개의 CSS 파일을 참조하거나 웹 폰트를 사용함으로써 DOM 구조를 변경하기 때문에 더욱 자주 발생할 수 있는 환경이다. 30 | 31 | ### `@import`를 사용한 CSS 32 | 33 | IE(Internet Explorer)를 제외한 브라우저의 경우, 참조(`@import`)되는 스타일이 적용될때까지 화면에 표시하지 않는다. 하지만, IE의 경우 화면에 노출된 상태로 스타일이 적용되어 FOUC를 유발한다. 34 | 35 | ### 웹 폰트의 사용 36 | 37 | 이또한 `@import`를 사용하여 스타일링을 할 때와 같은 원리로 `FOUC`가 발생하게 된다. IE는 웹 폰트를 사용할 경우 기본 폰트를 불러들이고 이를 사용된 웹 폰트로 다시 재변경되게 되는데 이 과정을 그대로 화면에 노출시키게 된다. 38 | 39 | ## FOUC 해결 40 | 41 | ### JS import 위치 변경 42 | 43 | 일반적으로 자바스크립트를 선언할 때는 성능을 위해 `
66 |` 태그 바로 위에 위치시키곤 한다. 44 | 하지만 이를 `
`태그 안으로 위치시킴으로써 `FOUC`를 개선할 수 있다. 하지만 이 방법으로는 웹 폰트나 `@import`를 사용한 CSS로 인한 `FOUC` 발생을 막을 수는 없다. 45 | 46 | ### FOUC 발생 위치의 컴포넌트 숨기기 47 | 48 | `@import` 사용으로 인한, 웹 폰트로 인한 `FOUC`발생을 막기 위해서는 `FOUC`가 발생하는 위치의 컴포넌트를 숨겼다가 웹 폰트 혹은 참조(`@import`) CSS의 로딩이 완료되면 보여주는 방법이 있다. 물론, 숨기는 것은 한 예시일 뿐이고 로딩바를 보여준다거나 스켈레톤 UI를 보여준다거나 할 수 있다. 49 | 50 | ```html 51 | 52 |
53 | 58 | 63 | 64 | 65 |
73 |