当前位置:首页>APP源码>启动 React APP 后,源码中经历了哪些过程?

启动 React APP 后,源码中经历了哪些过程?

  • 2026-05-12 22:05:50
启动 React APP 后,源码中经历了哪些过程?

本文作者为 360 奇舞团前端开发工程师

前言

本文中使用的React版本为18,在摘取代码的过程中删减了部分代码,具体以源代码为准。

React 18里,通过ReactDOM.createRoot创建根节点。并且通过调用原型链上的render来渲染。 本文主要是从以下两个方法来介绍展开。

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>

);

一、createRoot()

createRoot这个方法主要是用来创建FiberRoot(全局唯一,保存全局状态)和RootFiber(是应用里的第一个fiber对象),并将其关系关联起来。主要有以下过程:

  1. 校验container有效性,以及处理options参数
  2. 创建FiberRootrootFiber,并关联起来
  3. 事件代理
  4. 返回ReactDOMRoot实例
function createRoot(
  container: Element | Document | DocumentFragment,
  options?: CreateRootOptions,
): RootType 
{
  // 校验合法性,以及处理options参数,此处省略
  if (!isValidContainer(container)) {
    //...
  }

  // 调用 createFiberRoot,创建FiberRoot和rootFiber,并关联关系,最终返回FiberRoot。FiberRoot.current = rootFiber; rootFiber.stateNode = FiberRoot;
  const root = createContainer(
    container,
    ConcurrentRoot,
    null,
    isStrictMode,
    concurrentUpdatesByDefaultOverride,
    identifierPrefix,
    onRecoverableError,
    transitionCallbacks,
  );
  
  // 标记container和rootFiber关系  container['__reactContainer$' + randomKey] = root.current
  markContainerAsRoot(root.current, container); 
  
  const rootContainerElement: Document | Element | DocumentFragment =
    container.nodeType === COMMENT_NODE
      ? (container.parentNode: any)
      : container;
  
  listenToAllSupportedEvents(rootContainerElement); // 事件代理

  // 实例化,挂载render,unmount方法
  return new ReactDOMRoot(root); // this._internalRoot = root;
}

关系结构示意图

image.png

二、render()

render主要是通过调用updateContainer,将组件渲染在页面上。

ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = function(
  children: ReactNodeList,
): void 
{
  const root = this._internalRoot;
  if (root === null) {
    throw new Error('Cannot update an unmounted root.');
  }
  updateContainer(children, root, nullnull);
};

updateContainer

updateContainer主要执行了以下步骤:

  1. 获取当前时间eventTime和任务优先级lane,调用createUpdate生成update;
  2. 执行enqueueUpdate将更新添加到更新队列里,并返回FiberRoot;
  3. scheduleUpdateOnFiber 调度更新;
function updateContainer(
  element: ReactNodeList,
  container: OpaqueRoot,
  parentComponent: ?React$Component<anyany>,
  callback: ?Function,
): Lane 
{
  const current = container.current; // rootFiber
  const eventTime = requestEventTime(); // 更新触发时间
  const lane = requestUpdateLane(current); // 获取任务优先级

  // ... context 处理 

  // 创建update:{eventTime, lane, tag: UpdateState // 更新类型, payload: null, callback: null, next: null, // 下一个更新}
  const update = createUpdate(eventTime, lane); 
  update.payload = {element}; // element首次渲染时为App

  callback = callback === undefined ? null : callback;
  if (callback !== null) {
    update.callback = callback;
  }

  const root = enqueueUpdate(current, update, lane); // 将update添加到concurrentQueues队列里,返回 FiberRoot
  if (root !== null) {
    scheduleUpdateOnFiber(root, current, lane, eventTime); // 调度
    entangleTransitions(root, current, lane);
  }

  return lane;
}

调度阶段

调度入口:scheduleUpdateOnFiber

主要有以下过程:

  1. root上标记更新
  2. 通过执行ensureRootIsScheduled来调度任务
function scheduleUpdateOnFiber(
  root: FiberRoot,
  fiber: Fiber,
  lane: Lane,
  eventTime: number,
{
  markRootUpdated(root, lane, eventTime); // 在root上标记更新 
  // root.pendingLanes |= lane; 将update的lane放到root.pendingLanes
  // 设置lane对应事件时间 root.eventTimes[laneToIndex(lane)] = eventTime;

  if (
    (executionContext & RenderContext) !== NoLanes &&
    root === workInProgressRoot
  ) { 
    // 更新是在渲染阶段调度提示错误 ...
  } else { // 正常更新
    // ...
    ensureRootIsScheduled(root, eventTime); // 调度任务
    // ...
  }
}

调度优先级:ensureRootIsScheduled

该函数用于调度任务,一个root只能有一个任务在执行

  1. 设置任务的过期时间,有过期任务加入到expiredLanes
  2. 获取下一个要处理的优先级,没有要执行的则退出
  3. 判断优先级相等则复用,否则取消当前执行的任务,重新调度。
function ensureRootIsScheduled(root: FiberRoot, currentTime: number{
  const existingCallbackNode = root.callbackNode; // 正在执行的任务

  // 遍历root.pendingLanes,没有过期时间设置root.expirationTimes,有过期时间判断是否过期,是则加入到root.expiredLanes中
  markStarvedLanesAsExpired(root, currentTime);
  // 过期时间设置 root.expirationTimes = currentTime+t(普通任务5000ms,用户输入250ms);
  
  // 获取要处理的下一个lanes
  const nextLanes = getNextLanes(
    root,
    root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,
  );
  
  // 没有要执行的lanes
  if (nextLanes === NoLanes) {
    if (existingCallbackNode !== null) {
      // 取消正在执行的任务
      cancelCallback(existingCallbackNode);
    }
    root.callbackNode = null;
    root.callbackPriority = NoLane;
    return;
  }

  const newCallbackPriority = getHighestPriorityLane(nextLanes); // 获取最高优先级的lane

  const existingCallbackPriority = root.callbackPriority;
  // 优先级相等复用已有的任务
  if (
    existingCallbackPriority === newCallbackPriority &&
    !(
      __DEV__ &&
      ReactCurrentActQueue.current !== null &&
      existingCallbackNode !== fakeActCallbackNode
    )
  ) {
    return;
  }
  // 优先级变化,取消正在执行的任务,重新调度
  if (existingCallbackNode != null) {
    cancelCallback(existingCallbackNode);
  }

  let newCallbackNode; // 注册调度任务
  // 同步任务,不可中断
  // 1. 调用scheduleSyncCallback将任务添加到队列syncQueue里;
  // 2. 创建微任务,调用flushSyncCallbacks,遍历syncQueue队列执行performSyncWorkOnRoot,清空队列;
  if (newCallbackPriority === SyncLane) {
    if (root.tag === LegacyRoot) {
      scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root));
    } else {
      scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
    }
    if (supportsMicrotasks) {
      // 支持微任务
        scheduleMicrotask(() => {
          if (
            (executionContext & (RenderContext | CommitContext)) ===
            NoContext
          ) {
            flushSyncCallbacks();
          }
        });
    } else {
      scheduleCallback(ImmediateSchedulerPriority, flushSyncCallbacks);
    }
    newCallbackNode = null;
  } else {
    let schedulerPriorityLevel;
    switch (lanesToEventPriority(nextLanes)) {
      // ...
      case DefaultEventPriority:
        schedulerPriorityLevel = NormalSchedulerPriority;
        break;
      default:
        schedulerPriorityLevel = NormalSchedulerPriority;
        break;
    }
    // 非同步任务,可中断
    // 1. 维护了两个队列 timerQueue taskQueue
    // 2. 通过requestHostCallback开启宏任务执行任务
    newCallbackNode = scheduleCallback(
      schedulerPriorityLevel,
      performConcurrentWorkOnRoot.bind(null, root),
    );
  }

  root.callbackPriority = newCallbackPriority;
  root.callbackNode = newCallbackNode;
}

调度任务 scheduleSyncCallback or scheduleCallback

  • scheduleSyncCallback 只有一个队列,将任务添加到队列里。按照顺序同步执行,不能中断。
function scheduleSyncCallback(callback: SchedulerCallback// callback =》performSyncWorkOnRoot
  if (syncQueue === null) {
    syncQueue = [callback];
  } else {
    syncQueue.push(callback);
  }
}
  • scheduleCallback 有两个队列(小顶堆),timerQueue存放未就绪的任务,taskQueue存放已就绪任务。每次循环,判断timerQueue里是否有可执行任务,并将其移动到taskQueue中,然后从taskQueue中取出任务执行。
function unstable_scheduleCallback(priorityLevel, callback, options{
  // ... startTime timeout expirationTime 等初始化
  var newTask = { // 新的调度任务
    id: taskIdCounter++,
    callback, // render时为performConcurrentWorkOnRoot.bind(null, root),
    priorityLevel,
    startTime, // getCurrentTime()
    expirationTime, // startTime + timeout(根据priorityLevel,-1、250、1073741823、10000、5000、)
    sortIndex: -1// startTime > currentTime ? startTime: expirationTime,
  };
  // 按照是否过期将任务推到队列timerQueue或者taskQueue里
  if (startTime > currentTime) {
    newTask.sortIndex = startTime;
    push(timerQueue, newTask);
    if (peek(taskQueue) === null && newTask === peek(timerQueue)) {
      if (isHostTimeoutScheduled) {
        cancelHostTimeout(); // 取消当前的timeout
      } else {
        isHostTimeoutScheduled = true;
      }
      // 本质上是从timerQueue去取可以执行的任务放到taskQueue里,然后执行requestHostCallback
      requestHostTimeout(handleTimeout, startTime - currentTime);
    }
  } else {
    newTask.sortIndex = expirationTime;
    push(taskQueue, newTask);
    
    // 调度任务
    if (!isHostCallbackScheduled && !isPerformingWork) {
      isHostCallbackScheduled = true;
      requestHostCallback(flushWork); // 设置isMessageLoopRunning,开启宏任务【schedulePerformWorkUntilDeadline】(优先级:setImmediate > MessageChannel > setTimeout)执行 performWorkUntilDeadline()
    }
  }

  return newTask;
}

这里要注意下,一直以来都认为是MessageChannel优先级大于setTimeout,但在浏览器打印之后发现事实相反。这个原因是chrome在某次更新里修改了二者的优先级顺序。想了解更多可以查看这篇文章:聊聊浏览器宏任务的优先级 - 掘金

执行任务 performWorkUntilDeadline

当监听到MessageChannel message的时候,执行该方法。通过调用scheduledHostCallback(即flushWork->workLoop返回的)结果,判断是否还有任务,若有则开启下一个宏任务。

const performWorkUntilDeadline = () => {
  if (scheduledHostCallback !== null) {
    const currentTime = getCurrentTime();
    startTime = currentTime;
    const hasTimeRemaining = true;

    let hasMoreWork = true;
    try {
      hasMoreWork = scheduledHostCallback(hasTimeRemaining, currentTime); // scheduledHostCallback = flushWork ->workLoop
    } finally {
      if (hasMoreWork) {
        schedulePerformWorkUntilDeadline(); // 开启下一个宏任务MessageChannel,执行 performWorkUntilDeadline()
      } else {
        isMessageLoopRunning = false;
        scheduledHostCallback = null;
      }
    }
  } else {
    isMessageLoopRunning = false;
  }
  needsPaint = false;
};

workLoop

taskQueue取出任务执行task.callback即(performConcurrentWorkOnRoot)。如果callback返回的是函数,则表示任务被中断。否则任务执行完毕,则弹出该任务。

function workLoop(hasTimeRemaining, initialTime{
  let currentTime = initialTime;
  advanceTimers(currentTime); // 将 timerQueue里到时间执行的定时任务移动到 taskQueue 里
  currentTask = peek(taskQueue); // 从 taskQueue 取任务
  while (
    currentTask !== null &&
    !(enableSchedulerDebugging && isSchedulerPaused)
  ) {
    // 任务未过期并且任务被中断
    if (
      currentTask.expirationTime > currentTime &&
      (!hasTimeRemaining || shouldYieldToHost())
    ) {
      break;
    }
    const callback = currentTask.callback; // 在scheduleCallback接受的第二个参数:performConcurrentWorkOnRoot
    if (typeof callback === 'function') {
      currentTask.callback = null;
      currentPriorityLevel = currentTask.priorityLevel;
      const didUserCallbackTimeout = currentTask.expirationTime <= currentTime;
      // 如果返回是函数,则代表要重新执行;
      const continuationCallback = callback(didUserCallbackTimeout);
      currentTime = getCurrentTime();
      if (typeof continuationCallback === 'function') {
        // 任务暂停重新赋值callback
        currentTask.callback = continuationCallback;
      } else {
        // 任务完成弹出
        if (currentTask === peek(taskQueue)) {
          pop(taskQueue);
        }
      }
      advanceTimers(currentTime); // 每次执行完,去timerQueue查看有没有到时间的任务
    } else {
      pop(taskQueue); // 弹出该任务
    }
    currentTask = peek(taskQueue);
  }
  // 返回给外部判断是否还有任务需要执行,即performWorkUntilDeadline里面的hasMoreWork
  if (currentTask !== null) {
    return true;
  } else {
    // taskQueue里面没有任务了,从timerQueue取任务
    const firstTimer = peek(timerQueue);
    if (firstTimer !== null) {
      // 目的将timerQueue里的任务,移动到taskQueue里执行
      requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);
    }
    return false;
  }
}

Render 阶段

这里render不是实际的dom render,而是fiber树的构建阶段。

Render入口

  • performSyncWorkOnRoot: 同步更新 =》 renderRootSync =》 workLoopSync
  • performConcurrentWorkOnRoot: 异步更新 =》 renderRootConcurrent =》 workLoopConcurrent

二者的区别主要是是否调用shouldYield,判断是否中断循环。

render之后就进入了commit阶段。

function performConcurrentWorkOnRoot(root, didTimeout{
  currentEventTime = NoTimestamp;
  currentEventTransitionLane = NoLanes;

  const originalCallbackNode = root.callbackNode;
  const didFlushPassiveEffects = flushPassiveEffects();
  if (didFlushPassiveEffects) {
   // ...
  }

  let lanes = getNextLanes(
    root,
    root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,
  );
  if (lanes === NoLanes) {
    return null;
  }

  // 判断是否有用户输入、过期任务打断,需要同步渲染
  const shouldTimeSlice =
    !includesBlockingLane(root, lanes) &&
    !includesExpiredLane(root, lanes) &&
    (disableSchedulerTimeoutInWorkLoop || !didTimeout); 
  // renderRootConcurrent|renderRootSync里都会调用prepareFreshStack:构建新的workInProgress树
  let exitStatus = shouldTimeSlice
    ? renderRootConcurrent(root, lanes)
    : renderRootSync(root, lanes);
  // render执行完成或抛出异常
  if (exitStatus !== RootInProgress) {
    if (exitStatus === RootErrored) {
    }
    if (exitStatus === RootFatalErrored) {
    }

    if (exitStatus === RootDidNotComplete) {
      markRootSuspended(root, lanes);
    } else {
      // render完成
      const renderWasConcurrent = !includesBlockingLane(root, lanes);
      const finishedWork: Fiber = (root.current.alternate: any);
      if (
        renderWasConcurrent &&
        !isRenderConsistentWithExternalStores(finishedWork)
      ) {
        exitStatus = renderRootSync(root, lanes);

        if (exitStatus === RootErrored) {
        }
        if (exitStatus === RootFatalErrored) {
        }
      }
      // 将新的fiber树赋值给root.finishedWork
      root.finishedWork = finishedWork;
      root.finishedLanes = lanes;
      
      // 进入commit阶段->调用 commitRoot-> commitRootImpl;
      // commitRootImpl 执行完成之后会清空重置root.callbackNode和root.callbackPriority;以及重置workInProgressRoot、workInProgress、workInProgressRootRenderLanes。
      finishConcurrentRender(root, exitStatus, lanes); 
    }
  }

  ensureRootIsScheduled(root, now()); // 退出前检测,是否有其他更新,需要发起调度
  if (root.callbackNode === originalCallbackNode) { // 没有改变,说明任务被中断,返回function,等待调用
    return performConcurrentWorkOnRoot.bind(null, root);
  }
  return null;
}

是否可中断循环

workLoopSync 和 workLoopConcurrent

  • 共同点:用于构建fiber树,workInProgress从根开始,遍历创建fiber节点。

  • 区别是:workLoopConcurrent里面增加了shouldYield判断。

function workLoopSync() {
while (workInProgress !== null) {
performUnitOfWork(workInProgress);
}
}

function workLoopConcurrent() {
while (workInProgress !== null && !shouldYield()) {
performUnitOfWork(workInProgress);
}
}

递归阶段 performUnitOfWork

遍历过程:从rootFiber向下采用深度优先遍历,当遍历到叶子节点时(递),然后会进入到归阶段,即遍历该节点的兄弟节点,如果没有兄弟节点则返回父节点。然后进行递归的交错执行。

  • 递阶段 beginWork: 创建或复用fiber节点。diff过程在此发生;
  • 归阶段 completeWork: 由下至上根据fiber创建或复用真实节点,并赋值给fiber.stateNode
function performUnitOfWork(unitOfWork: Fiber): void // unitOfWork即workInProgress,指向下一个节点
  const current = unitOfWork.alternate;
  let next;
  next = beginWork(current, unitOfWork, renderLanes); 

  unitOfWork.memoizedProps = unitOfWork.pendingProps;
  if (next === null) {
    // 遍历到叶子节点后,开始归阶段,并创建dom节点
    completeUnitOfWork(unitOfWork);
  } else {
    workInProgress = next; // workInProgress指向next
  }

  ReactCurrentOwner.current = null;
}

递归后的新的fiber树

image.png

Commit 阶段

通过commitRoot进入commit阶段。此阶段是同步执行的,不可中断。接下来经历了三个过程:

  1. before mutation阶段(执行DOM操作前):处理DOM节点渲染/删除后的focus、blur逻辑;调用getSnapshotBeforeUpdate生命周期钩子;调度useEffect。
  2. mutation阶段(执行DOM操作):DOM 插入、更新、删除
  3. layout阶段(执行DOM操作后):调用类组件的 componentDidMount、componentDidUpdate、setState 的回调函数;或函数组件的useLayoutEffectcreate函数;更新ref

页面渲染结果

import { useState } from 'react';

export default function Count() {
const [num, setNum] = useState(1);
const onClick = () => {
setNum(num + 1);
};
return (
<div>
num is {num}
<button onClick={onClick}>点击+1</button>
</div>
);
}

function List() {
const arr = [1, 2, 3];
return (
<ul>
{arr.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
);
}

function App() {
return (
<div>
<Count />
<List />
</div>
);
}

export default App;
image.png

参考文章

[1] React https://github.com/facebook/react
[2] React技术揭秘 https://react.iamkasong.com/
[3] 图解React https://7km.top/main/macro-structure/
[4] 聊聊浏览器宏任务的优先级 https://juejin.cn/post/7202211586676064315

  • 欢迎长按图片加 ssh 为好友,我会第一时间和你分享前端行业趋势,学习途径等等。2023 陪你一起度过!
  • 关注公众号,发送消息:
    指南获取高级前端、算法学习路线,是我自己一路走来的实践。
    简历获取大厂简历编写指南,是我看了上百份简历后总结的心血。
    面经获取大厂面试题,集结社区优质面经,助你攀登高峰
因为微信公众号修改规则,如果不标星或点在看,你可能会收不到我公众号文章的推送,请大家将本公众号星标,看完文章后记得点下赞或者在看,谢谢各位!

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-05-13 02:24:09 HTTP/2.0 GET : https://g.sjds.net/a/458376.html
  2. 运行时间 : 0.132634s [ 吞吐率:7.54req/s ] 内存消耗:4,554.55kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=d481f37c587a1b56562df63117bc6a81
  1. /yingpanguazai/ssd/ssd1/www/g.sjds.net/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/g.sjds.net/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/g.sjds.net/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/g.sjds.net/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/g.sjds.net/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/g.sjds.net/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/g.sjds.net/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/g.sjds.net/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/g.sjds.net/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/g.sjds.net/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/g.sjds.net/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/g.sjds.net/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/g.sjds.net/runtime/temp/8321bd4d2de6fe7dffb246d4ae0c61fd.php ( 12.06 KB )
  140. /yingpanguazai/ssd/ssd1/www/g.sjds.net/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000598s ] mysql:host=127.0.0.1;port=3306;dbname=g_sjds;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000794s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.006971s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.003557s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001496s ]
  6. SELECT * FROM `set` [ RunTime:0.000694s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001501s ]
  8. SELECT * FROM `article` WHERE `id` = 458376 LIMIT 1 [ RunTime:0.007286s ]
  9. UPDATE `article` SET `lasttime` = 1778610249 WHERE `id` = 458376 [ RunTime:0.004793s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 65 LIMIT 1 [ RunTime:0.000704s ]
  11. SELECT * FROM `article` WHERE `id` < 458376 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.005842s ]
  12. SELECT * FROM `article` WHERE `id` > 458376 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001198s ]
  13. SELECT * FROM `article` WHERE `id` < 458376 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.003230s ]
  14. SELECT * FROM `article` WHERE `id` < 458376 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.002959s ]
  15. SELECT * FROM `article` WHERE `id` < 458376 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.003561s ]
0.136483s