from the Core
Почему начать с Nuxt быстрее чем vue-ssr?
Nuxt - готовое решение из коробки, включающее в себя vue-ssr
vue-ssr - низкоуровневая библиотека для ssr рендеринга
В Nuxt интегрированы наиболее используемые vue библиотеки
Библиотеки для сборки
ОПРЕДЕЛЕННАЯ СТРУКТУРА ПРОЕКТА
Улучшенная функциональность компонентов
Модули
Для Nuxt имеется множество готовых модулей:
Поддержка Typescript
@nuxt/typescript-runtime - поддержка typescript для nuxt.config, локальных модулей и server-middleware
@nuxt/types - типы для всех классов nuxt
router.js
import user from '....'
import cart from '....'
import favorites from '....'
import Vuex from 'vuex'
const createStore = () => {
return new Vuex.Store({
namespaced: true,
state: () => ({
query: ''
}),
mutations: {
updateQuery(state, query) {
state.query = query;
}
},
modules: {
user,
cart,
favorites,
},
actions: {
async newSearch({dispatch, commit}, data) {
//...
},
async populateQuery({dispatch, commit}, query) {
//...
}
},
getters: {
getQuery: state => state.query,
getLoading: state => state.isLoading
},
})
};
классический vuex store
export const state = () => ({/**/})
export const mutations = {/**/}
export const actions = {/**/}
export const getters = {/**/}
export default {
setName(state, name){
state.name = name
},
// и другие мутации
}
Developer Experience
Улучшенные логи с consola
Логи с SSR в консоли браузера
Прогресс бар при hot reload проекта
Экран загрузки при билде проекта
render: {
compressor: false
}
Экспериментальное отключение функционала
features: {
router: true,
store: true,
layouts: true,
meta: true,
middleware: true,
transitions: true,
deprecations: true,
validate: true,
asyncData: true,
fetch: true,
clientOnline: true,
clientPrefetch: true,
clientUseUrl: false,
componentAliases: true,
componentClientOnly: true
}
Отключение неиспользуемых функций
Все включено
Минимально необходимый набор
Экспериментальное отключение функционала
autocannon -d 60 http://localhost:3000
Running 60s test @ http://localhost:3000
10 connections
Stat 2.5% 50% 97.5% 99% Avg Stdev Max
Latency 4 ms 4 ms 8 ms 10 ms 4.67 ms 1.42 ms 19.37 ms
Stat 1% 2.5% 50% 97.5% Avg Stdev Min
Req/Sec 1655 1764 1951 2038 1931.57 78.95 1655
Bytes/Sec 5.88 MB 6.27 MB 6.93 MB 7.24 MB 6.86 MB 280 kB 5.88 MB
Req/Bytes counts sampled once per second.
116k requests in 60.08s, 412 MB read
autocannon -d 60 http://localhost:3000
Running 60s test @ http://localhost:3000
10 connections
Stat 2.5% 50% 97.5% 99% Avg Stdev Max
Latency 8 ms 9 ms 16 ms 18 ms 10.12 ms 2.25 ms 30.38 ms
Stat 1% 2.5% 50% 97.5% Avg Stdev Min
Req/Sec 784 805 951 1046 942.29 57.03 784
Bytes/Sec 3.68 MB 3.78 MB 4.47 MB 4.91 MB 4.42 MB 268 kB 3.68 MB
Req/Bytes counts sampled once per second.
57k requests in 60.09s, 265 MB read
Все включено
Минимально необходимый набор
2X разница в производительности
Оптимизация кода
<template>
<div>
<SyncComponent />
<AsyncComponent />
</div>
</template>
<script>
import AsyncComponent from '~/components/AsyncComponent.vue'
import SyncComponent from '~/components/SyncComponent.vue'
export default {
components: {
SyncComponent,
AsyncComponent: () => import('~/components/AsyncComponent.vue')
}
}
</script>
Vue-lazy-hydration
<!-- по списку событий-->
<LazyHydrate on-interaction="['fullscreen', 'mousedown']">
...
</LazyHydrate>
<!-- По видимости -->
<LazyHydrate when-visible>
...
</LazyHydrate>
<!-- когда процессор не занят -->
<LazyHydrate when-idle>
....
</LazyHydrate>
<!-- только на сервере -->
<LazyHydrate ssr-only>
...
</LazyHydrate>
<!-- контролируемая гидрация -->
<LazyHydrate ssr-only :trigger-hydration="isItReady">
<ArticleContent :content="article.content"/>
</LazyHydrate>
<script>
import LazyHydrate from 'vue-lazy-hydration';
export default {
components: {
LazyHydrate,
// The `ArticleContent` будет импортирован только если isItReady true
ArticleContent: () => import('./ArticleContent.vue'),
},
// ...
};
</script>
yarn add vue-lazy-hydration
<template>
<div class="ArticlePage">
<ImageSlider/>
<ArticleContent :content="article.content"/>
<AdSlider/>
<CommentForm :article-id="article.id"/>
</div>
</template>
<script>
import {
hydrateOnInteraction,
hydrateSsrOnly,
hydrateWhenIdle,
hydrateWhenVisible,
} from 'vue-lazy-hydration';
export default {
components: {
AdSlider: hydrateWhenVisible(
() => import('./AdSlider.vue'),
// Optional.
{ observerOptions: { rootMargin: '100px' } },
),
ArticleContent: hydrateSsrOnly(
() => import('./ArticleContent.vue'),
{ ignoredProps: ['content'] },
),
CommentForm: hydrateOnInteraction(
() => import('./CommentForm.vue'),
// `focus` is the default event.
{ event: 'focus', ignoredProps: ['articleId'] },
),
ImageSlider: hydrateWhenIdle(() => import('./ImageSlider.vue')),
},
// ...
};
</script>
Врапперы импортов
Vue-lazy-hydration
После
До
Vue-lazy-hydration
Анализирование бандла
nuxt build --analyze
Что нового готовит NUXT 3
server
static
serverless
import ExampleBlueprint from './blueprint'
export default {
modules: [
function exampleBlueprint () {
const options1 = {
id: '1',
backgroundColor: 'gold'
}
const options2 = {
id: '2',
backgroundColor: 'silver'
}
new ExampleBlueprint(this.nuxt, options1).init()
new ExampleBlueprint(this.nuxt, options2).init()
}
]
}
div {
background-color: <%= options.backgroundColor %>;
padding: 1rem;
margin: 1rem auto;
}
<template>
<div>
<h2>Hello from ExampleBlueprint instance <%= options.id %></h2>
<p>With a fancy background</p>
</div>
</template>
<style scoped>
@import url('../css/style.css')
</style>
Немного о том, как Nuxt.js устроен изнутри
@nuxt/builder
@nuxt/cli
@nuxt/core
@nuxt/generator
@nuxt/webpack
@nuxt/webpack
Внешние плагины
@nuxt/friendly-errors-webpack-plugin
time-fix-plugin
extract-css-chunks-webpack-plugin
hard-source-webpack-plugin
terser-webpack-plugin
webpackbar
optimize-css-assets-webpack-plugin
html-webpack-plugin
Middleware
webpack-dev-middleware
webpack-hot-middleware
Внутренние плагины
warning-ignore
CorsPlugin
ModernModePlugin
VueSSRServerPlugin
VueSSRClientPlugin
@nuxt/babel-preset-app
Postcss Config
Resolver
Module
Nuxt
@nuxt/config
@nuxt/server
@nuxt/vue-renderer
addPlugin
addTemplate
addLayout
addErrorLayout
addModule
resolveAlias
resolveModule
resolvePath
Обработка nuxt.config
Настройка сервера, используется библиотека connect
Компиляция vue шаблонов
Renderer
SPA
SSR
MODERN
NuxtCommand
Options
build
dev
generate
help
index
start
common
locking
server
list
run
watch
@nuxt/devalue
валидация ( validatePages, validateTemplate )
serialize-javascript
Builder
Сериализация данных
резолвинг ( resolveRoutes, resolveLayouts, resolveStore, resolveMiddleware, resolveCustomTemplates, resolvePlugins)
build & generate
TemplateContext
router, store, plugins, isDev, etc
@nuxt/vue-app
lodash темплейты
'App.js', | |
'client.js', | |
'index.js', | |
'router.js', | |
'router.scrollBehavior.js', | |
'server.js', | |
'utils.js', | |
'empty.js', | |
'components/nuxt-error.vue', | |
'components/nuxt-child.js', | |
'components/nuxt-link.server.js', | |
'components/nuxt-link.client.js', | |
'components/nuxt.js', | |
'views/app.template.html', | |
'views/error.html' |
@nuxt/builder
@nuxt/cli
@nuxt/core
@nuxt/generator
@nuxt/webpack
nuxt
nuxt-start
@nuxt/cli
@nuxt/core
nuxt-edge & nuxt-start-edge