HarrisonLin's Technical Learning Notes

website·Indexed 30 days ago

https://harrisonls.github.io/

A comprehensive collection of technical notes and learning records covering front-end development (React, Vue, TypeScript, HTML, CSS, JavaScript), back-end technologies (NestJS, Rust, Docker), framework workflows (Next.js, umi, IceJS), state management (Redux, Recoil), and developer tools (pnpm, Yarn, nvm, Git, VS Code). Includes interview preparation, LeetCode algorithm solutions, and explorations into SVG, WebGL, and micro-frontends.

Tokens
36.7K
Snippets
211
Records
272
Agent score
74%

What's inside HarrisonLin Knowledge Base

  1. Overview of HTML5 new features

    HTML5 introduced several capabilities to enhance web application functionality without relying on third-party plugins:

    • Web Forms 2.0: Improved form elements with new attributes.
    • Offline Data Access: Ability to store and access data locally.
    • WebSocket: Full-duplex communication channel for real-time apps.
    • Server-Sent Events (SSE): One-way data stream from server to browser.
    • Canvas: API for programmatic 2D drawing via JavaScript.
    • Audio and Video: Native embedding of multimedia content.
    • Geolocation: API to access the user's geographical location (with permission).
    • Microdata: Custom vocabulary to extend web semantics.
    • Drag and Drop: Native ability to move elements within a page.
  2. Implement drag-and-drop functionality with React-DnD

    React-DnD allows for the creation of draggable and droppable elements using a provider-based architecture. The DndProvider must wrap the application or the specific area where drag-and-drop interactions occur, specifying a backend implementation such as HTML5Backend. Components are typically enhanced using DragSource and DropTarget (HOCs) to define their behavior in the drag-and-drop lifecycle.
    import React from "react";
    import { DndProvider } from "react-dnd";
    import HTML5Backend from "react-dnd-html5-backend";
    import MyDraggableComponent from "./MyDraggableComponent";
    import MyDroppableComponent from "./MyDroppableComponent";
    
    const App = () => (
      <DndProvider backend={HTML5Backend}>
        <div style={{ display: "flex", justifyContent: "space-around" }}>
          <MyDraggableComponent id="1" />
          <MyDraggableComponent id="2" />
          <MyDroppableComponent />
        </div>
      </DndProvider>
    );
    
    export default App;
  3. Understand DNS, HTTPS, and HTTP/2 basics

    Key networking concepts for web development:

    • DNS (Domain Name System): An application layer protocol (typically running on UDP port 53) used to resolve domain names to IP addresses via recursive or iterative queries.
    • HTTPS: Not a separate protocol, but HTTP combined with SSL/TLS to provide a secure encryption layer over TCP.
    • HTTP/2: An evolution of the HTTP protocol focused on performance improvements (e.g., multiplexing).
  4. Understand Browser Process and IPC in Micro Frontends

    In a browser, the Browser process manages the overall orchestration. When a new navigation is initiated within a Renderer process (e.g., via a link click or window.location change), the Renderer process communicates this to the Browser process via Inter-Process Communication (IPC). If the navigation is to a different site, the Browser process spawns a new Renderer process to handle the page rendering. Every page load, whether via a new tab or navigation submission, follows a specific lifecycle.
  5. Understand the React Fiber architecture

    Before React 16, updates were performed via depth-first traversal, which could not be interrupted and caused performance lag in deep component trees. Fiber is a re-implementation of the reconciliation process. It transforms the virtual DOM into a linked-list structure (containing return, children, and sibling pointers). This allows React to pause, resume, or prioritize rendering work, acting as a bridge between the dynamic element tree and the actual DOM structure using a double-buffering mechanism.
  6. Understand Redux Core Principles

    Redux is based on two primary concepts:

    1. Unidirectional Data Flow: The application state describes the status at a specific point in time. The View is rendered based on this state. When an event occurs (e.g., a button click), the state is updated to a new state, which triggers a re-render of the View.
    2. Immutability: State should never be mutated directly. To update an object or array, you must create a copy of the original and modify the copy.
    // Mutable (Avoid in Redux)
    const obj = { a: 1, b: 2 };
    obj.b = 3;
    
    // Immutable (Correct way)
    const obj = { a: { c: 3 }, b: 2 };
    const obj2 = {
      ...obj,
      a: {
        ...obj.a,
        c: 42,
      },
    };
    
    const arr = ['a', 'b'];
    const arr2 = arr.concat('c'); // Returns a new array
  7. Understand the difference between Server and Client Components in Next.js

    In Next.js, components are Server Components by default.

    Server Components: Render only on the server. They provide better SEO, faster initial page loads (FCP), smaller bundle sizes (code is not sent to the client), and secure access to sensitive data/Node APIs. They support Streaming, allowing the UI to be sent in chunks.

    Client Components: Render once on the server and then hydrate on the client. They are used for interactivity, DOM manipulation, and complex UI states. To define a Client Component, add the "use client" directive at the top of the file.

    Key Constraints:

    • Server Components can import Client Components.
    • Client Components cannot import Server Components (because Server Components may use Node APIs unavailable in the browser). However, Server Components can be passed to Client Components as props.
  8. Retrieve client IP addresses with request-ip

    Use the request-ip package to retrieve the client's IP address from an HTTP request. This is particularly useful for servers running behind proxies or CDNs, as it correctly handles relevant header information to identify the actual client IP for logging, geolocation, or security controls.
  9. Understand Rust ownership rules

    Ownership is Rust's system for memory management. The core rules are:

    1. Every value has an owner.
    2. There can only be one owner at a time.
    3. When the owner goes out of scope, the value is dropped.
    fn main() {
        let s1 = String::from("hello"); // s1 owns the string
        {
            let s2 = s1; // Ownership moves from s1 to s2. s1 is now invalid.
            println!("{}", s2);
        } // s2 goes out of scope, memory is freed
    }
  10. Compare SVG and Canvas for graphics rendering

    Choose between SVG and Canvas based on the following characteristics:

    • SVG (Scalable Vector Graphics): Uses XML to describe vector-based graphics. It is a full DOM, supporting event handling, animations, and filters. It scales infinitely without loss of quality. However, performance may degrade with a very high number of complex elements as each element consumes memory and CPU.
    • Canvas: Uses JavaScript to draw bitmaps. It provides a basic drawing API and is highly performant for rendering a large number of shapes. However, it does not support a DOM for individual shapes, meaning it lacks built-in event handling for specific drawn elements and can lose quality when scaled.

    Recommendation: Use SVG for complex interactions, dynamic effects, and high-quality scaling. Use Canvas for high-performance rendering of massive amounts of graphics.

  11. Understand the React Fiber architecture

    Before React 16, updates used a synchronous depth-first traversal that could block the main thread. Fiber is a new reconciliation engine that represents the Virtual DOM as a linked list (with return, children, and sibling pointers). This allows React to break rendering work into small units, pause and resume them, and prioritize updates to keep the UI responsive.
  12. Perform Type Assertions

    Type assertions are used to tell the compiler that you know more about a value's type than it does. This can be achieved using the angle-bracket syntax or the as syntax.
    let someValue: any = "this is a string";
    
    // Angle-bracket syntax
    let strLength: number = (<string>someValue).length;
    
    // 'as' syntax
    let str_length: number = (someValue as string).length;