JavaScriptã³ãŒãåå²ã®å æ¬çãªã¬ã€ãã§ãããé«éãªãŠã§ãã¢ããªã±ãŒã·ã§ã³ãå®çŸããŸããããææ°ãã¬ãŒã ã¯ãŒã¯åãã®åçèªã¿èŸŒã¿ãã«ãŒãããŒã¹åå²ãããã©ãŒãã³ã¹æé©åæè¡ã解説ããŸãã
JavaScriptã³ãŒãåå²ïŒåçèªã¿èŸŒã¿ãšããã©ãŒãã³ã¹æé©åã®æ·±æã
çŸä»£ã®ããžã¿ã«ç€ŸäŒã«ãããŠããŠã§ãã¢ããªã±ãŒã·ã§ã³ã®ç¬¬äžå°è±¡ã¯ããã°ãã°ãé床ããšããåäžã®ææšã«ãã£ãŠæ±ºãŸããŸããé ããåå¿ã®éããŠã§ããµã€ãã¯ããŠãŒã¶ãŒã®äžæºãé«ãçŽåž°çã«ã€ãªãããããžãã¹ç®æšã«çŽæ¥çãªæªåœ±é¿ãäžããŸããé ããŠã§ãã¢ããªã±ãŒã·ã§ã³ã®æå€§ã®åå ã®äžã€ããã¢ããªã·ãã¯ãªJavaScriptãã³ãã«ã§ããããã¯ããµã€ãå šäœã®ãã¹ãŠã®ã³ãŒããå«ãåäžã®å·šå€§ãªãã¡ã€ã«ã§ããããŠãŒã¶ãŒãããŒãžãæäœã§ããããã«ãªãåã«ãããŠã³ããŒããè§£æãå®è¡ãããªããã°ãªããŸããã
ããã§JavaScriptã®ã³ãŒãåå²ã圹ç«ã¡ãŸããããã¯åãªãæè¡ã§ã¯ãªãããŠã§ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ãé ä¿¡ããæ¹æ³ã«ãããæ ¹æ¬çãªæ§é 転æã§ãããã®å€§ããªãã³ãã«ãããªã³ããã³ãã§èªã¿èŸŒããå°ããªãã£ã³ã¯ã«åå²ããããšã§ãååèªã¿èŸŒã¿æéãåçã«æ¹åããã¯ããã«ã¹ã ãŒãºãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãçã¿åºãããšãã§ããŸãããã®ã¬ã€ãã§ã¯ãã³ãŒãåå²ã®äžçãæ·±æããããã®äžæ žãšãªãæŠå¿µãå®è·µçãªæŠç¥ããããŠããã©ãŒãã³ã¹ãžã®å€§ããªåœ±é¿ãæ¢ããŸãã
ã³ãŒãåå²ãšã¯äœãããªãæ°ã«ããã¹ããïŒ
ãã®æ žå¿ã«ãããŠãã³ãŒãåå²ãšã¯ãã¢ããªã±ãŒã·ã§ã³ã®JavaScriptã³ãŒããè€æ°ã®å°ããªãã¡ã€ã«ïŒãã°ãã°ããã£ã³ã¯ããšåŒã°ããïŒã«åå²ããåçãŸãã¯äžŠè¡ããŠèªã¿èŸŒããããã«ããææ³ã§ãããŠãŒã¶ãŒãæåã«ããŒã ããŒãžã«ã¢ã¯ã»ã¹ãããšãã«2MBã®JavaScriptãã¡ã€ã«ãéã代ããã«ããã®ããŒãžã®ã¬ã³ããªã³ã°ã«å¿ èŠãªæ¬è³ªçãª200KBã ããéãããšãã§ããŸãããŠãŒã¶ãŒãããã£ãŒã«ããŒãžã管çè ããã·ã¥ããŒããè€éãªããŒã¿å¯èŠåããŒã«ãšãã£ãæ©èœã®æ®ãã®ã³ãŒãã¯ããŠãŒã¶ãŒãå®éã«ãããã®æ©èœã«ç§»åããããæäœããããããšãã«ã®ã¿ååŸãããŸãã
ã¬ã¹ãã©ã³ã§ã®æ³šæãæ³åããŠã¿ãŠãã ãããã¢ããªã·ãã¯ãªãã³ãã«ã¯ã欲ãããã©ããã«é¢ããããè€æ°ã³ãŒã¹ã®ã¡ãã¥ãŒå šäœãäžåºŠã«æäŸããããããªãã®ã§ããã³ãŒãåå²ã¯ã¢ã©ã«ã«ãäœéšã§ããå¿ èŠãªãã®ããå¿ èŠãªãšãã«ãæ£ç¢ºã«æã«å ¥ããããšãã§ããŸãã
ã¢ããªã·ãã¯ãã³ãã«ã®åé¡ç¹
ãã®è§£æ±ºçã®äŸ¡å€ãååã«çè§£ããããã«ã¯ããŸãåé¡ãçè§£ããªããã°ãªããŸãããåäžã®å€§ããªãã³ãã«ã¯ãããã€ãã®ç¹ã§ããã©ãŒãã³ã¹ã«æªåœ±é¿ãäžããŸãã
- ãããã¯ãŒã¯é å»¶ã®å¢å€§ïŒãã¡ã€ã«ãµã€ãºã倧ããã»ã©ããŠã³ããŒãã«æéãããããŸããããã¯äžçã®å€ãã®å°åã§æ®åããŠããäœéãªã¢ãã€ã«ãããã¯ãŒã¯ã§ã¯ç¹ã«é¡èã§ãããã®åæã®åŸ ã¡æéãããã°ãã°æåã®ããã«ããã¯ãšãªããŸãã
- è§£æã»ã³ã³ãã€ã«æéã®é·æåïŒããŠã³ããŒãåŸããã©ãŠã¶ã®JavaScriptãšã³ãžã³ã¯ã³ãŒãããŒã¹å šäœãè§£æããã³ã³ãã€ã«ããªããã°ãªããŸãããããã¯CPUãéäžçã«äœ¿çšããã¿ã¹ã¯ã§ãããã¡ã€ã³ã¹ã¬ããããããã¯ããããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ã¯ããªãŒãºããç¡åå¿ãªç¶æ ãç¶ããŸãã
- ã¬ã³ããªã³ã°ã®ãããã¯ïŒã¡ã€ã³ã¹ã¬ãããJavaScriptã®åŠçã§å¿ããéãããŒãžã®ã¬ã³ããªã³ã°ããŠãŒã¶ãŒå ¥åãžã®å¿çãšãã£ãä»ã®éèŠãªã¿ã¹ã¯ãå®è¡ã§ããŸãããããã¯Time to Interactive (TTI)ã®æªåã«çŽæ¥ã€ãªãããŸãã
- ãªãœãŒã¹ã®ç¡é§é£ãïŒã¢ããªã·ãã¯ãªãã³ãã«ã«å«ãŸããã³ãŒãã®å€§éšåã¯ãå žåçãªãŠãŒã¶ãŒã»ãã·ã§ã³äžã«ã¯æ±ºããŠäœ¿çšãããªãå¯èœæ§ããããŸããããã¯ããŠãŒã¶ãŒãäœã®äŸ¡å€ããããããªãã³ãŒããããŠã³ããŒããæºåããããã«ãããŒã¿ãããããªãŒãåŠçèœåãç¡é§ã«ããŠããããšãæå³ããŸãã
- Core Web Vitalsã®æªåïŒãããã®ããã©ãŒãã³ã¹åé¡ã¯ãCore Web Vitalsã®ã¹ã³ã¢ã«çŽæ¥çãªå®³ãåãŒããæ€çŽ¢ãšã³ãžã³ã®ã©ã³ãã³ã°ã«åœ±é¿ãäžããå¯èœæ§ããããŸãããããã¯ãããã¡ã€ã³ã¹ã¬ããã¯First Input Delay (FID)ãInteraction to Next Paint (INP)ãæªåãããé å»¶ããã¬ã³ããªã³ã°ã¯Largest Contentful Paint (LCP)ã«åœ±é¿ããŸãã
çŸä»£ã®ã³ãŒãåå²ã®äžæ žïŒåç `import()`
ææ°ã®ã³ãŒãå岿Šç¥ã®ã»ãšãã©ã®èåŸã«ããéæ³ã¯ãæšæºçãªJavaScriptã®æ©èœã§ããåç `import()` åŒã§ãããã«ãæã«åŠçããã¢ãžã¥ãŒã«ãäžã€ã«ãŸãšããéç㪠`import` æãšã¯ç°ãªããåç `import()` ã¯ãªã³ããã³ãã§ã¢ãžã¥ãŒã«ãèªã¿èŸŒã颿°ã®ãããªåŒã§ãã
ä»çµã¿ã¯æ¬¡ã®ãšããã§ãã
import('/path/to/module.js')
WebpackãViteãRollupã®ãããªãã³ãã©ããã®æ§æãèŠããšã`'./path/to/module.js'` ãšãã®äŸåé¢ä¿ãå¥ã®ãã£ã³ã¯ã«é 眮ãã¹ãã ãšçè§£ããŸãã`import()` åŒã³åºãèªäœã¯Promiseãè¿ãããããã¯ãŒã¯çµç±ã§ã¢ãžã¥ãŒã«ã®ã³ã³ãã³ããæ£åžžã«èªã¿èŸŒãŸãããšããã®å 容ã§è§£æ±ºãããŸãã
å žåçãªå®è£ ã¯æ¬¡ã®ããã«ãªããŸãã
// id="load-feature"ãæã€ãã¿ã³ãæ³å®
const featureButton = document.getElementById('load-feature');
featureButton.addEventListener('click', () => {
import('./heavy-feature.js')
.then(module => {
// ã¢ãžã¥ãŒã«ã¯æ£åžžã«èªã¿èŸŒãŸããŸãã
const feature = module.default;
feature.initialize(); // èªã¿èŸŒãŸããã¢ãžã¥ãŒã«ãã颿°ãå®è¡
})
.catch(err => {
// èªã¿èŸŒã¿äžã®ãšã©ãŒãåŠç
console.error('Failed to load the feature:', err);
});
});
ãã®äŸã§ã¯ã`heavy-feature.js` ã¯æåã®ããŒãžèªã¿èŸŒã¿ã«ã¯å«ãŸããŸããããŠãŒã¶ãŒããã¿ã³ãã¯ãªãã¯ãããšãã«ã®ã¿ããµãŒããŒãããªã¯ãšã¹ããããŸãããããåçèªã¿èŸŒã¿ã®åºæ¬ååã§ãã
å®è·µçãªã³ãŒãå岿Šç¥
ãã©ã®ããã«ããç¥ãããšãäžã€ã§ããããã©ãã§ãããã€ããç¥ãããšããã³ãŒãåå²ãçã«å¹æçã«ããŸãã以äžã¯ãçŸä»£ã®ãŠã§ãéçºã§äœ¿ãããæãäžè¬çã§åŒ·åãªæŠç¥ã§ãã
1. ã«ãŒãããŒã¹ã®åå²
ããã¯ééããªãæã圱é¿åããããåºã䜿çšãããŠããæŠç¥ã§ããèãæ¹ã¯ã·ã³ãã«ã§ããã¢ããªã±ãŒã·ã§ã³ã®åããŒãžãã«ãŒãããããããç¬èªã®JavaScriptãã£ã³ã¯ãæã¡ãŸãããŠãŒã¶ãŒã`/home`ã«ã¢ã¯ã»ã¹ãããšãããŒã ããŒãžçšã®ã³ãŒãã®ã¿ãèªã¿èŸŒã¿ãŸãã`/dashboard`ã«ç§»åãããšãããã·ã¥ããŒãçšã®JavaScriptãåçã«ååŸãããŸãã
ãã®ã¢ãããŒãã¯ãŠãŒã¶ãŒã®è¡åãšå®å šã«äžèŽããŠããããã«ãããŒãžã¢ããªã±ãŒã·ã§ã³ïŒã·ã³ã°ã«ããŒãžã¢ããªã±ãŒã·ã§ã³ãSPAã§ãããïŒã«ãšã£ãŠéåžžã«å¹æçã§ããã»ãšãã©ã®ææ°ãã¬ãŒã ã¯ãŒã¯ã¯ãããã«å¯Ÿããçµã¿èŸŒã¿ãµããŒããåããŠããŸãã
Reactã§ã®äŸïŒ`React.lazy` ãš `Suspense`ïŒ
Reactã§ã¯ãã³ã³ããŒãã³ããåçã«ã€ã³ããŒãããããã®`React.lazy`ãšãã³ã³ããŒãã³ãã®ã³ãŒããèªã¿èŸŒãŸããŠããéã«ãã©ãŒã«ããã¯UIïŒããŒãã£ã³ã°ã¹ãããŒãªã©ïŒã衚瀺ããããã®`Suspense`ã䜿çšããŠãã«ãŒãããŒã¹ã®åå²ãã·ãŒã ã¬ã¹ã«è¡ããŸãã
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
// å
±é/åæã«ãŒãã®ã³ã³ããŒãã³ãã¯éçã«ã€ã³ããŒã
import HomePage from './pages/HomePage';
// ããŸãäžè¬çã§ãªãããŸãã¯éãã«ãŒãã®ã³ã³ããŒãã³ãã¯åçã«ã€ã³ããŒã
const DashboardPage = lazy(() => import('./pages/DashboardPage'));
const AdminPanel = lazy(() => import('./pages/AdminPanel'));
function App() {
return (
Loading page...
Vueã§ã®äŸïŒéåæã³ã³ããŒãã³ãïŒ
Vueã®ã«ãŒã¿ãŒã¯ãã«ãŒãå®çŸ©ã§çŽæ¥åç `import()` æ§æã䜿çšããããšã§ãã³ã³ããŒãã³ãã®é å»¶èªã¿èŸŒã¿ã第äžçŽã§ãµããŒãããŠããŸãã
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
const routes = [
{
path: '/',
name: 'Home',
component: Home // åæç¶æ
ã§èªã¿èŸŒãŸãã
},
{
path: '/about',
name: 'About',
// ã«ãŒãã¬ãã«ã®ã³ãŒãåå²
// ããã«ããããã®ã«ãŒãçšã«å¥ã®ãã£ã³ã¯ãçæããã
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
2. ã³ã³ããŒãã³ãããŒã¹ã®åå²
æã«ã¯ãåäžã®ããŒãžå ã§ãã£ãŠããããã«å¿ èŠãšãããªã倧ããªã³ã³ããŒãã³ããååšããŸãããããã¯ã³ã³ããŒãã³ãããŒã¹ã®åå²ã«æé©ãªåè£ã§ããäŸãšããŠã¯ã以äžã®ãããªãã®ããããŸãã
- ãŠãŒã¶ãŒããã¿ã³ãã¯ãªãã¯ããåŸã«è¡šç€ºãããã¢ãŒãã«ããã€ã¢ãã°ã
- ã¹ã¯ããŒã«ããªããšèŠããªãäœçœ®ã«ãããè€éãªãã£ãŒããããŒã¿å¯èŠåã
- ãŠãŒã¶ãŒããç·šéããã¯ãªãã¯ãããšãã«ã®ã¿è¡šç€ºããããªããããã¹ããšãã£ã¿ã
- ãŠãŒã¶ãŒãåçã¢ã€ã³ã³ãã¯ãªãã¯ãããŸã§èªã¿èŸŒãå¿ èŠã®ãªããããªãã¬ã€ã€ãŒã©ã€ãã©ãªã
å®è£ ã¯ã«ãŒãããŒã¹ã®åå²ãšäŒŒãŠããŸãããã«ãŒãã®å€æŽã§ã¯ãªããŠãŒã¶ãŒã®ã€ã³ã¿ã©ã¯ã·ã§ã³ã«ãã£ãŠããªã¬ãŒãããŸãã
äŸïŒã¯ãªãã¯æã«ã¢ãŒãã«ãèªã¿èŸŒã
import React, { useState, Suspense, lazy } from 'react';
// ã¢ãŒãã«ã³ã³ããŒãã³ãã¯ç¬èªã®ãã¡ã€ã«ã§å®çŸ©ãããå¥ã®ãã£ã³ã¯ã«ãªã
const HeavyModal = lazy(() => import('./components/HeavyModal'));
function MyPage() {
const [isModalOpen, setIsModalOpen] = useState(false);
const openModal = () => {
setIsModalOpen(true);
};
return (
Welcome to the Page
{isModalOpen && (
Loading modal... }>
setIsModalOpen(false)} />
)}