React16源码: React中的completeWork对HostComponent处理的源码实现

别再手动挂载NPU了!手把手教你用Ascend-Docker-Runtime一键启动昇腾AI容器 本文详细介绍了如何使用Ascend-Docker-Runtime一键启动昇腾AI容器,大幅简化NPU设备挂载流程。通过环境变量ASCEND_VISIBLE_DEVICES,开发者可以灵活指定NPU设备,提升开发效率。文章还提供了安装配置指南、高级使用技巧和常见问题排查方法,帮助开发者快速掌握这一高效工具。 阅读详情

HostComponent


1 )概述

  • 在 completeWork 当中,我们需要对 HostComponent 的一些操作有哪些?
    • 首先在一次更新而不是初次渲染的情况下
    • 需要去 diffProperties 来计算,需要更新的内容
    • 也就是在 vdom 中去进行一个对比来判断这一个节点是否需要真的去更新它
    • 以此来最低程度的去更新整个 dom 的一个过程
    • 对于不同 dom property,它有一些不同的处理方式

2 )源码

定位到 packages/react-reconciler/src/ReactFiberCompleteWork.js#L581

找到 case HostComponent

case HostComponent: {
  // 跳过
  popHostContext(workInProgress);
  // 跳过
  const rootContainerInstance = getRootHostContainer();
  const type = workInProgress.type;
  // 不是第一次渲染,也就是更新的时候
  if (current !== null && workInProgress.stateNode != null) {
    updateHostComponent(
      current,
      workInProgress,
      type,
      newProps,
      rootContainerInstance,
    );

    if (current.ref !== workInProgress.ref) {
      markRef(workInProgress); // 跳过
    }
  } else {
    // 第一次挂载渲染
    // 没有 props 说明有问题,提示
    if (!newProps) {
      invariant(
        workInProgress.stateNode !== null,
        'We must have new props for new mounts. This error is likely ' +
          'caused by a bug in React. Please file an issue.',
      );
      // This can happen when we abort work.
      break;
    }
    // 跳过
    const currentHostContext = getHostContext();
    // TODO: Move createInstance to beginWork and keep it on a context
    // "stack" as the parent. Then append children as we go in beginWork
    // or completeWork depending on we want to add then top->down or
    // bottom->up. Top->down is faster in IE11.
    let wasHydrated = popHydrationState(workInProgress);
    if (wasHydrated) {
      // TODO: Move this and createInstance step into the beginPhase
      // to consolidate.
      if (
        prepareToHydrateHostInstance(
          workInProgress,
          rootContainerInstance,
          currentHostContext,
        )
      ) {
        // If changes to the hydrated node needs to be applied at the
        // commit-phase we mark this as such.
        markUpdate(workInProgress);
      }
    } else {
      // 第一次挂载
      // 注意,这里,创建 element的过程
      let instance = createInstance(
        type,
        newProps,
        rootContainerInstance,
        currentHostContext,
        workInProgress,
      );

      // 第一次渲染,要添加子节点
      appendAllChildren(instance, workInProgress, false, false);

      // Certain renderers require commit-time effects for initial mount.
      // (eg DOM renderer supports auto-focus for certain elements).
      // Make sure such renderers get scheduled for later work.
      if (
        // 主要功能: 对dom节点上面的可能的事件监听,需要初始化整个react的事件体系
        // 这个函数返回当前节点 是否需要 autoFocus
        finalizeInitialChildren(
          instance,
          type,
          newProps,
          rootContainerInstance,
          currentHostContext,
        )
      ) {
        // 如果上面if最终是 autofocus, 就要在这个 workInProgress 上面去增加 Update 的 SideEffect
        // 来告诉后续commit的时候要执行一定的操作
        markUpdate(workInProgress);
      }
      workInProgress.stateNode = instance; // 挂载 instance
    }

    if (workInProgress.ref !== null) {
      // If there is a ref on a host node we need to schedule a callback
      markRef(workInProgress);
    }
  }
  break;
}
  • 进入 createInstance
    // packages/react-dom/src/client/ReactDOMHostConfig.js#L167
    // 这个方法就是创建节点的过程
    export function createInstance(
      type: string,
      props: Props,
      rootContainerInstance: Container,
      hostContext: HostContext,
      internalInstanceHandle: Object,
    ): Instance {
      let parentNamespace: string;
      if (__DEV__) {
        // TODO: take namespace into account when validating.
        const hostContextDev = ((hostContext: any): HostContextDev);
        validateDOMNesting(type, null, hostContextDev.ancestorInfo);
        if (
          typeof props.children === 'string' ||
          typeof props.children === 'number'
        ) {
          const string = '' + props.children;
          const ownAncestorInfo = updatedAncestorInfo(
            hostContextDev.ancestorInfo,
            type,
          );
          validateDOMNesting(null, string, ownAncestorInfo);
        }
        parentNamespace = hostContextDev.namespace;
      } else {
        parentNamespace = ((hostContext: any): HostContextProd);
      }
      // 主要在这里
      const domElement: Instance = createElement(
        type,
        props,
        rootContainerInstance,
        parentNamespace,
      );
      // 后面会进入这个方法
      precacheFiberNode(internalInstanceHandle, domElement);
      // 同上
      updateFiberProps(domElement, props);
      return domElement;
    }
    
    • 进入 createElement
      // 不展开这个方法里面调用的内容
      export function createElement(
        type: string,
        props: Object,
        rootContainerElement: Element | Document,
        parentNamespace: string,
      ): Element {
        let isCustomComponentTag;
      
        // We create tags in the namespace of their parent container, except HTML
        // tags get no namespace.
        // 先要获取 document, 先要通过 document 的api来创建
        const ownerDocument: Document = getOwnerDocumentFromRootContainer(
          rootContainerElement,
        );
        let domElement: Element;
        let namespaceURI = parentNamespace;
        // 在React中有区分,不同节点类型,都会有一个定义,比如html普通节点, svg节点等
        if (namespaceURI === HTML_NAMESPACE) {
          namespaceURI = getIntrinsicNamespace(type);
        }
        // 如果是 html 类型节点,做一些特殊处理
        if (namespaceURI === HTML_NAMESPACE) {
          if (__DEV__) {
            isCustomComponentTag = isCustomComponent(type, props);
            // Should this check be gated by parent namespace? Not sure we want to
            // allow <SVG> or <mATH>.
            warning(
              isCustomComponentTag || type === type.toLowerCase(),
              '<%s /> is using incorrect casing. ' +
                'Use PascalCase for React components, ' +
                'or lowercase for HTML elements.',
              type,
            );
          }
          // 对script节点进行特殊处理
          if (type === 'script') {
            // Create the script via .innerHTML so its "parser-inserted" flag is
            // set to true and it does not execute
            const div = ownerDocument.createElement('div');
            div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
            // This is guaranteed to yield a script element.
            const firstChild = ((div.firstChild: any): HTMLScriptElement);
            domElement = div.removeChild(firstChild);
          } else if (typeof props.is === 'string') {
            // $FlowIssue `createElement` should be updated for Web Components
            domElement = ownerDocument.createElement(type, {is: props.is});
          } else {
            // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
            // See discussion in https://github.com/facebook/react/pull/6896
            // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
            domElement = ownerDocument.createElement(type);
            // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple`
            // attribute on `select`s needs to be added before `option`s are inserted. This prevents
            // a bug where the `select` does not scroll to the correct option because singular
            // `select` elements automatically pick the first item.
            // See https://github.com/facebook/react/issues/13222
            if (type === 'select' && props.multiple) {
              const node = ((domElement: any): HTMLSelectElement);
              node.multiple = true;
            }
          }
        } else {
          domElement = ownerDocument.createElementNS(namespaceURI, type);
        }
      
        if (__DEV__) {
          if (namespaceURI === HTML_NAMESPACE) {
            if (
              !isCustomComponentTag &&
              Object.prototype.toString.call(domElement) ===
                '[object HTMLUnknownElement]' &&
              !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)
            ) {
              warnedUnknownTags[type] = true;
              warning(
                false,
                'The tag <%s> is unrecognized in this browser. ' +
                  'If you meant to render a React component, start its name with ' +
                  'an uppercase letter.',
                type,
              );
            }
          }
        }
      
        return domElement;
      }
      
    • 进入 precacheFiberNode
      const internalInstanceKey = '__reactInternalInstance$' + randomKey;
      
      // 就是在node上挂载上述属性
      // hostInst, node 对应着 internalInstanceHandle, domElement
      // 相当于在 对应dom节点上,通过 internalInstanceKey 这个 key
      // 去创建一个指向 fiber 对象的引用
      // 后期,我们想要从dom对象上获取对应的 fiber就可以方便获取
      export function precacheFiberNode(hostInst, node) {
        node[internalInstanceKey] = hostInst;
      }
      
    • 进入 updateFiberProps
      const internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
      
      // 两个参数 node 和 props, 对应着 domElement, props
      // 在 domElement 上用一个key 存储 props
      // props 会对应到上面 domElement 的 attribute, 所以,有对应关系,方便后期取用
      export function updateFiberProps(node, props) {
        node[internalEventHandlersKey] = props;
      }
      
  • 进入 appendAllChildren
    appendAllChildren = function(
      parent: Instance,
      workInProgress: Fiber,
      needsVisibilityToggle: boolean,
      isHidden: boolean,
    ) {
      // We only have the top Fiber that was created but we need recurse down its
      // children to find all the terminal nodes.
      let node = workInProgress.child;
      // 这个循环的意义:对当前节点下寻找第一层的dom节点或text节点,不会append 嵌套(继续下一层)的dom节点
      // 这样做的原因,因为对每个dom节点都会有这样一个执行 completeWork 的阶段
      // 也就是当前层只找自己下一层的dom或text, 一层一层的向下找,不会存在忽略的问题
      while (node !== null) {
        if (node.tag === HostComponent || node.tag === HostText) {
          // 注意这里,挂载节点 
          // parent 是刚刚创建的 instance
          // node.stateNode 是当前节点子节点对应的Fiber对象
          // 如果说,它的子节点那一层上面发现了原生dom节点或者文本节点,就把它挂载到节点上面
          appendInitialChild(parent, node.stateNode);
        } else if (node.tag === HostPortal) {
          // If we have a portal child, then we don't want to traverse
          // down its children. Instead, we'll get insertions from each child in
          // the portal directly.
        } else if (node.child !== null) {
          // 向下遍历
          node.child.return = node;
          node = node.child;
          continue;
        }
        // 这里直接 return
        if (node === workInProgress) {
          return;
        }
        // 没有兄弟节点,向上遍历
        while (node.sibling === null) {
          if (node.return === null || node.return === workInProgress) {
            return;
          }
          node = node.return;
        }
        // 这个本来如此,对sibling进行挂载操作
        node.sibling.return = node.return;
        // 循环找 sibling 节点
        node = node.sibling;
      }
    };
    
    • 进入 appendInitialChild
      // 这个函数执行的就是 dom 节点的 appendChild方法
      export function appendInitialChild(
        parentInstance: Instance,
        child: Instance | TextInstance,
      ): void {
        parentInstance.appendChild(child);
      }
      
  • 进入 finalizeInitialChildren
    export function finalizeInitialChildren(
      domElement: Instance,
      type: string,
      props: Props,
      rootContainerInstance: Container,
      hostContext: HostContext,
    ): boolean {
      // 做了初始化事件监听,对创建的节点根据 props 设置对应的 attribute 的封装
      setInitialProperties(domElement, type, props, rootContainerInstance);
      // 返回该节点是否需要 autoFocus
      return shouldAutoFocusHostComponent(type, props);
    }
    
    • 进入 setInitialProperties
      export function setInitialProperties(
        domElement: Element,
        tag: string,
        rawProps: Object,
        rootContainerElement: Element | Document,
      ): void {
        const isCustomComponentTag = isCustomComponent(tag, rawProps);
        if (__DEV__) {
          validatePropertiesInDevelopment(tag, rawProps);
          if (
            isCustomComponentTag &&
            !didWarnShadyDOM &&
            (domElement: any).shadyRoot
          ) {
            warning(
              false,
              '%s is using shady DOM. Using shady DOM with React can ' +
                'cause things to break subtly.',
              getCurrentFiberOwnerNameInDevOrNull() || 'A component',
            );
            didWarnShadyDOM = true;
          }
        }
      
        // TODO: Make sure that we check isMounted before firing any of these events.
        let props: Object;
        // 看下面的 switch 大部分都是绑定事件
        // 大部分都是绑定事件,这个叫做 trapBubbledEvent ,这个方法就是用来绑定事件的
        // react它有一个自己开发的事件体系,它是在dom的事件体系上面去包装了一层
        // 比如说他这边传入了这个 TOP_LOAD 
        // 它有一些事件类型,它会区分不同的一些事件类型来进行一个不同的事件绑定的方式,然后会有很多的事件的一个依赖关系
        // 可以看到这边有各种各样的不同的事件绑定。比如说 TOP_ERROR, TOP_TOGGLE, TOP_INVALID, TOP_SUBMIT
        // 对于input标签,option,select,taxtarea 都会调用对应的处理程序,如 ReactDOMInput, ReactDOMTextarea等
        // 它们都有一定的封装,因为对于这些,我们认为它是一个交互组件,就是我们要进行一些输入用户操作的一些组件
        // 比如说,input它调用的这个方法叫做 ReactDOMInput.initWrapperState 这个方法
        switch (tag) {
          case 'iframe':
          case 'object':
            trapBubbledEvent(TOP_LOAD, domElement);
            props = rawProps;
            break;
          case 'video':
          case 'audio':
            // Create listener for each media event
            for (let i = 0; i < mediaEventTypes.length; i++) {
              trapBubbledEvent(mediaEventTypes[i], domElement);
            }
            props = rawProps;
            break;
          case 'source':
            trapBubbledEvent(TOP_ERROR, domElement);
            props = rawProps;
            break;
          case 'img':
          case 'image':
          case 'link':
            trapBubbledEvent(TOP_ERROR, domElement);
            trapBubbledEvent(TOP_LOAD, domElement);
            props = rawProps;
            break;
          case 'form':
            trapBubbledEvent(TOP_RESET, domElement);
            trapBubbledEvent(TOP_SUBMIT, domElement);
            props = rawProps;
            break;
          case 'details':
            trapBubbledEvent(TOP_TOGGLE, domElement);
            props = rawProps;
            break;
          case 'input':
            ReactDOMInput.initWrapperState(domElement, rawProps);
            props = ReactDOMInput.getHostProps(domElement, rawProps);
            trapBubbledEvent(TOP_INVALID, domElement);
            // For controlled components we always need to ensure we're listening
            // to onChange. Even if there is no listener.
            ensureListeningTo(rootContainerElement, 'onChange');
            break;
          case 'option':
            ReactDOMOption.validateProps(domElement, rawProps);
            props = ReactDOMOption.getHostProps(domElement, rawProps);
            break;
          case 'select':
            ReactDOMSelect.initWrapperState(domElement, rawProps);
            props = ReactDOMSelect.getHostProps(domElement, rawProps);
            trapBubbledEvent(TOP_INVALID, domElement);
            // For controlled components we always need to ensure we're listening
            // to onChange. Even if there is no listener.
            ensureListeningTo(rootContainerElement, 'onChange');
            break;
          case 'textarea':
            ReactDOMTextarea.initWrapperState(domElement, rawProps);
            props = ReactDOMTextarea.getHostProps(domElement, rawProps);
            trapBubbledEvent(TOP_INVALID, domElement);
            // For controlled components we always need to ensure we're listening
            // to onChange. Even if there is no listener.
            ensureListeningTo(rootContainerElement, 'onChange');
            break;
          default:
            props = rawProps;
        }
      
        // 验证 props 并给出提醒
        assertValidProps(tag, props);
      
        // 初始化dom的属性相关逻辑
        setInitialDOMProperties(
          tag,
          domElement,
          rootContainerElement,
          props,
          isCustomComponentTag,
        );
      
        switch (tag) {
          case 'input':
            // TODO: Make sure we check if this is still unmounted or do any clean
            // up necessary since we never stop tracking anymore.
            inputValueTracking.track((domElement: any));
            ReactDOMInput.postMountWrapper(domElement, rawProps, false);
            break;
          case 'textarea':
            // TODO: Make sure we check if this is still unmounted or do any clean
            // up necessary since we never stop tracking anymore.
            inputValueTracking.track((domElement: any));
            ReactDOMTextarea.postMountWrapper(domElement, rawProps);
            break;
          case 'option':
            ReactDOMOption.postMountWrapper(domElement, rawProps);
            break;
          case 'select':
            ReactDOMSelect.postMountWrapper(domElement, rawProps);
            break;
          default:
            if (typeof props.onClick === 'function') {
              // TODO: This cast may not be sound for SVG, MathML or custom elements.
              trapClickOnNonInteractiveElement(((domElement: any): HTMLElement));
            }
            break;
        }
      }
      
      • 进入 ReactDOMInput.initWrapperState
        // packages/react-dom/src/client/ReactDOMInput.js
        export function initWrapperState(element: Element, props: Object) {
          // 跳过 DEV
          if (__DEV__) {
            ReactControlledValuePropTypes.checkPropTypes('input', props);
        
            if (
              props.checked !== undefined &&
              props.defaultChecked !== undefined &&
              !didWarnCheckedDefaultChecked
            ) {
              warning(
                false,
                '%s contains an input of type %s with both checked and defaultChecked props. ' +
                  'Input elements must be either controlled or uncontrolled ' +
                  '(specify either the checked prop, or the defaultChecked prop, but not ' +
                  'both). Decide between using a controlled or uncontrolled input ' +
                  'element and remove one of these props. More info: ' +
                  'https://fb.me/react-controlled-components',
                getCurrentFiberOwnerNameInDevOrNull() || 'A component',
                props.type,
              );
              didWarnCheckedDefaultChecked = true;
            }
            if (
              props.value !== undefined &&
              props.defaultValue !== undefined &&
              !didWarnValueDefaultValue
            ) {
              warning(
                false,
                '%s contains an input of type %s with both value and defaultValue props. ' +
                  'Input elements must be either controlled or uncontrolled ' +
                  '(specify either the value prop, or the defaultValue prop, but not ' +
                  'both). Decide between using a controlled or uncontrolled input ' +
                  'element and remove one of these props. More info: ' +
                  'https://fb.me/react-controlled-components',
                getCurrentFiberOwnerNameInDevOrNull() || 'A component',
                props.type,
              );
              didWarnValueDefaultValue = true;
            }
          }
        
        
          const node = ((element: any): InputWithWrapperState);
        
          // 关于 defaultValue, 如果不希望使用value来绑定input它的一个值
          // 如果绑定了value这个值,我们input的value,只能通过 setState 这个value的值来进行一个变更
          // 如果我们没有绑定事件,那么我们在input里面输入是不会有任何变化的
          // 那这个时候我们如果要有初始的值,又不希望去绑定 value
          // 可以通过使用 defaultValue,如果没有 defaultvalue 它就是一个空的
          const defaultValue = props.defaultValue == null ? '' : props.defaultValue;
        
          // 在input对应的dom节点上面呢去挂载了一个属性,叫做 _wrapperState
          // 它里面定义了3个属性
          node._wrapperState = {
            initialChecked:
              props.checked != null ? props.checked : props.defaultChecked,
            initialValue: getToStringValue(
              props.value != null ? props.value : defaultValue,
            ),
            controlled: isControlled(props),
          };
        }
        
        • 进入 isControlled
          // 处理 checkbox 和 radio
          function isControlled(props) {
            const usesChecked = props.type === 'checkbox' || props.type === 'radio';
            return usesChecked ? props.checked != null : props.value != null;
          }
          
      • 进入 getHostProps
        export function getHostProps(element: Element, props: Object) {
          const node = ((element: any): InputWithWrapperState);
          const checked = props.checked;
          // 组合 props
          const hostProps = Object.assign({}, props, {
            defaultChecked: undefined,
            defaultValue: undefined,
            value: undefined,
            checked: checked != null ? checked : node._wrapperState.initialChecked,
          });
        
          return hostProps;
        }
        
      • 对于 assertValidProps 和 setInitialDOMProperties
        • 这样两项封装的Dom操作细节处理,不展开
        • 前者做提示处理,后者做dom操作
    • 进入 shouldAutoFocusHostComponent
      function shouldAutoFocusHostComponent(type: string, props: Props): boolean {
        // 对可以 focus 的 dom节点进行 bool 处理,注意,这里没有 break
        switch (type) {
          case 'button':
          case 'input':
          case 'select':
          case 'textarea':
            return !!props.autoFocus;
        }
        return false;
      }
      
  • 进入 markUpdate
    // 标记 Update 这个 SideEffect
    function markUpdate(workInProgress: Fiber) {
      // Tag the fiber with an update effect. This turns a Placement into
      // a PlacementAndUpdate.
      workInProgress.effectTag |= Update;
    }
    
  • 关于 更新时的 updateHostComponent 这块后续单独拿出来说
uniapp - 强力解决H5网页浏览器跨域问题,如何解决uniapp请求接口在浏览器跨域问题,UniApp H5 跨域代理配置详细教程完美解决所有uniapp跨域(调用第三方接口或服务器api跨域) uni-app 跨域,uniApp解决h5跨域问题,解决uni-app请求接口在浏览器跨域问题,uni.request请求跨域问题解决方案,uni-app-跨域解决方法,彻底解决uniapp发布为H5的跨域问题,uniapp H5页面设置跨域请求_uniapp h5跨域配置,uniapp开发 H5 解决跨域问题,uniApp请求解决跨域问题,uniapp request如何实现前端请求跨域,解决uniapp调试过程中的请求跨域和环境配置,Uniapp调用外部api接口跨域请求,uni-app发布H5页面跨域 阅读详情

相关推荐

ArcGIS Pro 3.0 加载天地图WMTS服务,解决偏移问题的保姆级教程(附最新Key申请流程)

本文详细介绍了在ArcGIS Pro 3.0中精准加载天地图WMTS服务的全流程,包括最新Key申请流程、解决地图偏移问题的关键配置步骤以及常见问题排查方法。通过设置`esri`参数和统一坐标参考,确保地理数据与天地图底图精确匹配,提升GIS空间分析的准确性。

weixin_28713947的博客 310

React16源码: React中的HostComponent & HostText的源码实现

`HostComponent` 就是我们dom原生的这些节点, 如: div, span, p 标签这种, 使用的是小写字母开头的这些节点一般都认为它是一个 HostComponent, `HostText`,它是单纯的文本节点, 主要关注它们的一个更新过程

Wang的专栏 1538

手机如何高效辅助林业调查

手机如何高效辅助林业调查 很多林业工作者将栅格类型的地形图处理后导入平板电脑,在林地使用平板电脑加载小班矢量图,辅助林业调查。但是,如果没有地形图底图,这种方法可能就有难度,而且最重要的是,大部分林地工作者没有能力配置平板电脑。大凡林业基层工作者在林地调查时,除调查记录本等部分纸质材料外,都必然携带手机和水杯,此外其他设备已经成为累赘,尤其是炎热的夏季在杂灌丛生的林地进行调查作业。因此,使用手机...

xu780820的博客 3079

助你理解 React 工作的机制——实现一个简单的自定义渲染器

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。Fiber 节点上有三个属性用来描述虚拟 dom 的关系) react-dom render 中对应的方法的实现。

小王的技术库 679

多臂老虎机——入门强化学习

多臂老虎机(Multi-Armed Bandit,MAB)问题是强化学习的经典入门例子,也是理解探索与利用(exploration-exploitation)平衡的重要案例。

qq_56683019的博客 2462

YOLOv13教程:手把手教你CSP_MutilScaleEdgeInformationSelect模块 通过DSM 在空间与局部对比域上做自适应选择

绿色线条为添加CSP_MutilScaleEdgeInformationSelect后的训练效果,map50指标提升12.45,准确率提升5.44。

FJN110的博客 816

react源码学习-实习篇-状态更新

实现篇-状态更新 状态更新的流程-几个关键节点 先了解几个关键函数的调用,看看常见触发状态更新的方法是如何工作的。 render阶段的开始 之前就了解归,render阶段开始于performSyncWorkOnRoot/performConcurrentWorkOnRoot,他们会执行对应的performUnitOfWork方法。 commit阶段的开始 commit阶段开始于commitRoot方法的调用,rootFiber作为传参。 render阶段完成后会进入commit阶段。那么从触发状态更新,到r

lin_fightin的博客 1755

39-高级优化技术:指令调度与乱序执行 - 手把手教你手写CPU

本文介绍了现代处理器设计中提高指令级并行性(ILP)的两种关键技术:指令调度和乱序执行。指令调度分为静态调度(由编译器完成)和动态调度(由硬件完成),后者能更好适应运行时情况但复杂度更高。乱序执行通过动态重排指令顺序提高硬件利用率,其核心组件包括重排序缓冲区、保留站和寄存器重命名。文章提供了保留站的Verilog实现示例,并分析了不同优化技术在性能、硬件开销和功耗方面的权衡。最终指出,CPU设计需根据性能、功耗等需求选择合适的优化技术。

2301_79143213的博客 86

GPT-4稀疏激活原理:1.8万亿参数与2%每token的工程真相

大语言模型中的稀疏激活是一种通过动态选择子网络(如MoE专家)来降低计算开销的关键技术,其核心在于平衡模型容量、硬件约束与推理效率。它基于专家混合(MoE)架构,利用路由网络实现token级参数选择,使实际参与前向计算的参数远小于总参数量。这种机制显著缓解显存带宽压力,支持千亿级知识容量在有限GPU资源下部署,广泛应用于高并发API服务、边缘推理与模型量化落地场景。本文深入解析GPT-4所采用的1.8万亿参数规模与约2%每token激活率背后的架构设计、动态路由逻辑及INT4量化部署实践,揭示稀疏性并非固定

weixin_33860528的博客 1314

第14.11章 高翔博士最新开源框架Lightning-LM源码解读(十一):离线定位模块全解析,从激光匹配到位姿图优化的极致优化

本文介绍了Lightning-LM离线定位模块的技术架构与实现细节。该模块基于3D激光雷达与IMU融合,采用改进版NDT匹配算法实现高精度定位,具备动态图层更新、多源信息融合等特性。核心流程包括数据预处理、激光里程计处理、IMU预测与点云去畸变、位姿图优化等环节,通过轻量级miao库实现高效增量优化。文章详细解析了模块的代码结构、关键函数功能及数据流,为SLAM系统的开发与优化提供了实践参考。

行知SLAM 376

【C#学习记录】如何让界面控件实现自适应布局(Winform)

小伙伴们大家好,我是雷工!在软件界面设计中,客户常常要求设计的界面可以随意缩放,缩放过程中,界面中的按钮等控件也会随着窗体变大缩小自动调整显示位置和尺寸大小。在C#的Winform窗体中如何实现这个效果,下面我们一起学习下。

做有价值的事,积累有价值的笔记! 1万+

「React进阶」一文吃透react事件原理

一 前言今天我们来一起探讨一下React事件原理,这篇文章,我尽量用通俗简洁的方式,把React事件系统讲的明明白白。我们讲的react版本是16.13.1 , v17之后react对于事...

qq_34998786的博客 844

vue+ThreeJS:从0 到1 搭建开发环境

本系列教程是在vue2.X的基础上加载threeJS程序,来开发各种示例程序。

大剑师兰特的GIS世界 2344

React16源码: React中的completeWork中对不同类型节点处理的源码实现

在 `completeUnitOfWork` 当中,在节点是正常渲染没有任何出错的情况下, 会去调用 completework,对这个节点进行一个完成工作的一系列操作, 在update各种component的时候,执行了各种获取context相关的内容

Wang的专栏 725

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

使用 MySQL 新建数据库搭建 Prisma Server:Docker 部署、服务发布与 GraphQL API 全流程实战

本教程来自 Prisma 1.x 官方文档体系(`docs/1.10/03-Tutorials2/01-Setup-Prisma/02-Create-New-DB/01-MySQL.md`),完整演示如何在本地通过 Docker 创建一台基于 MySQL 的 Prisma server,并部署第一个 Prisma service,最终通过 GraphQL Playground 对自动生成的 CRU

gitblog_00142的博客 893

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Fiber 节点 —— 一个数据结构如何承载整个 React 运行时

React通过 Fiber 节点去承载整个 React 的运行时,今天我们通过这篇文章来梳理一下 React 是如何做的,为什么要这样做,这样做背后的考量是什么?

u011397689的博客 190

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

flex 学习笔记 hostcomponent

错误:ReferenceError: Error #1069: 在 skin.TextAreaSkin 上找不到属性 hostComponent,且没有默认值。 原因:由于在皮肤文件里面没有设置 hostComponent,并且也没有在皮肤文件里面设置 focusSkinExclusions 导致 由于我删除了所有自动生成的as代码,且删除了Metadata...

weixin_34259559的博客 230

Flex 4 [HostComponent] class xxx not found (AS code)

1.Custom Button public class GrayButton extends spark.components.Button…2.Custom Button Skin [HostComponent("GrayButton")]public class GrayButtonSkin extends spark.components.supportClasses.Skin im...

weixin_34117211的博客 131

Fix signatures do not match the previously installed version

报错信息FAILURE: Build failed with an exception.* What went wrong: Execution failed for task ':app:installDebug'. > com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException: Fai

Wang的专栏 2万+

在react中 实现 base64的图片转换成formdata格式并实现上传功能

如果不想要服务端实现处理base64格式的图片的转换,那么在浏览器端来实现,部分属于伪代码,仅作为开发参考,请勿直接拷贝使用

Wang的专栏 8836

快速解决gradle下载慢的问题的小技巧

在ionic run 或build 或clean命令的时候,如果没有下载过gradle, 需要重新下载一次,而通过CLI的方式下载很慢,即使科学上网后,下载还是存在一些问题。这里总结一下,快速的下载安装方式。 步骤 本地安装 http-server 包, 通过 $ npm i -g http-server 的方式安装到全局 在官网上下载自己的版本,目前自带的版本是 2.14.1,其他版本可能在执行过

Wang的专栏 6714

React 实现 2D 画板功能

在移动端或者PC端我们来模拟画板的实现, 支持清除和导出功能,此处简单实现,仅作开发参考。 效果演示 主要代码演示 /* 此模块用于实现签名绘图功能 */ // 需要用到的变量定义 let clickX = new Array(); let clickY = new Array(); let clickDrag = new Array(); let paint; let point...

Wang的专栏 4325

React16源码: React中LegacyContext的源码实现

对于在 beginWork 中的 context 操作,可以看上述判断成立的条件下的代码,即便有符合跳过更新的操作,依然 需要 push 和 pop 操作。如果我们可以跳出组件的更新,也就是代表着当前这个 classComponent,它的state它的props都应该是没有任何变化的。对于子组件来说,它的所有子树所获取到的context肯定是经过子组件,和上层的父组件合并的 context 了, 也就是。所以,先 push 一个老的值进去再说, 然后到后面,如果发现这个组件它是要更新的,就调用这个。

Wang的专栏 2803

Fix babel-preset-react-native TransformError

错误环境新版本存在不兼容,在运行 react-native run-android 的时候,发生的错误分析: babel-preset-react-native version : @3.0.0 $ react-native -v :react-native-cli: 2.0.1 react-native: 0.47.1$node -v : v7.8.0 $ npm -v :4.4.4 解决方案

Wang的专栏 2800

React18原理: 再聊Fiber架构下的时间分片

react的任务可以被打断,其实就是基于时间分片的,人眼最高能识别的帧数不超过30帧,电影的帧数差不多是在24,浏览器的帧率一般来说是60帧,也就是每秒60个画面, 平均一个画面大概是16.5毫秒左右,浏览器正常的工作流程是运算渲染,运算,渲染运算渲染,在浏览器里面一个运算,加上一个渲染就是一帧

Wang的专栏 2796

在react项目中修改webpack中本地服务器架设的目录

一个产品的上线往往会有很多的问题,现在就出现一个需求,我们是在服务器下的某个目录进行发布,而不是根服务器,服务端不想为一个项目配置ip地址,而在react项目中,默认是走的根路径,现在我们就开始修改一下它。 前提说明 如果我们需要修改手动配置webpack, 那么根据现在的版本, 我们只能执行 npm run eject, 之后就可以着手修改了。 webpack中与需求相关的...

Wang的专栏 2397
上一篇: React16源码: React中的completeWork中对不同类型节点处理的源码实现
下一篇: React16源码: React中的updateHostComponent的源码实现
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值