🐎 prerender les principales landing pages

Acceleration drastique des perfomances, la page est chargée immédiatement.

Limitations:
- La page embauche.beta.gouv.fr est prérendue en français. Le contenue saute si le navigateur est en anglais
- Les tests end to end ne sont pas encore branchés avec les pages prérendues. Voir https://github.com/zeit/serve-handler/issues/71
pull/409/head
Johan Girod 2018-10-18 16:36:30 +02:00
parent 18023057ec
commit 24cfebb5d0
12 changed files with 1650 additions and 57 deletions

View File

@ -28,21 +28,6 @@ describe('Landing basic test', function() {
})
})
describe('Simulation saving test', function() {
it('should save the current simulation', async function() {
cy.visit('/')
salaryInput('Salaire net').type('5471')
cy.tick(500)
cy.contains('Autres').click()
cy.contains('passer').click()
cy.contains('passer').click()
cy.tick(2000).then(() => this.clock.restore)
cy.visit('/')
cy.contains('Retrouver ma simulation').click()
salaryInput('Salaire net').should('have.value', '5471')
})
})
describe('Iframe integration test', function() {
it('should display an iframe of the simulateur', function() {
cy.visit('/integration-test')

View File

@ -40,6 +40,7 @@
#js {
opacity: 0;
transform: translateY(20px);
transition: all 0.4s
}
/* CSS Loader */
@ -133,9 +134,9 @@
<div></div>
<div></div>
</div>
<div id="js"></div>
</div>
<!-- APP -->
<div id="js"></div>
<!-- A little help for the Netlify bots if you're not using a SSG -->
<form name="feedback" netlify netlify-honeypot="bot-field" hidden>

View File

@ -1,24 +1,31 @@
[[redirects]]
from = "https://embauche.beta.gouv.fr/stats"
to = "https://rough-college.glitch.me/"
status = 200
[[redirects]]
from = "https://infrance.org/*"
to = "/infrance.html"
status = 200
# InFrance PRODUCTION settings
[[redirects]]
from = "https://mycompanyinfrance.fr/robots.txt"
to = "/robots.infrance.txt"
status = 200
[[redirects]]
from = "https://mycompanyinfrance.fr"
to = "/prerender/infrance/index.html"
status = 200
[[redirects]]
from = "https://mycompanyinfrance.fr"
to = "/prerender/infrance/social-security/index.html"
status = 200
[[redirects]]
from = "https://mycompanyinfrance.fr/*"
to = "/infrance.html"
status = 200
# Embauche PRODUCTION settings
[[redirects]]
from = "https://embauche.beta.gouv.fr/stats"
to = "https://rough-college.glitch.me/"
status = 200
[[redirects]]
from = "https://embauche.beta.gouv.fr/modules/v2/*"
@ -29,11 +36,23 @@ from = "https://embauche.beta.gouv.fr/robots.txt"
to = "/robots.embauche.txt"
status = 200
[[redirects]]
from = "https://embauche.beta.gouv.fr/"
to = "/prerender/embauche/index.html"
status = 200
[[redirects]]
from = "https://embauche.beta.gouv.fr/*"
to = "/embauche.html"
status = 200
# Redirect for embauche in staging and development settings
[[redirects]]
from = "/"
query = {s = "e"}
to = "/prerender/embauche/index.html"
status = 200
[[redirects]]
from = "/*"
@ -41,6 +60,17 @@ query = {s = "e"}
to = "/embauche.html"
status = 200
# Redirect for infrance in staging and development settings
[[redirects]]
from = "/"
to = "/prerender/infrance/index.html"
status = 200
[[redirects]]
from = "/social-security"
to = "/prerender/infrance/social-security/index.html"
status = 200
[[redirects]]
from = "/*"
to = "/infrance.html"

View File

@ -58,7 +58,7 @@
"eslint": "LIST=`git diff --cached --name-only --diff-filter=AMR HEAD | grep .*\\.js | grep -v json`; if [ \"$LIST\" ]; then eslint $LIST; fi",
"externalize": "node source/externalize.js",
"heroku-postbuild": "yarn install --production=false && yarn compile",
"serve:infrance": "cp dist/infrance.html dist/index.html && serve -s dist",
"serve:infrance": "serve --config serve.infrance.json",
"pretest": "LIST=`git diff --name-only --diff-filter=AMR HEAD^..HEAD | grep .*\\.js | grep -v json`; if [ \"$LIST\" ]; then eslint $LIST; fi && flow check",
"start": "node source/server.js",
"test-inversions": "yarn test-watch --grep 'inversions'",
@ -117,13 +117,16 @@
"jsdom": "^12.0.0",
"json-loader": "^0.5.7",
"koa-connect": "^2.0.1",
"mini-css-extract-plugin": "^0.4.4",
"mocha": "^5.0.4",
"mocha-webpack": "^2.0.0-beta.0",
"mock-local-storage": "^1.0.5",
"nearley-loader": "^2.0.0",
"postcss-loader": "^2.1.2",
"prerender-spa-plugin": "^3.4.0",
"ramda-fantasy": "^0.8.0",
"serve": "^10.0.2",
"serve-handler": "^5.0.5",
"sinon": "^4.5.0",
"sinon-chai": "^3.0.0",
"source-map-support": "^0.5.4",

4
serve.infrance.json Normal file
View File

@ -0,0 +1,4 @@
{
"rewrites": [{ "source": "**", "destination": "infrance.html" }],
"public": "dist"
}

View File

@ -56,7 +56,6 @@ span.ui__.enumeration:not(:last-of-type)::after {
#js {
opacity: 1;
transform: translateY(0px);
transition: opacity 0.4s, transform 0.4s;
}
#lds-ellipsis {
display: none;

View File

@ -52,17 +52,11 @@ export class ScrollToElement extends Component {
) {
return
}
try {
this.ref.scrollIntoView({
behavior: this.props.behavior,
block: 'nearest',
inline: 'nearest'
})
} catch (error) {
this.ref.scrollIntoView({
behavior: this.props.behavior
})
}
this.ref.scrollIntoView({
behavior: this.props.behavior,
block: 'nearest',
inline: 'nearest'
})
}
componentDidMount() {
this.scrollIfNeeded()

View File

@ -19,7 +19,6 @@ import computeThemeColours from 'Ui/themeColours'
import { simulationTargetNames } from '../config.js'
import defaultLang from '../i18n'
import inFranceAppReducer from './inFranceAppReducer'
import storageReducer from './storageReducer'
import type { Action } from 'Types/ActionsTypes'
// TODO : use context API instead
@ -161,7 +160,6 @@ const existingCompanyReducer = (state, action) => {
}
export default reduceReducers(
existingCompanyReducer,
storageReducer,
combineReducers({
sessionId: defaultTo(Math.floor(Math.random() * 1000000000000) + ''),
// this is handled by redux-form, pas touche !

View File

@ -67,7 +67,7 @@ class Search extends React.Component<Props, State> {
Thanks to the SIREN database, the public informations of your company
will be automatically available for the next steps.
</p>
{/* $FlowFixMe */}
<ReactSelect.Async
valueKey="id"
labelKey="l1_normalisee"
@ -82,7 +82,6 @@ class Search extends React.Component<Props, State> {
loadingPlaceholder="Searching..."
loadOptions={this.getOptions}
/>
{!!this.state.input && (
<>
<Company {...this.state.input} />

View File

@ -2,6 +2,7 @@
const HTMLPlugin = require('html-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')
const path = require('path')
module.exports = {
resolve: {
alias: {

View File

@ -1,18 +1,62 @@
const common = require('./webpack.common.js')
const WorkboxPlugin = require('workbox-webpack-plugin')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
const path = require('path')
const cheerio = require('cheerio')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const prerenderConfig = () => ({
staticDir: path.resolve('dist'),
renderer: new Renderer({
renderAfterTime: 5000,
skipThirdPartyRequests: true
}),
postProcess: context => {
const $ = cheerio.load(context.html)
// force https on twitter emoji cdn
$('img[src^="http://twemoji.maxcdn.com"]').each((i, el) => {
$(el).attr('src', (_, path) => path.replace('http://', 'https://'))
})
// Remove loader
$('#outdated-browser').after(`
<style>
#js {
opacity: 1;
transform: translateY(0px);
}
#lds-ellipsis {
display: none;
}
</style>
`)
// Remove piwik script
$('script[src$="stats.data.gouv.fr/piwik.js"]').remove()
context.html = $.html()
return context
}
})
// Replace style-loader with MiniCssExtractPlugin.loader
common.module.rules
.find(rule => rule.test.test('a.css'))
.use.find(loader => loader.loader === 'style-loader').loader =
MiniCssExtractPlugin.loader
module.exports = {
...common,
mode: 'production',
devtool: 'source-map',
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].[hash].css',
chunkFilename: '[id].[hash].css'
}),
...common.plugins,
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true,
swDest: 'sw.js',
navigateFallback: '/',
navigateFallbackBlacklist: [/.*\?s=.*$/, /^\/stats/],
runtimeCaching: [
{
urlPattern: new RegExp(
@ -29,7 +73,26 @@ module.exports = {
}
}
}
],
navigateFallback: '/fallback',
navigateFallbackBlacklist: [
/.*\?s=.*$/,
/^\/stats/,
/^\/robots\.txt$/,
/^\/sitemap\.infrance\.txt$/
]
}),
new PrerenderSPAPlugin({
...prerenderConfig(),
outputDir: path.resolve('dist', 'prerender', 'infrance'),
routes: ['/', '/social-security'],
indexPath: path.resolve('dist', 'infrance.html')
}),
new PrerenderSPAPlugin({
...prerenderConfig(),
outputDir: path.resolve('dist', 'prerender', 'embauche'),
routes: ['/'],
indexPath: path.resolve('dist', 'embauche.html')
})
]
}

1542
yarn.lock

File diff suppressed because it is too large Load Diff