Fix the slowness of the Silence UI (#1235)

* Cache tabs and fix slow css

* update bindata
This commit is contained in:
Andrey Kuzmin 2018-02-09 10:42:44 +01:00 committed by stuart nelson
parent 168cb217c6
commit 5101d65938
7 changed files with 125 additions and 43 deletions

View File

@ -7,6 +7,22 @@ import Utils.Date
import Utils.Types exposing (ApiData(..))
map : (a -> b) -> ApiData a -> ApiData b
map fn response =
case response of
Success value ->
Success (fn value)
Initial ->
Initial
Loading ->
Loading
Failure a ->
Failure a
withDefault : a -> ApiData a -> a
withDefault default response =
case response of

View File

@ -24,7 +24,10 @@ view labels maybeActiveId alert =
|> uncurry (++)
in
li
[ class "align-items-start list-group-item border-0 alert-list-item p-0 mb-4"
[ -- speedup rendering in Chrome, because list-group-item className
-- creates a new layer in the rendering engine
style [ ( "position", "static" ) ]
, class "align-items-start list-group-item border-0 p-0 mb-4"
]
[ div
[ class "w-100 mb-2 d-flex align-items-start" ]

View File

@ -13,14 +13,18 @@ import Utils.List
import Utils.Types exposing (Matcher)
import Utils.Views exposing (buttonLink)
import Views.FilterBar.Types as FilterBarTypes
import Views.SilenceForm.Types exposing (SilenceFormMsg(NewSilenceFromMatchers))
import Views.SilenceList.Types exposing (SilenceListMsg(ConfirmDestroySilence, DestroySilence, FetchSilences, MsgForFilterBar))
import Views.SilenceForm.Parsing exposing (newSilenceFromAlertLabels)
view : Bool -> Silence -> Html Msg
view showConfirmationDialog silence =
li [ class "align-items-start list-group-item border-0 alert-list-item p-0 mb-4" ]
li
[ -- speedup rendering in Chrome, because list-group-item className
-- creates a new layer in the rendering engine
style [ ( "position", "static" ) ]
, class "align-items-start list-group-item border-0 p-0 mb-4"
]
[ div [ class "w-100 mb-2 d-flex align-items-start" ]
[ case silence.status.state of
Active ->

View File

@ -1,4 +1,4 @@
module Views.SilenceList.Types exposing (Model, SilenceListMsg(..), initSilenceList)
module Views.SilenceList.Types exposing (Model, SilenceTab, SilenceListMsg(..), initSilenceList)
import Silences.Types exposing (Silence, State(Active), SilenceId)
import Utils.Types exposing (ApiData(Initial))
@ -14,8 +14,15 @@ type SilenceListMsg
| SetTab State
type alias SilenceTab =
{ silences : List Silence
, tab : State
, count : Int
}
type alias Model =
{ silences : ApiData (List Silence)
{ silences : ApiData (List SilenceTab)
, filterBar : FilterBar.Model
, tab : State
, showConfirmationDialog : Maybe SilenceId

View File

@ -2,17 +2,26 @@ module Views.SilenceList.Updates exposing (update, urlUpdate)
import Navigation
import Silences.Api as Api
import Utils.Api as ApiData
import Utils.Filter exposing (Filter, generateQueryString)
import Utils.Types as Types exposing (ApiData(Failure, Loading, Success), Matchers, Time)
import Views.FilterBar.Updates as FilterBar
import Views.SilenceList.Types exposing (Model, SilenceListMsg(..))
import Views.SilenceList.Types exposing (Model, SilenceTab, SilenceListMsg(..))
import Silences.Types exposing (Silence, State(..))
update : SilenceListMsg -> Model -> Filter -> String -> String -> ( Model, Cmd SilenceListMsg )
update msg model filter basePath apiUrl =
case msg of
SilencesFetch sils ->
( { model | silences = sils }, Cmd.none )
SilencesFetch fetchedSilences ->
( { model
| silences =
ApiData.map
(\silences -> List.map (groupSilencesByState silences) states)
fetchedSilences
}
, Cmd.none
)
FetchSilences ->
( { model
@ -50,6 +59,28 @@ update msg model filter basePath apiUrl =
( { model | tab = tab }, Cmd.none )
groupSilencesByState : List Silence -> State -> SilenceTab
groupSilencesByState silences state =
let
silencesInTab =
filterSilencesByState state silences
in
{ tab = state
, silences = silencesInTab
, count = List.length silencesInTab
}
states : List State
states =
[ Active, Pending, Expired ]
filterSilencesByState : State -> List Silence -> List Silence
filterSilencesByState state =
List.filter (.status >> .state >> (==) state)
urlUpdate : Maybe String -> ( SilenceListMsg, Filter )
urlUpdate maybeString =
( FetchSilences, updateFilter maybeString )

View File

@ -4,13 +4,14 @@ import Html exposing (..)
import Html.Attributes exposing (..)
import Silences.Types exposing (Silence, State(..), stateToString, SilenceId)
import Types exposing (Msg(MsgForSilenceList, Noop, UpdateFilter))
import Utils.Api exposing (withDefault)
import Utils.String as StringUtils
import Utils.Types exposing (ApiData(..), Matcher)
import Utils.Views exposing (buttonLink, checkbox, error, formField, formInput, iconButtonMsg, loading, textField)
import Views.FilterBar.Views as FilterBar
import Views.SilenceList.SilenceView
import Views.SilenceList.Types exposing (Model, SilenceListMsg(..))
import Views.SilenceList.Types exposing (Model, SilenceListMsg(..), SilenceTab)
import Html.Lazy exposing (lazy, lazy2, lazy3)
import Html.Keyed
view : Model -> Html Msg
@ -20,49 +21,69 @@ view { filterBar, tab, silences, showConfirmationDialog } =
[ label [ class "mb-2", for "filter-bar-matcher" ] [ text "Filter" ]
, Html.map (MsgForFilterBar >> MsgForSilenceList) (FilterBar.view filterBar)
]
, ul [ class "nav nav-tabs mb-4" ]
(List.map (tabView tab) (groupSilencesByState (withDefault [] silences)))
, case silences of
Success sils ->
silencesView showConfirmationDialog (filterSilencesByState tab sils)
Failure msg ->
error msg
_ ->
loading
, lazy2 tabsView tab silences
, lazy3 silencesView showConfirmationDialog tab silences
]
tabView : State -> ( State, List a ) -> Html Msg
tabView currentState ( state, silences ) =
Utils.Views.tab state currentState (SetTab >> MsgForSilenceList) <|
case List.length silences of
tabsView : State -> ApiData (List SilenceTab) -> Html Msg
tabsView currentTab tabs =
case tabs of
Success silencesTabs ->
List.map (\{ tab, count } -> tabView currentTab count tab) silencesTabs
|> ul [ class "nav nav-tabs mb-4" ]
_ ->
List.map (tabView currentTab 0) states
|> ul [ class "nav nav-tabs mb-4" ]
tabView : State -> Int -> State -> Html Msg
tabView currentTab count tab =
Utils.Views.tab tab currentTab (SetTab >> MsgForSilenceList) <|
case count of
0 ->
[ text (StringUtils.capitalizeFirst (stateToString state)) ]
[ text (StringUtils.capitalizeFirst (stateToString tab)) ]
n ->
[ text (StringUtils.capitalizeFirst (stateToString state))
[ text (StringUtils.capitalizeFirst (stateToString tab))
, span
[ class "badge badge-pillow badge-default align-text-top ml-2" ]
[ text (toString n) ]
]
silencesView : Maybe SilenceId -> List Silence -> Html Msg
silencesView showConfirmationDialog silences =
if List.isEmpty silences then
Utils.Views.error "No silences found"
else
ul [ class "list-group" ]
(List.map
(\silence ->
Views.SilenceList.SilenceView.view
(showConfirmationDialog == Just silence.id)
silence
)
silences
)
silencesView : Maybe SilenceId -> State -> ApiData (List SilenceTab) -> Html Msg
silencesView showConfirmationDialog tab silencesTab =
case silencesTab of
Success tabs ->
tabs
|> List.filter (.tab >> (==) tab)
|> List.head
|> Maybe.map .silences
|> Maybe.withDefault []
|> (\silences ->
if List.isEmpty silences then
Utils.Views.error "No silences found"
else
Html.Keyed.ul [ class "list-group" ]
(List.map
(\silence ->
( silence.id
, Views.SilenceList.SilenceView.view
(showConfirmationDialog == Just silence.id)
silence
)
)
silences
)
)
Failure msg ->
error msg
_ ->
loading
groupSilencesByState : List Silence -> List ( State, List Silence )

File diff suppressed because one or more lines are too long