You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS新手求助:如何加快基于window.onload生成页面目录的速度?

优化目录生成速度的几个实用方法

Hey there! As someone who’s wrestled with slow DOM-ready scripts early on, let’s break down how to speed up your table of contents generation—great question for a JS/jQuery newbie, this is such a common optimization hurdle!

1. 用DOMContentLoaded代替window.onload

The biggest culprit here is window.onload: it waits for every single resource on the page to finish loading—images, stylesheets, external scripts, everything. That’s why your script feels slow to run.

document.onload isn’t a standard browser event (which is why switching to it did nothing). Instead, use DOMContentLoaded: it fires the moment the HTML is parsed and the DOM structure is ready, no need to wait for non-critical resources like images.

Here’s how to swap it in:

document.addEventListener('DOMContentLoaded', function() {
  // Your TOC generation code goes here
});

2. 别用正则处理HTML字符串——直接遍历DOM元素

Your current code uses a regex to rewrite the entire innerHTML of your content section. This is both slow (parsing huge strings is inefficient) and fragile (regex can break if your <h2>/<h3> tags have extra attributes or nested elements like <span>).

Instead, directly select and iterate over heading elements—this is faster and way more reliable:

const headings = document.querySelectorAll('h2, h3'); // Grab only the levels you care about
const maxLevel = 3;
let currentLevel = 0;
const tocFragment = document.createDocumentFragment();
let currentList = null;

headings.forEach(heading => {
  const level = parseInt(heading.tagName.charAt(1));
  if (level > maxLevel) return;

  // Create anchor for the heading (use id instead of outdated name attribute)
  const anchorId = heading.textContent.replace(/[^a-zA-Z]+/g, '-');
  heading.setAttribute('id', anchorId);
  
  // Keep your offset fix for anchor scrolling
  heading.style.paddingTop = '60px';
  heading.style.marginTop = '-60px';

  // Build TOC list structure
  if (level > currentLevel) {
    // Add a nested list
    const newList = document.createElement('ol');
    currentList ? currentList.lastElementChild.appendChild(newList) : tocFragment.appendChild(newList);
    currentList = newList;
  } else if (level < currentLevel) {
    // Move up to parent lists
    for (let i = 0; i < currentLevel - level; i++) {
      currentList = currentList.parentElement.parentElement;
    }
  }

  // Add list item with link
  const listItem = document.createElement('li');
  const link = document.createElement('a');
  link.href = `#${anchorId}`;
  link.textContent = heading.textContent;
  listItem.appendChild(link);
  currentList.appendChild(listItem);

  currentLevel = level;
});

// Append the fully built TOC to the page
document.getElementById('toc').appendChild(tocFragment);

3. 用DocumentFragment减少DOM重绘

Every time you modify the DOM (like using innerHTML +=), the browser has to re-render parts of the page—this is called a reflow, and it’s expensive. DocumentFragment lets you build all your TOC elements off-screen first, then insert them all at once. This cuts down on reflows drastically and makes your script run much faster.

4. 缓存DOM元素引用

Instead of calling document.getElementById('contents') or document.getElementById('toc') multiple times, store them in variables at the start of your script. This saves the browser from searching the entire DOM every time you need the element:

const contentsEl = document.getElementById('contents');
const tocEl = document.getElementById('toc');
// Now use contentsEl and tocEl instead of re-querying

为什么你的原 code felt slow?

  • window.onload waits for all resources, not just the DOM structure
  • Regex replacement on large innerHTML strings is slow and error-prone
  • Multiple small DOM modifications (each innerHTML += triggers a reflow)

Putting all these tweaks together will make your TOC load noticeably faster, even on pages with lots of headings.

内容的提问来源于stack exchange,提问作者Ujjawal Bhandari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:37:55