[{"data":1,"prerenderedAt":1671},["ShallowReactive",2],{"content-/raw-metrics-lazy-loading":3,"all-pages-for-dir":1648,"related-/raw-metrics-lazy-loading":1649,"og-image-/raw-metrics-lazy-loading":1670},{"id":4,"title":5,"body":6,"category":1633,"concepts":1633,"description":1634,"extension":1635,"meta":1636,"navigation":195,"ogImage":1633,"path":1637,"project_name":1633,"published":1638,"publishedAt":1639,"seo":1640,"source":1633,"stem":1641,"tags":1642,"todo":1633,"unpublished":1638,"updatedAt":1639,"__hash__":1647},"pages/2025-12/2025-12-18/raw-metrics-lazy-loading.md","財務データ全量表示の遅延読み込み設計",{"type":7,"value":8,"toc":1608},"minimark",[9,12,16,24,27,31,41,58,61,69,73,76,82,87,100,103,109,112,116,125,235,240,605,610,698,702,709,1271,1274,1323,1329,1332,1368,1372,1375,1459,1471,1474,1491,1494,1497,1500,1563,1566,1577,1580,1604],[10,11,5],"h1",{"id":5},[13,14,15],"h2",{"id":15},"概要",[17,18,19,23],"p",{},[20,21,22],"code",{},"proportional-animation-qqq.vue","ページの「財務データ一覧」セクションに、SQLiteに格納された全メトリクスを表示する機能を追加した際の設計について記録する。",[13,25,26],{"id":26},"背景と課題",[28,29,30],"h3",{"id":30},"現状のアーキテクチャ",[32,33,38],"pre",{"className":34,"code":36,"language":37},[35],"language-text","data/koyfin.db (SQLite)\n    ↓ [node scripts/generate-financial-data.mjs]\napp/composables/financial-data.ts (3.4MB)\n    ↓ [import]\napp/pages/financial-quiz/proportional-animation-qqq.vue\n","text",[20,39,36],{"__ignoreMap":40},"",[42,43,44,48,51],"ul",{},[45,46,47],"li",{},"チャート表示に必要なメトリクスのみを TypeScript ファイルに事前生成",[45,49,50],{},"初期ロード時にすべてのデータが読み込まれる",[45,52,53,57],{},[54,55,56],"strong",{},"問題",": DBには約100種類のメトリクスがあるが、チャートでは約30種類のみ使用",[28,59,60],{"id":60},"要件",[42,62,63,66],{},[45,64,65],{},"「財務データ一覧」で全メトリクスを表示したい",[45,67,68],{},"しかし、全メトリクスを TypeScript に含めると初期ロードが重くなる（推定 30MB+）",[13,70,72],{"id":71},"解決策-遅延読み込み-lazy-loading","解決策: 遅延読み込み (Lazy Loading)",[28,74,75],{"id":75},"アーキテクチャ",[32,77,80],{"className":78,"code":79,"language":37},[35],"data/koyfin.db (SQLite)\n    ↓ [node scripts/generate-raw-metrics.mjs]\npublic/data/raw/{TICKER}.json (50-60KB/企業)\n    ↓ [fetch() on demand]\napp/components/financial-quiz/FinancialDataTable.vue\n",[20,81,79],{"__ignoreMap":40},[17,83,84],{},[54,85,86],{},"ポイント:",[88,89,90,93],"ol",{},[45,91,92],{},"チャート用データ: 従来通り TypeScript で即時読み込み",[45,94,95,96,99],{},"全メトリクス: JSONとして ",[20,97,98],{},"public/data/raw/"," に配置し、タブクリック時に fetch",[28,101,102],{"id":102},"データフロー",[32,104,107],{"className":105,"code":106,"language":37},[35],"┌─────────────────────────────────────────────────────────────┐\n│ Initial Load                                                │\n├─────────────────────────────────────────────────────────────┤\n│  financial-data.ts (3.4MB)                                 │\n│    └─ チャート用メトリクス ~30種類                           │\n│       → BS/PL/CF図、収益チャート、バリュエーション等         │\n└─────────────────────────────────────────────────────────────┘\n                            ↓\n┌─────────────────────────────────────────────────────────────┐\n│ On \"全データ\" Tab Click                                     │\n├─────────────────────────────────────────────────────────────┤\n│  fetch(`/data/raw/${ticker}.json`)                         │\n│    └─ 全メトリクス ~100種類 (50-60KB)                       │\n│       → セクション別テーブル表示                             │\n└─────────────────────────────────────────────────────────────┘\n",[20,108,106],{"__ignoreMap":40},[13,110,111],{"id":111},"実装詳細",[28,113,115],{"id":114},"_1-データ生成スクリプト","1. データ生成スクリプト",[17,117,118,121,122],{},[54,119,120],{},"ファイル:"," ",[20,123,124],{},"scripts/generate-raw-metrics.mjs",[32,126,130],{"className":127,"code":128,"language":129,"meta":40,"style":40},"language-javascript shiki shiki-themes vitesse-light vitesse-light","// 使用方法\ncd apps/web\nnode scripts/generate-raw-metrics.mjs\n\n// 出力\npublic/data/raw/{TICKER}.json  // 101企業分\n","javascript",[20,131,132,141,158,190,197,203],{"__ignoreMap":40},[133,134,137],"span",{"class":135,"line":136},"line",1,[133,138,140],{"class":139},"sxvE3","// 使用方法\n",[133,142,144,148,151,155],{"class":135,"line":143},2,[133,145,147],{"class":146},"s4oTP","cd",[133,149,150],{"class":146}," apps",[133,152,154],{"class":153},"stQ0i","/",[133,156,157],{"class":146},"web\n",[133,159,161,164,167,169,172,175,178,180,183,187],{"class":135,"line":160},3,[133,162,163],{"class":146},"node",[133,165,166],{"class":146}," scripts",[133,168,154],{"class":153},[133,170,171],{"class":146},"generate",[133,173,174],{"class":153},"-",[133,176,177],{"class":146},"raw",[133,179,174],{"class":153},[133,181,182],{"class":146},"metrics",[133,184,186],{"class":185},"shFtX",".",[133,188,189],{"class":146},"mjs\n",[133,191,193],{"class":135,"line":192},4,[133,194,196],{"emptyLinePlaceholder":195},true,"\n",[133,198,200],{"class":135,"line":199},5,[133,201,202],{"class":139},"// 出力\n",[133,204,206,209,211,214,216,218,220,223,226,229,232],{"class":135,"line":205},6,[133,207,208],{"class":146},"public",[133,210,154],{"class":153},[133,212,213],{"class":146},"data",[133,215,154],{"class":153},[133,217,177],{"class":146},[133,219,154],{"class":153},[133,221,222],{"class":185},"{",[133,224,225],{"class":146},"TICKER",[133,227,228],{"class":185},"}.",[133,230,231],{"class":146},"json",[133,233,234],{"class":139},"  // 101企業分\n",[17,236,237],{},[54,238,239],{},"出力JSONの構造:",[32,241,244],{"className":242,"code":243,"language":231,"meta":40,"style":40},"language-json shiki shiki-themes vitesse-light vitesse-light","{\n  \"ticker\": \"NVDA\",\n  \"periods\": [\"2016\", \"2017\", ..., \"LTM\"],\n  \"sections\": [\n    {\n      \"id\": \"highlights\",\n      \"label\": \"ハイライト\",\n      \"metrics\": [\n        {\n          \"name\": \"Diluted EPS\",\n          \"values\": {\n            \"2016\": \"0.03\",\n            \"2017\": \"0.06\",\n            ...\n          }\n        }\n      ]\n    },\n    {\n      \"id\": \"income_statement\",\n      \"label\": \"損益計算書\",\n      \"metrics\": [...]\n    }\n    // ... 他のセクション\n  ]\n}\n",[20,245,246,251,280,329,343,348,369,390,403,409,431,446,467,487,493,499,505,511,517,522,542,562,581,587,593,599],{"__ignoreMap":40},[133,247,248],{"class":135,"line":136},[133,249,250],{"class":185},"{\n",[133,252,253,257,261,264,267,271,275,277],{"class":135,"line":143},[133,254,256],{"class":255},"sqvqQ","  \"",[133,258,260],{"class":259},"sz8Xr","ticker",[133,262,263],{"class":255},"\"",[133,265,266],{"class":185},":",[133,268,270],{"class":269},"sMJiu"," \"",[133,272,274],{"class":273},"sdGka","NVDA",[133,276,263],{"class":269},[133,278,279],{"class":185},",\n",[133,281,282,284,287,289,291,294,296,299,301,304,306,309,311,313,317,319,321,324,326],{"class":135,"line":160},[133,283,256],{"class":255},[133,285,286],{"class":259},"periods",[133,288,263],{"class":255},[133,290,266],{"class":185},[133,292,293],{"class":185}," [",[133,295,263],{"class":269},[133,297,298],{"class":273},"2016",[133,300,263],{"class":269},[133,302,303],{"class":185},",",[133,305,270],{"class":269},[133,307,308],{"class":273},"2017",[133,310,263],{"class":269},[133,312,303],{"class":185},[133,314,316],{"class":315},"sPP4b"," ...",[133,318,303],{"class":185},[133,320,270],{"class":269},[133,322,323],{"class":273},"LTM",[133,325,263],{"class":269},[133,327,328],{"class":185},"],\n",[133,330,331,333,336,338,340],{"class":135,"line":192},[133,332,256],{"class":255},[133,334,335],{"class":259},"sections",[133,337,263],{"class":255},[133,339,266],{"class":185},[133,341,342],{"class":185}," [\n",[133,344,345],{"class":135,"line":199},[133,346,347],{"class":185},"    {\n",[133,349,350,353,356,358,360,362,365,367],{"class":135,"line":205},[133,351,352],{"class":255},"      \"",[133,354,355],{"class":259},"id",[133,357,263],{"class":255},[133,359,266],{"class":185},[133,361,270],{"class":269},[133,363,364],{"class":273},"highlights",[133,366,263],{"class":269},[133,368,279],{"class":185},[133,370,372,374,377,379,381,383,386,388],{"class":135,"line":371},7,[133,373,352],{"class":255},[133,375,376],{"class":259},"label",[133,378,263],{"class":255},[133,380,266],{"class":185},[133,382,270],{"class":269},[133,384,385],{"class":273},"ハイライト",[133,387,263],{"class":269},[133,389,279],{"class":185},[133,391,393,395,397,399,401],{"class":135,"line":392},8,[133,394,352],{"class":255},[133,396,182],{"class":259},[133,398,263],{"class":255},[133,400,266],{"class":185},[133,402,342],{"class":185},[133,404,406],{"class":135,"line":405},9,[133,407,408],{"class":185},"        {\n",[133,410,412,415,418,420,422,424,427,429],{"class":135,"line":411},10,[133,413,414],{"class":255},"          \"",[133,416,417],{"class":259},"name",[133,419,263],{"class":255},[133,421,266],{"class":185},[133,423,270],{"class":269},[133,425,426],{"class":273},"Diluted EPS",[133,428,263],{"class":269},[133,430,279],{"class":185},[133,432,434,436,439,441,443],{"class":135,"line":433},11,[133,435,414],{"class":255},[133,437,438],{"class":259},"values",[133,440,263],{"class":255},[133,442,266],{"class":185},[133,444,445],{"class":185}," {\n",[133,447,449,452,454,456,458,460,463,465],{"class":135,"line":448},12,[133,450,451],{"class":255},"            \"",[133,453,298],{"class":259},[133,455,263],{"class":255},[133,457,266],{"class":185},[133,459,270],{"class":269},[133,461,462],{"class":273},"0.03",[133,464,263],{"class":269},[133,466,279],{"class":185},[133,468,470,472,474,476,478,480,483,485],{"class":135,"line":469},13,[133,471,451],{"class":255},[133,473,308],{"class":259},[133,475,263],{"class":255},[133,477,266],{"class":185},[133,479,270],{"class":269},[133,481,482],{"class":273},"0.06",[133,484,263],{"class":269},[133,486,279],{"class":185},[133,488,490],{"class":135,"line":489},14,[133,491,492],{"class":315},"            ...\n",[133,494,496],{"class":135,"line":495},15,[133,497,498],{"class":185},"          }\n",[133,500,502],{"class":135,"line":501},16,[133,503,504],{"class":185},"        }\n",[133,506,508],{"class":135,"line":507},17,[133,509,510],{"class":185},"      ]\n",[133,512,514],{"class":135,"line":513},18,[133,515,516],{"class":185},"    },\n",[133,518,520],{"class":135,"line":519},19,[133,521,347],{"class":185},[133,523,525,527,529,531,533,535,538,540],{"class":135,"line":524},20,[133,526,352],{"class":255},[133,528,355],{"class":259},[133,530,263],{"class":255},[133,532,266],{"class":185},[133,534,270],{"class":269},[133,536,537],{"class":273},"income_statement",[133,539,263],{"class":269},[133,541,279],{"class":185},[133,543,545,547,549,551,553,555,558,560],{"class":135,"line":544},21,[133,546,352],{"class":255},[133,548,376],{"class":259},[133,550,263],{"class":255},[133,552,266],{"class":185},[133,554,270],{"class":269},[133,556,557],{"class":273},"損益計算書",[133,559,263],{"class":269},[133,561,279],{"class":185},[133,563,565,567,569,571,573,575,578],{"class":135,"line":564},22,[133,566,352],{"class":255},[133,568,182],{"class":259},[133,570,263],{"class":255},[133,572,266],{"class":185},[133,574,293],{"class":185},[133,576,577],{"class":315},"...",[133,579,580],{"class":185},"]\n",[133,582,584],{"class":135,"line":583},23,[133,585,586],{"class":185},"    }\n",[133,588,590],{"class":135,"line":589},24,[133,591,592],{"class":139},"    // ... 他のセクション\n",[133,594,596],{"class":135,"line":595},25,[133,597,598],{"class":185},"  ]\n",[133,600,602],{"class":135,"line":601},26,[133,603,604],{"class":185},"}\n",[17,606,607],{},[54,608,609],{},"セクション一覧:",[611,612,613,626],"table",{},[614,615,616],"thead",{},[617,618,619,623],"tr",{},[620,621,622],"th",{},"ID",[620,624,625],{},"日本語名",[627,628,629,636,642,650,658,666,674,682,690],"tbody",{},[617,630,631,634],{},[632,633,364],"td",{},[632,635,385],{},[617,637,638,640],{},[632,639,537],{},[632,641,557],{},[617,643,644,647],{},[632,645,646],{},"balance_sheet",[632,648,649],{},"貸借対照表",[617,651,652,655],{},[632,653,654],{},"cash_flow",[632,656,657],{},"キャッシュフロー計算書",[617,659,660,663],{},[632,661,662],{},"profitability",[632,664,665],{},"収益性指標",[617,667,668,671],{},[632,669,670],{},"multiples",[632,672,673],{},"マルチプル（株価倍率）",[617,675,676,679],{},[632,677,678],{},"enterprise_value",[632,680,681],{},"企業価値",[617,683,684,687],{},[632,685,686],{},"solvency",[632,688,689],{},"安全性指標",[617,691,692,695],{},[632,693,694],{},"roic",[632,696,697],{},"ROIC関連",[28,699,701],{"id":700},"_2-コンポーネント実装","2. コンポーネント実装",[17,703,704,121,706],{},[54,705,120],{},[20,707,708],{},"components/financial-quiz/FinancialDataTable.vue",[32,710,714],{"className":711,"code":712,"language":713,"meta":40,"style":40},"language-vue shiki shiki-themes vitesse-light vitesse-light","\u003Cscript setup lang=\"ts\">\n// タブ状態\nconst activeTab = ref\u003C'summary' | 'raw'>('summary')\n\n// rawデータの状態\nconst rawData = ref\u003CRawData | null>(null)\nconst isLoading = ref(false)\nconst loadedTicker = ref\u003Cstring | null>(null)\n\n// 「全データ」タブクリック時に読み込み\nasync function loadRawData() {\n  activeTab.value = 'raw'\n\n  // キャッシュチェック: 同じtickerなら再読み込みしない\n  if (loadedTicker.value === props.company.ticker && rawData.value) {\n    return\n  }\n\n  isLoading.value = true\n  try {\n    const response = await fetch(`/data/raw/${props.company.ticker}.json`)\n    rawData.value = await response.json()\n    loadedTicker.value = props.company.ticker\n  } catch (e) {\n    loadError.value = `データの読み込みに失敗しました`\n  } finally {\n    isLoading.value = false\n  }\n}\n\n// 企業切り替え時: rawタブなら自動再読み込み\nwatch(() => props.company.ticker, () => {\n  if (activeTab.value === 'raw') {\n    loadRawData()\n  }\n})\n\u003C/script>\n","vue",[20,715,716,744,749,796,800,805,834,853,879,883,888,904,923,927,932,976,981,986,990,1004,1011,1059,1082,1104,1121,1141,1150,1165,1170,1175,1180,1186,1217,1242,1250,1255,1261],{"__ignoreMap":40},[133,717,718,721,725,728,731,734,736,739,741],{"class":135,"line":136},[133,719,720],{"class":185},"\u003C",[133,722,724],{"class":723},"sHkkW","script",[133,726,727],{"class":146}," setup",[133,729,730],{"class":146}," lang",[133,732,733],{"class":185},"=",[133,735,263],{"class":269},[133,737,738],{"class":273},"ts",[133,740,263],{"class":269},[133,742,743],{"class":185},">\n",[133,745,746],{"class":135,"line":143},[133,747,748],{"class":139},"// タブ状態\n",[133,750,751,754,757,760,764,766,769,772,774,777,780,782,784,787,789,791,793],{"class":135,"line":160},[133,752,753],{"class":153},"const ",[133,755,756],{"class":146},"activeTab",[133,758,759],{"class":185}," =",[133,761,763],{"class":762},"senZ8"," ref",[133,765,720],{"class":185},[133,767,768],{"class":269},"'",[133,770,771],{"class":273},"summary",[133,773,768],{"class":269},[133,775,776],{"class":185}," |",[133,778,779],{"class":269}," '",[133,781,177],{"class":273},[133,783,768],{"class":269},[133,785,786],{"class":185},">(",[133,788,768],{"class":269},[133,790,771],{"class":273},[133,792,768],{"class":269},[133,794,795],{"class":185},")\n",[133,797,798],{"class":135,"line":192},[133,799,196],{"emptyLinePlaceholder":195},[133,801,802],{"class":135,"line":199},[133,803,804],{"class":139},"// rawデータの状態\n",[133,806,807,809,812,814,816,818,822,824,827,829,832],{"class":135,"line":205},[133,808,753],{"class":153},[133,810,811],{"class":146},"rawData",[133,813,759],{"class":185},[133,815,763],{"class":762},[133,817,720],{"class":185},[133,819,821],{"class":820},"sSkh3","RawData",[133,823,776],{"class":185},[133,825,826],{"class":153}," null",[133,828,786],{"class":185},[133,830,831],{"class":153},"null",[133,833,795],{"class":185},[133,835,836,838,841,843,845,848,851],{"class":135,"line":371},[133,837,753],{"class":153},[133,839,840],{"class":146},"isLoading",[133,842,759],{"class":185},[133,844,763],{"class":762},[133,846,847],{"class":185},"(",[133,849,850],{"class":723},"false",[133,852,795],{"class":185},[133,854,855,857,860,862,864,866,869,871,873,875,877],{"class":135,"line":392},[133,856,753],{"class":153},[133,858,859],{"class":146},"loadedTicker",[133,861,759],{"class":185},[133,863,763],{"class":762},[133,865,720],{"class":185},[133,867,868],{"class":820},"string",[133,870,776],{"class":185},[133,872,826],{"class":153},[133,874,786],{"class":185},[133,876,831],{"class":153},[133,878,795],{"class":185},[133,880,881],{"class":135,"line":405},[133,882,196],{"emptyLinePlaceholder":195},[133,884,885],{"class":135,"line":411},[133,886,887],{"class":139},"// 「全データ」タブクリック時に読み込み\n",[133,889,890,893,896,899,902],{"class":135,"line":433},[133,891,892],{"class":153},"async",[133,894,895],{"class":153}," function",[133,897,898],{"class":762}," loadRawData",[133,900,901],{"class":185},"()",[133,903,445],{"class":185},[133,905,906,909,911,914,916,918,920],{"class":135,"line":448},[133,907,908],{"class":146},"  activeTab",[133,910,186],{"class":185},[133,912,913],{"class":146},"value",[133,915,759],{"class":185},[133,917,779],{"class":269},[133,919,177],{"class":273},[133,921,922],{"class":269},"'\n",[133,924,925],{"class":135,"line":469},[133,926,196],{"emptyLinePlaceholder":195},[133,928,929],{"class":135,"line":489},[133,930,931],{"class":139},"  // キャッシュチェック: 同じtickerなら再読み込みしない\n",[133,933,934,937,940,942,944,946,949,952,954,957,959,961,964,967,969,971,974],{"class":135,"line":495},[133,935,936],{"class":723},"  if",[133,938,939],{"class":185}," (",[133,941,859],{"class":146},[133,943,186],{"class":185},[133,945,913],{"class":146},[133,947,948],{"class":153}," ===",[133,950,951],{"class":146}," props",[133,953,186],{"class":185},[133,955,956],{"class":146},"company",[133,958,186],{"class":185},[133,960,260],{"class":146},[133,962,963],{"class":153}," &&",[133,965,966],{"class":146}," rawData",[133,968,186],{"class":185},[133,970,913],{"class":146},[133,972,973],{"class":185},")",[133,975,445],{"class":185},[133,977,978],{"class":135,"line":501},[133,979,980],{"class":723},"    return\n",[133,982,983],{"class":135,"line":507},[133,984,985],{"class":185},"  }\n",[133,987,988],{"class":135,"line":513},[133,989,196],{"emptyLinePlaceholder":195},[133,991,992,995,997,999,1001],{"class":135,"line":519},[133,993,994],{"class":146},"  isLoading",[133,996,186],{"class":185},[133,998,913],{"class":146},[133,1000,759],{"class":185},[133,1002,1003],{"class":723}," true\n",[133,1005,1006,1009],{"class":135,"line":524},[133,1007,1008],{"class":723},"  try",[133,1010,445],{"class":185},[133,1012,1013,1016,1019,1021,1024,1027,1029,1032,1035,1038,1041,1043,1045,1047,1049,1052,1055,1057],{"class":135,"line":544},[133,1014,1015],{"class":153},"    const ",[133,1017,1018],{"class":146},"response",[133,1020,759],{"class":185},[133,1022,1023],{"class":723}," await",[133,1025,1026],{"class":762}," fetch",[133,1028,847],{"class":185},[133,1030,1031],{"class":269},"`",[133,1033,1034],{"class":273},"/data/raw/",[133,1036,1037],{"class":723},"${",[133,1039,1040],{"class":273},"props",[133,1042,186],{"class":185},[133,1044,956],{"class":273},[133,1046,186],{"class":185},[133,1048,260],{"class":273},[133,1050,1051],{"class":723},"}",[133,1053,1054],{"class":273},".json",[133,1056,1031],{"class":269},[133,1058,795],{"class":185},[133,1060,1061,1064,1066,1068,1070,1072,1075,1077,1079],{"class":135,"line":564},[133,1062,1063],{"class":146},"    rawData",[133,1065,186],{"class":185},[133,1067,913],{"class":146},[133,1069,759],{"class":185},[133,1071,1023],{"class":723},[133,1073,1074],{"class":146}," response",[133,1076,186],{"class":185},[133,1078,231],{"class":762},[133,1080,1081],{"class":185},"()\n",[133,1083,1084,1087,1089,1091,1093,1095,1097,1099,1101],{"class":135,"line":583},[133,1085,1086],{"class":146},"    loadedTicker",[133,1088,186],{"class":185},[133,1090,913],{"class":146},[133,1092,759],{"class":185},[133,1094,951],{"class":146},[133,1096,186],{"class":185},[133,1098,956],{"class":146},[133,1100,186],{"class":185},[133,1102,1103],{"class":146},"ticker\n",[133,1105,1106,1109,1112,1114,1117,1119],{"class":135,"line":589},[133,1107,1108],{"class":185},"  }",[133,1110,1111],{"class":723}," catch",[133,1113,939],{"class":185},[133,1115,1116],{"class":146},"e",[133,1118,973],{"class":185},[133,1120,445],{"class":185},[133,1122,1123,1126,1128,1130,1132,1135,1138],{"class":135,"line":595},[133,1124,1125],{"class":146},"    loadError",[133,1127,186],{"class":185},[133,1129,913],{"class":146},[133,1131,759],{"class":185},[133,1133,1134],{"class":269}," `",[133,1136,1137],{"class":273},"データの読み込みに失敗しました",[133,1139,1140],{"class":269},"`\n",[133,1142,1143,1145,1148],{"class":135,"line":601},[133,1144,1108],{"class":185},[133,1146,1147],{"class":723}," finally",[133,1149,445],{"class":185},[133,1151,1153,1156,1158,1160,1162],{"class":135,"line":1152},27,[133,1154,1155],{"class":146},"    isLoading",[133,1157,186],{"class":185},[133,1159,913],{"class":146},[133,1161,759],{"class":185},[133,1163,1164],{"class":723}," false\n",[133,1166,1168],{"class":135,"line":1167},28,[133,1169,985],{"class":185},[133,1171,1173],{"class":135,"line":1172},29,[133,1174,604],{"class":185},[133,1176,1178],{"class":135,"line":1177},30,[133,1179,196],{"emptyLinePlaceholder":195},[133,1181,1183],{"class":135,"line":1182},31,[133,1184,1185],{"class":139},"// 企業切り替え時: rawタブなら自動再読み込み\n",[133,1187,1189,1192,1195,1198,1200,1202,1204,1206,1208,1210,1213,1215],{"class":135,"line":1188},32,[133,1190,1191],{"class":762},"watch",[133,1193,1194],{"class":185},"(()",[133,1196,1197],{"class":185}," =>",[133,1199,951],{"class":146},[133,1201,186],{"class":185},[133,1203,956],{"class":146},[133,1205,186],{"class":185},[133,1207,260],{"class":146},[133,1209,303],{"class":185},[133,1211,1212],{"class":185}," ()",[133,1214,1197],{"class":185},[133,1216,445],{"class":185},[133,1218,1220,1222,1224,1226,1228,1230,1232,1234,1236,1238,1240],{"class":135,"line":1219},33,[133,1221,936],{"class":723},[133,1223,939],{"class":185},[133,1225,756],{"class":146},[133,1227,186],{"class":185},[133,1229,913],{"class":146},[133,1231,948],{"class":153},[133,1233,779],{"class":269},[133,1235,177],{"class":273},[133,1237,768],{"class":269},[133,1239,973],{"class":185},[133,1241,445],{"class":185},[133,1243,1245,1248],{"class":135,"line":1244},34,[133,1246,1247],{"class":762},"    loadRawData",[133,1249,1081],{"class":185},[133,1251,1253],{"class":135,"line":1252},35,[133,1254,985],{"class":185},[133,1256,1258],{"class":135,"line":1257},36,[133,1259,1260],{"class":185},"})\n",[133,1262,1264,1267,1269],{"class":135,"line":1263},37,[133,1265,1266],{"class":185},"\u003C/",[133,1268,724],{"class":723},[133,1270,743],{"class":185},[13,1272,1273],{"id":1273},"ファイルサイズ比較",[611,1275,1276,1289],{},[614,1277,1278],{},[617,1279,1280,1283,1286],{},[620,1281,1282],{},"ファイル",[620,1284,1285],{},"サイズ",[620,1287,1288],{},"読み込みタイミング",[627,1290,1291,1302,1313],{},[617,1292,1293,1296,1299],{},[632,1294,1295],{},"financial-data.ts",[632,1297,1298],{},"3.4MB",[632,1300,1301],{},"初期ロード",[617,1303,1304,1307,1310],{},[632,1305,1306],{},"raw/{TICKER}.json",[632,1308,1309],{},"50-60KB",[632,1311,1312],{},"タブクリック時",[617,1314,1315,1318,1321],{},[632,1316,1317],{},"全rawファイル合計",[632,1319,1320],{},"5.4MB",[632,1322,174],{},[17,1324,1325,1328],{},[54,1326,1327],{},"効果:"," 初期ロードサイズを増やさずに全メトリクス表示を実現",[13,1330,1331],{"id":1331},"設計のメリット",[88,1333,1334,1340,1346,1352,1362],{},[45,1335,1336,1339],{},[54,1337,1338],{},"初期ロード維持",": チャート表示に必要なデータのみ初期読み込み",[45,1341,1342,1345],{},[54,1343,1344],{},"オンデマンド読み込み",": 全データが必要な場合のみ追加fetch",[45,1347,1348,1351],{},[54,1349,1350],{},"キャッシュ効率",": 同一企業の再読み込みを防止",[45,1353,1354,1357,1358,1361],{},[54,1355,1356],{},"CDN対応",": ",[20,1359,1360],{},"public/"," 配下の静的JSONはCDNキャッシュ可能",[45,1363,1364,1367],{},[54,1365,1366],{},"デプロイ簡素化",": JSONは静的ファイルとしてビルドに含まれる",[13,1369,1371],{"id":1370},"cloudflare-pages-の容量制限","Cloudflare Pages の容量制限",[17,1373,1374],{},"無料枠での制限と現在の使用状況:",[611,1376,1377,1393],{},[614,1378,1379],{},[617,1380,1381,1384,1387,1390],{},[620,1382,1383],{},"制限項目",[620,1385,1386],{},"上限",[620,1388,1389],{},"現在の使用状況",[620,1391,1392],{},"余裕",[627,1394,1395,1409,1422,1435,1447],{},[617,1396,1397,1400,1403,1406],{},[632,1398,1399],{},"1ファイルあたり",[632,1401,1402],{},"25 MB",[632,1404,1405],{},"50-60 KB",[632,1407,1408],{},"十分",[617,1410,1411,1414,1417,1420],{},[632,1412,1413],{},"ファイル数",[632,1415,1416],{},"20,000 ファイル",[632,1418,1419],{},"101 ファイル",[632,1421,1408],{},[617,1423,1424,1427,1430,1433],{},[632,1425,1426],{},"総デプロイサイズ",[632,1428,1429],{},"1 GB",[632,1431,1432],{},"約 5.4 MB",[632,1434,1408],{},[617,1436,1437,1440,1443,1445],{},[632,1438,1439],{},"月間デプロイ回数",[632,1441,1442],{},"500 回",[632,1444,174],{},[632,1446,174],{},[617,1448,1449,1452,1455,1457],{},[632,1450,1451],{},"帯域幅",[632,1453,1454],{},"無制限",[632,1456,174],{},[632,1458,174],{},[17,1460,1461,121,1464],{},[54,1462,1463],{},"参考:",[1465,1466,1470],"a",{"href":1467,"rel":1468},"https://developers.cloudflare.com/pages/platform/limits/",[1469],"nofollow","Cloudflare Pages Limits",[28,1472,1473],{"id":1473},"将来的なスケーリング",[42,1475,1476,1479,1482],{},[45,1477,1478],{},"1000企業に増えても約 60MB（1GB上限には余裕）",[45,1480,1481],{},"ファイル数も 20,000 の上限に対して余裕",[45,1483,1484,1485,1490],{},"25MBを超える大きなファイルが必要な場合は ",[1465,1486,1489],{"href":1487,"rel":1488},"https://developers.cloudflare.com/r2/",[1469],"Cloudflare R2"," を検討",[13,1492,1493],{"id":1493},"注意事項",[28,1495,1496],{"id":1496},"データ更新時の手順",[17,1498,1499],{},"SQLiteデータが更新された場合:",[32,1501,1505],{"className":1502,"code":1503,"language":1504,"meta":40,"style":40},"language-bash shiki shiki-themes vitesse-light vitesse-light","cd apps/web\n\n# 1. チャート用データを再生成\nnode scripts/generate-financial-data.mjs\n\n# 2. 全メトリクスJSONを再生成\nnode scripts/generate-raw-metrics.mjs\n\n# 3. ビルド＆デプロイ\npnpm build\n","bash",[20,1506,1507,1514,1518,1523,1530,1534,1539,1546,1550,1555],{"__ignoreMap":40},[133,1508,1509,1511],{"class":135,"line":136},[133,1510,147],{"class":259},[133,1512,1513],{"class":273}," apps/web\n",[133,1515,1516],{"class":135,"line":143},[133,1517,196],{"emptyLinePlaceholder":195},[133,1519,1520],{"class":135,"line":160},[133,1521,1522],{"class":139},"# 1. チャート用データを再生成\n",[133,1524,1525,1527],{"class":135,"line":192},[133,1526,163],{"class":762},[133,1528,1529],{"class":273}," scripts/generate-financial-data.mjs\n",[133,1531,1532],{"class":135,"line":199},[133,1533,196],{"emptyLinePlaceholder":195},[133,1535,1536],{"class":135,"line":205},[133,1537,1538],{"class":139},"# 2. 全メトリクスJSONを再生成\n",[133,1540,1541,1543],{"class":135,"line":371},[133,1542,163],{"class":762},[133,1544,1545],{"class":273}," scripts/generate-raw-metrics.mjs\n",[133,1547,1548],{"class":135,"line":392},[133,1549,196],{"emptyLinePlaceholder":195},[133,1551,1552],{"class":135,"line":405},[133,1553,1554],{"class":139},"# 3. ビルド＆デプロイ\n",[133,1556,1557,1560],{"class":135,"line":411},[133,1558,1559],{"class":762},"pnpm",[133,1561,1562],{"class":273}," build\n",[28,1564,1565],{"id":1565},"スクリプトの制限事項",[42,1567,1568,1574],{},[45,1569,1570,1573],{},[20,1571,1572],{},"generate-raw-metrics.mjs"," は年次データ (Annual) と LTM のみ出力",[45,1575,1576],{},"四半期データは含まれない（必要であれば別途対応）",[13,1578,1579],{"id":1579},"関連ファイル",[42,1581,1582,1587,1592,1598],{},[45,1583,1584,1586],{},[20,1585,124],{}," - JSON生成スクリプト",[45,1588,1589,1591],{},[20,1590,708],{}," - 表示コンポーネント",[45,1593,1594,1597],{},[20,1595,1596],{},"pages/financial-quiz/proportional-animation-qqq.vue"," - 親ページ",[45,1599,1600,1603],{},[20,1601,1602],{},"composables/financial-data.ts"," - チャート用データ",[1605,1606,1607],"style",{},"html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}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);}html pre.shiki code .sqvqQ, html code.shiki .sqvqQ{--shiki-default:#99841877;--shiki-dark:#99841877}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .sPP4b, html code.shiki .sPP4b{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#B31D28;--shiki-dark-font-style:italic}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sSkh3, html code.shiki .sSkh3{--shiki-default:#2E8F82;--shiki-dark:#2E8F82}",{"title":40,"searchDepth":143,"depth":143,"links":1609},[1610,1611,1615,1619,1623,1624,1625,1628,1632],{"id":15,"depth":143,"text":15},{"id":26,"depth":143,"text":26,"children":1612},[1613,1614],{"id":30,"depth":160,"text":30},{"id":60,"depth":160,"text":60},{"id":71,"depth":143,"text":72,"children":1616},[1617,1618],{"id":75,"depth":160,"text":75},{"id":102,"depth":160,"text":102},{"id":111,"depth":143,"text":111,"children":1620},[1621,1622],{"id":114,"depth":160,"text":115},{"id":700,"depth":160,"text":701},{"id":1273,"depth":143,"text":1273},{"id":1331,"depth":143,"text":1331},{"id":1370,"depth":143,"text":1371,"children":1626},[1627],{"id":1473,"depth":160,"text":1473},{"id":1493,"depth":143,"text":1493,"children":1629},[1630,1631],{"id":1496,"depth":160,"text":1496},{"id":1565,"depth":160,"text":1565},{"id":1579,"depth":143,"text":1579},null,"SQLiteから生成したJSON APIによる財務データテーブルの遅延読み込み実装","md",{},"/raw-metrics-lazy-loading",false,"2025-12-18T00:00:00.000Z",{"title":5,"description":1634},"2025-12/2025-12-18/raw-metrics-lazy-loading",[1643,1644,1645,1646],"architecture","performance","lazy-loading","nuxt","i9IXhTaF4guVwa9aCuLP5wQZSnau7-MwP1lpcw5Ujek",[],[1650,1654,1658,1662,1666],{"title":1651,"path":1652,"publishedAt":1653},"検索ページ（/search）パフォーマンス改善計画","/search-page-performance-plan","2026-01-29T00:00:00.000Z",{"title":1655,"path":1656,"publishedAt":1657},"Nuxt 4 + @nuxt/content の開発サーバー起動が遅い原因と対策","/nuxt-dev-startup-time","2026-01-10T00:00:00.000Z",{"title":1659,"path":1660,"publishedAt":1661},"Nuxtビルド最適化：341ページを137秒でSSG","/nuxt-devtools-optimization","2026-01-02T00:00:00.000Z",{"title":1663,"path":1664,"publishedAt":1665},"SSGスケーラビリティ課題 - 長期運用における考慮事項","/ssg-scalability-challenges","2026-01-01T00:00:00.000Z",{"title":1667,"path":1668,"publishedAt":1669},"Nuxt 3のapp/dataとpublicディレクトリの使い分け","/nuxt-data-directory-guide","2025-12-24T00:00:00.000Z","https://log.eurekapu.com/og/blog/raw-metrics-lazy-loading.png?v=2025-12-18T00%3A00%3A00.000Z&title=%E8%B2%A1%E5%8B%99%E3%83%87%E3%83%BC%E3%82%BF%E5%85%A8%E9%87%8F%E8%A1%A8%E7%A4%BA%E3%81%AE%E9%81%85%E5%BB%B6%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E8%A8%AD%E8%A8%88&author=Kei%20Komatsu&sig=aabd91cf2f550663",1785654973530]