[{"data":1,"prerenderedAt":435},["ShallowReactive",2],{"post-\u002Fposts\u002Fdeleted-90-percent":3,"post-nav-\u002Fposts\u002Fdeleted-90-percent":397,"post-related-\u002Fposts\u002Fdeleted-90-percent":417},{"id":4,"title":5,"body":6,"category":382,"cover":383,"date":384,"description":385,"draft":386,"extension":387,"featured":386,"meta":388,"navigation":305,"path":389,"pinned":386,"seo":390,"stem":391,"tags":392,"updated":383,"__hash__":396},"posts\u002Fposts\u002Fdeleted-90-percent.md","我删掉了站点的 90% 功能",{"type":7,"value":8,"toc":374},"minimark",[9,13,16,19,23,26,93,96,99,102,148,151,154,164,167,170,173,234,237,240,319,322,325,328,334,337,340,343,353,364,367,370],[10,11,12],"p",{},"上一个版本的博客有 14 个页面、3 个第三方脚本、一套后台、还有评论系统。",[10,14,15],{},"我每个月写两篇文章。",[10,17,18],{},"这两件事之间存在严重的不匹配。",[20,21,22],"h2",{"id":22},"先算笔账",[10,24,25],{},"我把访问数据拉出来看了看：",[27,28,29,45],"table",{},[30,31,32],"thead",{},[33,34,35,39,42],"tr",{},[36,37,38],"th",{},"页面",[36,40,41],{},"月访问",[36,43,44],{},"占比",[46,47,48,60,71,82],"tbody",{},[33,49,50,54,57],{},[51,52,53],"td",{},"首页",[51,55,56],{},"1,240",[51,58,59],{},"41%",[33,61,62,65,68],{},[51,63,64],{},"文章详情",[51,66,67],{},"1,510",[51,69,70],{},"50%",[33,72,73,76,79],{},[51,74,75],{},"归档",[51,77,78],{},"180",[51,80,81],{},"6%",[33,83,84,87,90],{},[51,85,86],{},"其他所有页面",[51,88,89],{},"90",[51,91,92],{},"3%",[10,94,95],{},"「其他所有页面」包括：分类索引、标签云、友链、关于、搜索页、404、两个我忘了当初为什么建的空页面。",[10,97,98],{},"它们加起来占了 3% 的流量，却占了我 70% 的维护时间。",[20,100,101],{"id":101},"删掉的清单",[103,104,105,113,119,125,131,137],"ul",{},[106,107,108,112],"li",{},[109,110,111],"strong",{},"后台管理"," —— 我用 Vim 写 markdown 比用任何后台都快",[106,114,115,118],{},[109,116,117],{},"评论系统"," —— 一年收到 4 条评论，其中 3 条是垃圾",[106,120,121,124],{},[109,122,123],{},"访问统计的第三方脚本"," —— 一个用了 8 年的静态博客，我不需要实时看板",[106,126,127,130],{},[109,128,129],{},"搜索独立页"," —— 搜索应该是弹窗，不该是一次页面跳转",[106,132,133,136],{},[109,134,135],{},"分类页的独立布局"," —— 它和标签页长得一模一样，为什么要写两遍",[106,138,139,142,143,147],{},[109,140,141],{},"暗色模式的切换动画库"," —— 我写了 40 行 ",[144,145,146],"code",{},"clip-path"," 替代了它",[20,149,150],{"id":150},"保留的东西",[10,152,153],{},"删完之后剩下这些，一个都不能少：",[155,156,161],"pre",{"className":157,"code":159,"language":160},[158],"language-text","\u002F                 首页，最新文章列表\n\u002Fposts\u002F[slug]     文章\n\u002Farchive          归档\n\u002Fcategories       分类\n\u002Ftags             标签\n\u002Flinks            友链\n\u002Fabout            关于\n\u002Frss.xml          订阅\n","text",[144,162,159],{"__ignoreMap":163},"",[10,165,166],{},"九个路由。其中三个（分类、标签、归档）共用同一个列表组件——它们本来就是同一个东西的不同切片。",[20,168,169],{"id":169},"性能是删出来的",[10,171,172],{},"改动前后，用 Lighthouse 在同一台机器上测：",[27,174,175,188],{},[30,176,177],{},[33,178,179,182,185],{},[36,180,181],{},"指标",[36,183,184],{},"改前",[36,186,187],{},"改后",[46,189,190,201,212,223],{},[33,191,192,195,198],{},[51,193,194],{},"FCP",[51,196,197],{},"1.8s",[51,199,200],{},"0.4s",[33,202,203,206,209],{},[51,204,205],{},"LCP",[51,207,208],{},"2.3s",[51,210,211],{},"0.6s",[33,213,214,217,220],{},[51,215,216],{},"JS 体积",[51,218,219],{},"284 KB",[51,221,222],{},"41 KB",[33,224,225,228,231],{},[51,226,227],{},"首屏请求数",[51,229,230],{},"23",[51,232,233],{},"6",[10,235,236],{},"没有做任何「优化」。没有拆包、没有预加载、没有 CDN 调优。",[10,238,239],{},"我只是不再发送用户不需要的代码。",[155,241,245],{"className":242,"code":243,"language":244,"meta":163,"style":163},"language-js shiki shiki-themes github-light github-dark","\u002F\u002F 删之前：每个页面都加载完整运行时\nimport { Analytics } from '@heavy\u002Fanalytics'\nimport { Comments } from '@heavy\u002Fcomments'\nimport { AdminWidget } from '@heavy\u002Fadmin'\n\n\u002F\u002F 删之后：什么都没有\n\u002F\u002F 静态 HTML + 一个 3KB 的搜索索引（首次搜索才加载）\n","js",[144,246,247,256,274,287,300,307,313],{"__ignoreMap":163},[248,249,252],"span",{"class":250,"line":251},"line",1,[248,253,255],{"class":254},"sJ8bj","\u002F\u002F 删之前：每个页面都加载完整运行时\n",[248,257,259,263,267,270],{"class":250,"line":258},2,[248,260,262],{"class":261},"szBVR","import",[248,264,266],{"class":265},"sVt8B"," { Analytics } ",[248,268,269],{"class":261},"from",[248,271,273],{"class":272},"sZZnC"," '@heavy\u002Fanalytics'\n",[248,275,277,279,282,284],{"class":250,"line":276},3,[248,278,262],{"class":261},[248,280,281],{"class":265}," { Comments } ",[248,283,269],{"class":261},[248,285,286],{"class":272}," '@heavy\u002Fcomments'\n",[248,288,290,292,295,297],{"class":250,"line":289},4,[248,291,262],{"class":261},[248,293,294],{"class":265}," { AdminWidget } ",[248,296,269],{"class":261},[248,298,299],{"class":272}," '@heavy\u002Fadmin'\n",[248,301,303],{"class":250,"line":302},5,[248,304,306],{"emptyLinePlaceholder":305},true,"\n",[248,308,310],{"class":250,"line":309},6,[248,311,312],{"class":254},"\u002F\u002F 删之后：什么都没有\n",[248,314,316],{"class":250,"line":315},7,[248,317,318],{"class":254},"\u002F\u002F 静态 HTML + 一个 3KB 的搜索索引（首次搜索才加载）\n",[20,320,321],{"id":321},"一个反直觉的发现",[10,323,324],{},"删功能最难的从来不是技术，是心理。",[10,326,327],{},"每删一个东西，我都会想：「万一以后要用呢？」",[10,329,330,331],{},"后来我给自己定了个规则：",[109,332,333],{},"如果要重新加回来，成本低于 2 小时，那就先删掉。",[10,335,336],{},"后台管理？重写要 8 小时，不删。评论系统？接第三方要 20 分钟，删。搜索页？改成弹窗要 1 小时，删。",[10,338,339],{},"这条规则让我删掉了大约 60% 的东西，而没有任何一个功能被真的加回来过。",[20,341,342],{"id":342},"结论",[344,345,346],"blockquote",{},[10,347,348,349,352],{},"一个博客的核心是：",[109,350,351],{},"让人能读到文章。"," 其他一切都是配角。",[10,354,355,356,359,360,363],{},"我现在写一篇新文章的工作流是：新建一个 ",[144,357,358],{},".md"," 文件，写 frontmatter，写正文，",[144,361,362],{},"git push","。",[10,365,366],{},"三十秒后它就在线上了，带 RSS、带搜索索引、带 OG 图。",[10,368,369],{},"这才是写博客该有的摩擦系数。",[371,372,373],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#57606A;--shiki-dark:#9AA4B0}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":163,"searchDepth":258,"depth":258,"links":375},[376,377,378,379,380,381],{"id":22,"depth":258,"text":22},{"id":101,"depth":258,"text":101},{"id":150,"depth":258,"text":150},{"id":169,"depth":258,"text":169},{"id":321,"depth":258,"text":321},{"id":342,"depth":258,"text":342},"工程",null,"2025-10-12","一个博客需要什么？列表、文章、归档、搜索、订阅。其他东西我全删了，然后发现加载时间从 2.3 秒掉到了 380 毫秒。",false,"md",{},"\u002Fposts\u002Fdeleted-90-percent",{"title":5,"description":385},"posts\u002Fdeleted-90-percent",[393,394,395],"性能","架构","反思","NeMKOUnwxefYZfqfwMfQzEu8PuZMiF_CoLUfNkaoiqM",{"prev":398,"next":408},{"path":399,"title":400,"description":401,"date":402,"updated":383,"tags":403,"category":382,"cover":407,"draft":386,"pinned":305,"featured":386},"\u002Fposts\u002Fxml-escaping-stress-test","特殊字符与代码块压测：& \u003C > \" ' 全都要","一篇专门用来喂 RSS\u002FAtom 校验器的文章。正文里塞满了 & \u003C > 引号、CDATA 边界、嵌套代码块和原始 HTML 片段。","2025-10-20",[404,405,406],"RSS","XML","测试","\u002Fimages\u002Fcovers\u002Fcharset.png",{"path":409,"title":410,"description":411,"date":412,"updated":383,"tags":413,"category":382,"cover":383,"draft":386,"pinned":386,"featured":386},"\u002Fposts\u002Fcjk-tokenizer","中文分词为什么把搜索做坏了","MiniSearch 默认按空格切词，对中文来说等于完全失效。这篇讲 CJK 该怎么切，以及 bigram 加单字兜底为什么比单纯整词匹配更靠谱。","2025-09-30",[414,415,416],"搜索","MiniSearch","中文",[418,425,433],{"path":419,"title":420,"description":421,"date":422,"updated":383,"tags":423,"category":382,"cover":383,"draft":386,"pinned":386,"featured":386},"\u002Fposts\u002Fstatic-search","静态博客的搜索为什么不用后端","300KB 的索引、一次懒加载、纯前端查询。对一个几百篇文章的博客来说，这个方案比任何搜索引擎都合适。","2025-09-05",[414,394,424],"SSG",{"path":426,"title":427,"description":428,"date":429,"updated":383,"tags":430,"category":382,"cover":383,"draft":386,"pinned":386,"featured":386},"\u002Fposts\u002Fzero-hardcode","一个配置文件能解决多少问题","零硬编码听起来是教条，实践起来是架构约束。这篇讲我怎么用四个配置文件把全站的可变内容抽干净，以及它带来的真实收益。","2025-07-10",[394,431,432],"配置","可维护性",{"path":399,"title":400,"description":401,"date":402,"updated":383,"tags":434,"category":382,"cover":407,"draft":386,"pinned":305,"featured":386},[404,405,406],1794113901485]