Duxinyue's Technical Notes
website·Indexed 30 days ago
https://duxinyues.github.io/A collection of technical notes and tutorials covering frontend development, including JavaScript (Promise, Proxy, Reflect, I/O streams, and File API), React and Redux (store, reducer, props, and state), CSS3 (variables, @media rules, and animations), Webpack, and Electron integration with Vue3, Vite, and TypeScript.
What's inside Duxinyue's Blog
- Reflect is a built-in global object that provides methods for intercepting JavaScript operations. It is not a constructor function; all its properties and methods are static, similar to the Math object.
Overview of JavaScript Proxy and its basic usage
AProxyobject allows you to create an interception layer in front of a target object. When external code accesses the object, it must pass through this layer, allowing you to filter or rewrite operations. TheProxyconstructor takes two arguments: the target object to be proxied and a handler object containing 'traps' (interceptors). If a specific operation is not defined in the handler, the operation falls through to the target object.const proxy = new Proxy({}, { get: () => { console.log("get"); }, set: () => { console.log("set") } }); proxy.count = 1; // Triggers 'set' trap ++proxy.count; // Triggers 'get' trapUnderstand Node.js Stream types and Buffer behavior
Node.js provides four primary types of streams for handling data from sources like files, memory, or networks:
- Readable: For reading data.
- Writable: For writing data.
- Duplex (Readable-Writable): For both reading and writing.
- Transform: A type of duplex stream that can modify the data stream during the read/write process.
Streams utilize a Buffer as a temporary storage area. The size of this buffer is determined by the
highWaterMarkoption in the stream's constructor. This parameter specifies the total number of bytes (or objects) the buffer can hold; once the buffer reaches this peak, the stream pauses reading from the data source.Understand Node.js Stream types and Buffer behavior
In Node.js, I/O streams provide a mechanism to read data from or write data to devices (such as files, memory, or network sources). There are four primary types of streams:
- Readable: For reading data.
- Writable: For writing data.
- Duplex: Both readable and writable.
- Transform: A type of duplex stream that can modify the data as it is read and written.
Streams utilize a Buffer to manage data. The size of this buffer is determined by the
highWaterMarkoption in the stream's constructor. This parameter specifies the total number of bytes (or objects) the buffer can hold; once the buffer reaches this peak, the stream will pause reading from the data source.Frontend performance optimization dimensions
Frontend performance optimization should be approached from the following five dimensions: Network, Browser, Build Tools, Cross-platform technologies, and Content Delivery Networks (CDN).Understand the relationship between JSX and Fiber
JSX is a syntactic sugar forReact.createElement, allowing developers to describe node structures using HTML-like syntax. Fiber is a JavaScript object used to store node information and priority. During the initial render, JSX objects are used bycreateFiberFromElementto generate Fiber nodes. During updates, React compares the new JSX with the old JSX to generate a new Fiber tree.Reference the FiberNode structure
TheFiberNodeis the core unit of the Fiber tree. It contains metadata about the component, its relationship to other nodes, and its current state/props.function FiberNode( tag: WorkTag, pendingProps: mixed, key: null | string, mode: TypeOfMode, ) { // Instance this.tag = tag; // Component type marker this.key = key; // React element key this.elementType = null; // Element type (first arg of createElement) this.type = null; // Resolved content of async components (function or class) this.stateNode = null; // Actual DOM node // Fiber Tree Structure this.return = null; // Pointer to parent node this.child = null; // Pointer to first child this.sibling = null; // Pointer to sibling node this.index = 0; this.ref = null; // ref attribute this.pendingProps = pendingProps; // New props from updates this.memoizedProps = null; // Props from previous render this.updateQueue = null; // Queue for component updates this.memoizedState = null; // State from previous render this.dependencies = null; this.mode = mode; // Effects this.flags = NoFlags; this.subtreeFlags = NoFlags; this.deletions = null; // Priority this.lanes = NoLanes; this.childLanes = NoLanes; // Pointer between current and workInProgress this.alternate = null; // Profiler timing if (enableProfilerTimer) { this.actualDuration = 0; this.actualStartTime = -1; this.selfBaseDuration = 0; this.treeBaseDuration = 0; } }Frontend performance optimization dimensions
Frontend performance optimization should be approached from several key technical perspectives: network efficiency, browser rendering, build tool configuration, cross-platform technology implementation, and CDN (Content Delivery Network) optimization.JavaScript data types overview
JavaScript data types are categorized into two main groups:
- Primitive Data Types:
number,string,Boolean,null,undefined,symbol, andBigInt.null: A special keyword representing an empty value.undefined: Indicates that a variable has not been defined.
- Reference Data Types:
object(a composite data type).
- Primitive Data Types:
Transpile ES6 to ES5 using Babel
Babel is a JavaScript compiler that converts ES6 (and newer language features) into ES5. This allows developers to use the latest JavaScript syntax while ensuring compatibility with browsers that do not fully support ES6.Implement basic object interception using Proxy
TheProxyobject allows you to create a wrapper around a target object, intercepting fundamental operations. It takes two arguments: the target object to be wrapped and a handler object containing 'traps' (interceptors) for specific operations. If a trap is not defined in the handler, the operation falls through to the target object.const proxy = new Proxy({}, { get: () => { console.log("get"); }, set: () => { console.log("set") } }); proxy.count = 1; // Triggers 'set' trap ++proxy.count; // Triggers 'get' trapCompare Imperative vs Declarative UI patterns in JavaScript
UI development generally follows two patterns: Imperative and Declarative.
- Imperative UI: Focuses on the execution process and explicit steps to change the UI. It offers maximum performance because the developer specifies exactly what needs to change, but it is harder to maintain as the project grows. Examples include jQuery and native DOM manipulation.
- Declarative UI: Focuses on the desired end result. The framework handles the process of updating the UI to match that state. It is significantly easier to maintain but introduces a performance overhead because the framework must calculate the difference between the current state and the new state (diffing).
Examples of changing a div's text to 'hello world' on click:
// Imperative: jQuery $("#app").text("hello world"); // Imperative: Native JavaScript let app = document.querySelector('#app') app.addEventListener("click", function () { app.innerText = "hello world"; }) // Declarative: React import React from "react"; function WordClassification() { const [text, setText] = React.useState('text'); return <div onClick={() => { setText("hello world") }}>{text}</div>; }